118507 fools suffered gladly since April 4, 1999...

links

rss icon syndication

headlines

Search Past Headlines:

 
contact
legal

All content copyright 1999, 2000, 2001, 2002, 2003, and 2004 Brent Blood. Unless of course it is somebody else's. Or unless I note otherwise for the particular content.

On utimes()

Mon, June 23, 2008 - 7:55 PM PST

I was writing a small piece of code yesterday that made a call to utimes(). The UNIX programmers manual for that system call includes the function prototype: it returns an int, and takes a char pointer as well as a pointer to a timeval structure as arguments. Not really much to it, right? Imagine my frustration when my program was always setting the mtime to Dec 30, 1969 regardless of what value I provided!

Only after reading the whole manpage a few times did I catch that the second argument wasn't just a pointer to a timeval structure - it was an array of two timeval structures. And since when passed as a function argument, an array degrades to a pointer to the first array element, the prototype wasn't so much wrong as it was ambiguous - which I guess is why they explained it in the manual. Accepting this did not lessen my frustration.

My mtime was being set to the UNIX epoch because utimes was using the atime that I passed, and then reading the next block of memory (which happened to be 0 - hence the date) and using that for the mtime. I'm lucky the next block of memory was mapped to my program and it didn't SIGSEGV! But I fixed my bug and the program now works.

Sometimes I hate UNIX.

So I did some reading just now. My copy of Advanced Programming in the UNIX Environment is an edition behind, but still worth having around. I knew that utimes() had replaced utime(), and so I hadn't looked at utime(). I did tonight, and it handles this situation by taking a pointer to a timbuf structure. This structure has two members of type time_t. So this is effectively the same idea as utimes(), only rather than advertising a call signature that took a pointer to a struct when it actually needed an array, this older, deprecated, function handled it in what would seem a more elegant way: by defining a new datatype that explicitly contains the two values it needs. I wonder why they deprecated it and bothered with utimes()... I suppose to handle granularity of less than 1 second.

Sometimes I hate UNIX.