fix nsec's issue with file descriptors and rfork at the price of a bit of performance Reference: /n/atom/patch/applied/nsecfdsafe Date: Wed Feb 19 13:30:23 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/libc/9sys/nsec.c Wed Feb 19 13:30:18 2014 +++ /sys/src/libc/9sys/nsec.c Wed Feb 19 13:30:18 2014 @@ -1,60 +1,18 @@ #include #include -#include - -static int fd = -1; -static struct { - int pid; - int fd; -} fds[64]; vlong nsec(void) { uchar b[8]; - int pid, i, f, tries; - - /* - * Threaded programs may have multiple procs - * with different fd tables, so we may need to open - * /dev/bintime on a per-pid basis - */ + int fd; - /* First, look if we've opened it for this particular pid */ - pid = _tos->pid; - for(tries = 0; tries < 3; tries++){ - f = -1; - for(i = 0; i < nelem(fds); i++) - if(fds[i].pid == pid){ - f = fds[i].fd; - break; - } - if(f < 0){ - /* If it's not open for this pid, try the global pid */ - if(fd >= 0) - f = fd; - else{ - /* must open */ - if((f = open("/dev/bintime", OREAD|OCEXEC)) < 0) - return 0; - fd = f; - for(i = 0; i < nelem(fds); i++) - if(fds[i].pid == 0){ - fds[i].pid = pid; - fds[i].fd = f; - break; - } - } - } - if(pread(f, b, sizeof b, 0) == sizeof b) - return getbe(b, 8); - close(f); - if(f == fd) - fd = -1; - if(i < nelem(fds)){ - fds[i].pid = 0; - fds[i].fd = -1; - } + fd = open("/dev/bintime", OREAD); + if(fd != -1) + if(pread(fd, b, sizeof b, 0) == sizeof b){ + close(fd); + return getbe(b, sizeof b); } + close(fd); return 0; } --- /sys/man/2/time Wed Feb 19 13:30:19 2014 +++ /sys/man/2/time Wed Feb 19 13:30:19 2014 @@ -64,14 +64,3 @@ .SH DIAGNOSTICS Sets .IR errstr . -.SH BUGS -Both -.I time -and -.I nsec -maintain a static file descriptor. -This can cause problems with programs -that share memory but not file descriptors. -Use -.I bintime -instead.