I currently have a double containing a POSIX time stamp, and I am successfully using gmtime and asctime to display a calendar date via a time_t struct:
time_t input = posix;
printf("%s",asctime(gmtime(&input)));
This works well, except (obviously) when the POSIX time falls outside the time.h library's limits (i.e. 1901-2038), in which case it returns a date in 1901. Are there any easy alternatives to gmtime/asctime/time.h, or am I simply going to have to work with the raw figures?
Edit: I should add that having a result that falls outside those limits is fairly likely, as the posix double is the result of a calculation, rather than an instantiation of the current system time.
Read the Wikipedia entry on Unix Time:
The POSIX and Open Group Unix specifications include the C standard library, which includes the time types and functions defined in the <time.h> header file. The ISO C standard states that time_t must be an arithmetic type, but does not mandate any specific type or encoding for it.
If you need to handle a large range of times in a portable manner, you will probably have to use your own time library. I don't think you can even count on struct tm covering a range beyond 1901 to 2038.
You might also want to read this StackOverflow answer regarding time_t.
Related
I tried clock_gettime() and timespec_get() but what is the difference?
Can anyone help me to find the difference between clock_gettime() and timespec_get()?
clock_gettime(clockid_t, struct timespec *) (declared in time.h) can return different values times based on clockid_t. You should read the man page.
timespec_get(struct timespec *, int) (also declared in time.h) sets the object value to time since the Epoch (1.1.1970, midnight). This should be ideally same as calling clock_gettime() with clockid_t as CLOCK_REALTIME.
The second argument here is base or time-zone. So using TIME_UTC would give the GMT.
Even though they are defined in time.h, they are not standard C functions but almost all compiler implementations have these.
I am making a program to copy files from a source to a destination directory and would like to change the destination file timestamps so they match the source file timestamps.
So far I have discovered the utime() function and have manipulated the utimbuf struct with the times I would like to use.
However, the times do not take into account the nanoseconds.
For example:
If I want to copy "file1" and it has a timestamp of 123.213241, my copy will have 123.000000 when running my current program. I would like to include the nanoseconds .213241 etc.
Here is my code so far:
struct stat buf;
struct utimbuf time;
stat(filename, &buf) // get metadata of file "filename" and then store in buf
time.actime = buf.st_atim.tv_sec; // set times in time struct
time.modtime = buf.st_mtim.tv_sec;
utime(filename_copy, &time); // load file copy with time struct
How can I include nanoseconds in my file timestamps?
According to POSIX, the function you need is utimensat() (or its close relative, futimens()). Both of these take a pair of struct timespec values in an array, which allows you to specify a time to nanoseconds. The first element is the access time; the second is the modification time.
Not all file systems support nanosecond timestamps. Not all systems actually support nanosecond resolution — they might round to the nearest microsecond.
Note that modern versions of the stat() function return a structure with elements st_atim, st_ctim, and st_mtim. These are also struct timespec values. The <sys/stat.h> defines some backwards-compatibility macros:
For compatibility with earlier versions of this standard, the st_atime macro shall be defined with the value st_atim.tv_sec. Similarly, st_ctime and st_mtime shall be defined as macros with the values st_ctim.tv_sec and st_mtim.tv_sec, respectively.
For Linux, see utimensat(2). However, the documentation for stat(2) only mentions subsecond times in the Notes section near the bottom. Be cautious.
Before I read that POSIX reserved the typedefs ending in _t I used it frequently. What would be a good commonly-used standard alternative for this suffix?
"Standard" is a big word. If you refer to the ISO C, it's beyond its job to define that; indeed, it does use names like time_t or size_t because it's allowed to as POSIX is secondary to it. Moreover, this convention does not apply to Windows-based programming environments, for instance.
IMHO, it's not really needed to state that a type is a type. C has a limited number of types so it's elementary to determine whether it's a built-in type or an ADT. Also, such built-in types have lower case one word names: if you saw stat_buffer you would immediately know it may not be a built-in type.
Whatever choice you make it's important to keep it consistent across your source code. Anyways, very frequent choices I see may be:
Uppercase nomenclature, like Time or Pid
_type suffix, like time_type or pid_type
Invisible suffix, like time or pid
I'm trying to print the time within my own custom system call in a human readable format (Jan 29 2015 05:53:12 for example, though any order is fine). I'm using code I know works in a standard C program because I've used it before, but for some reason it doesn't work within a system call.
#include<linux/linkage.h>
#include<linux/kernel.h>
#include<linux/sched.h>
#include<linux/time.h>
asmlinkage long sys_mycall (int someVal)
{
time_t t;
time(&t);
printk("myInt: %d", someVal);
printk("%s", ctime(&t)) ;
return 0 ;
}
I'm getting errors on implicit declaration of functions 'time' and 'ctime', even though I included linux/time.h (I also tried just time.h).
And an error on ctime returning type int when I specified %s.
I know this means that something is going wrong with the time.h, but what exactly is it? Am I not allowed to include that in a sys call?
Thanks!
The kernel coding environment is not a "hosted" implementation of C, which implies that various standard C functions like ctime() might not exist, or if they do, might not behave in the same way as the standard functions. In fact, ctime() does not exist inside the kernel at all.
Instead, you can use time_to_tm() from <linux/time.h> to convert a time_t to a broken-down time in a struct tm, and then print the components of struct tm individually.
Note that you have to supply a timezone offset to time_to_tm(), because there is no overall "current timezone" for the kernel - timezone is a display setting and is therefore handled entirely in userspace. This is one reason why the kernel typically doesn't format times to be "human-readable" itself. If you don't have a good value to supply for the timezone offset, you can use zero which will mean that the broken-down time is in UTC.
Instead of time(), to obtain the current time to seconds granuality inside the kernel use get_seconds().
The ctime() function is not available in the kernel.
In fact, there are very few date/time formatting functions available in the kernel; most of these functions are only available in user space. If you want to generate a timestamp in the kernel, don't try to format it; just return a time_t and let userspace applications handle the formatting.
If that isn't enough and you really want a readable timestamp, you'll need to define the necessary functions yourself.
I came across a method named do_nanosleep() in C that I don't understand how it is used? One thing I know that it has to do with the suspending the execution of the calling thread, but that task is handled by nanosleep() in C. If that's true, then what is the need of do_nanosleep() here and how it is different from nanosleep()?
For reference, this is what it does.
/* arguments are seconds and nanoseconds */
inline void
do_nanosleep(time_t tv_sec, long tv_nsec)
{
struct timespec req;
req.tv_sec = tv_sec;
req.tv_nsec = tv_nsec;
nanosleep(&req, NULL);
}
Since do_nanosleep() is not a standard function, you will have to track it in your source code, or in the manuals for your system, to see what it does. It might be a portability wrapper which uses nanosleep() when it is available, and something else (usleep() or even sleep()) when it is not. It might do something completely unrelated to sleeping, too — but it probably does do what its name suggests.
Google has not (yet — 5 minutes after it was asked) indexed your question, and it does not know anything about do_nanosleep(). That suggests the code should be in your source somewhere, rather than in a system manual.
With the function definition in the question, we can see that instead of requiring the user to create a struct timespec, they can call do_nanosleep() with two arguments, the first for the seconds and the second for the fractions of a second (0..999,999,999 measured in nanoseconds). It then calls nanosleep(). So, in the minds of the people who wrote the software, do_nanosleep() presents a slightly more convenient interface to the underlying nanosleep() function. Since it is inline, the declarations for struct timespec must still be in scope, so I'm not convinced I agree with the authors, but it is not automatically a wrong decision.
It looks like it's just a simplified (and crippled) wrapper around POSIX nanosleep.
The first parameter is the number of seconds, and the second is the number of nanoseconds.
Like, do_nanosleep(3, 500000000) would (hopefully) sleep for 3 and a half seconds.
Since the function completely ignores return values... Your mileage may vary.