From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: From: Charles Forsyth Date: Fri, 3 Jun 2011 10:52:57 +0100 To: 9fans@9fans.net In-Reply-To: <19513f2dcc9c570739726d1108c482a2@ladd.quanstro.net> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] a pair nec bugs Topicbox-Message-UUID: eae5a1a4-ead6-11e9-9d60-3106f5b1d025 unfortunately, that one still fails: h% 8c -w nsec.c h% 8l nsec.8 h% 8.out 1307094033073099818 1307094033079570483 0 my approach is a little different. in the library: vlong nsec(void) { uchar b[8]; vlong t; int fd, n; fd = open("/dev/bintime", OREAD); if(fd < 0) return 0; t = 0; if(pread(fd, b, sizeof(b), 0) == sizeof(b)) be2vlong(&t, b); close(fd); return t; } what about applications that need to get the nsec frequently? *in those applications*, i write extern int timefd; void applicationinit(void) { timefd = open("/dev/bintime", OREAD|OCEXEC); if(timefd < 0) sysfatal("can't open /dev/bintime: %r"); ... } vlong readnsec(void) { uchar b[8]; vlong t; if(pread(timefd, b, sizeof(b), 0) != sizeof(b)) return 0; /* or sysfatal as you like */ be2vlong(&t, b); return t; } that's the first phase. then since there are a few applications that do that, it might be better to account for that in the library: extern vlong readnsec(int fd); it's similar to the above, but takes fd as a parameter. alternatively you could have a function that unpacked and returned the other values in bintime as well (clock ticks, and clock frequency), if you're keen. the original flaw was having a library routine that messed about with a process's file descriptors without any idea of context, and worse, stored the file descriptor in a hidden location, with no way to mark it later as redundant or invalid. that makes the library function fragile, and you can't fix it from outside the library. in the failing example above, i wrote: print("%llud\n", xnsec()); print("%llud\n", xnsec()); for(i = 2; i < 20; i++) close(i); print("%lld\n", xnsec()); (where xnsec is the most recently proposed version of nsec). being able to close files seems reasonable to me, but invalidates the file descriptor that nsec had stashed away. worse, i could open another file later that had the same index for xnsec to try to read. lots of other things could be changed, such as making rfork and close into functions that wrap _rfork and _close system calls, so they can notify other library functions to clean up their fd debris, but perhaps it's better not to create the potential for debris. other interfaces are possible that make the file descriptor visible to the application, and any of those would be fine.