open() fails to update st_mtime when used with O_TRUNC and 0 byte files
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com Dkim-signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:mime-version:content-type; b=mFzFkaYB/KpM61HD2ckGcj0toJTWet3+YYhc1ioyn8v+elcOZ2LK/rDfJZFQ/rXEH4EujCDNRW0G9fBZvuczgllHefgWMlfsIh8FRzv8BwrAJF5WfQFLcUKuZ4vrWXE0VBRFS+qIrbU7wzL+5XtvQ48KQFJT6BN44+eLMnd7f3s= Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:mime-version:content-type; b=XEpT5YKgTrJCwopWZrSNwseof1NPkE8nzkJJUqr/DQXT1IPkn7Jnzq2WRtwTr0KGv6KEfn/JMDLRHJ8HQXb8edic/ysnuNdYJXMmCe+k6AQPN6Js1OIKnC47Da+3moQK6HP8SD6e6jAvxHtVALGrcXAR+uMQ+cJO+1QnfBbwQ2U= i was tracking down a bug in the Linux kernel build system which seems to be caused by a bug in Darwin. the kernel build system creates a bunch of 0 byte files and then uses open(O_TRUNC) on them in order to update the st_mtime field (which triggers make to recreate some object files). on my mac mini, this all falls apart. according to POSIX: http://www.opengroup.org/onlinepubs/009695399/functions/open.html If O_TRUNC is set and the file did previously exist, upon successful completion, open() shall mark for update the st_ctime and st_mtime fields of the file. Darwin appears to update st_ctime properly, but not st_mtime. the machine i'm testing on: $ uname -a Darwin Blackfin-Linux-Mac-Mini.local 8.9.0 Darwin Kernel Version 8.9.0: Thu Feb 22 20:54:07 PST 2007; root:xnu-792.17.14~1/RELEASE_PPC Power Macintosh powerpc but it was first noticed on one of the new Interl based macbooks the filesystem is default OS X HFS+ with case sensitivity enabled the attached test code should show the issue clearly -mike #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> void timestest(size_t num_bytes) { const char *tempfile = "MOO_MOO"; struct stat st1, st2; int fd, ret; /* punt the file and then create a 0 byte file and get its times */ printf("getting first times ...\n"); unlink(tempfile); fd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); assert(fd >= 0); if (num_bytes) write(fd, tempfile, num_bytes); close(fd); ret = stat(tempfile, &st1); assert(ret == 0); /* sleep a little to make there is a difference in the times */ printf("sleeping for three seconds ...\n"); sleep(3); /* open the file again and grab the new file times */ printf("getting second times ...\n"); fd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); assert(fd >= 0); close(fd); ret = stat(tempfile, &st2); assert(ret == 0); unlink(tempfile); /* each of these should be different (except for atime if you * mount your filesystem with atime turned off) */ #define comp(member) (st1.member == st2.member ? "same" : "diff") printf("the following times should all be different\n(atime can be the same if you have filesystem mounted noatime)\n"); printf("atime: %lu vs %lu (%s)\n" "mtime: %lu vs %lu (%s)\n" "ctime: %lu vs %lu (%s)\n", st1.st_atime, st2.st_atime, comp(st_atime), st1.st_mtime, st2.st_mtime, comp(st_mtime), st1.st_ctime, st2.st_ctime, comp(st_ctime)); printf("\n"); } int main(int argc, char *argv[]) { printf("testing truncation with a 0 byte file\n"); timestest(0); printf("testing truncation with a 4 byte file\n"); timestest(4); return 0; } _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This email sent to site_archiver@lists.apple.com
participants (1)
-
Mike Frysinger