Messages in this thread | | | Subject | Re: Linux-2.1.54.. | From | Darryl Miles <> | Date | Sat, 13 Sep 1997 01:32:15 +0100 (BST) |
| |
Hi,
If I've heard the Unix specification correctly applications are also broken if they presume that the select timeout isn't modified and also if they presume on how it has been modified. It's true to say "Applications should consider the contents of the timeout to be undefined, after calling select(2) use.".
This statement is obviously not true if you know extra information on how it has been modified, in which case as no standard has defined how to obtain this information then it's a platform specific issue, a Linux'ism :-) and not what you're trying to address which is general software portability.
How many broken commercial and non-commercial applications fall into the area of presuming the timeout if not modified, even though the UNIX specs now say that it maybe. If they are broken to start with then why are we changing Linux policy, since these application will eventually be fixed to confirm to the UNIX specification. AFAIK this fix (of reloading the timeout every time, just before calling select(2)), then presuming nothing about if after the syscall will make that application work with both Linux (SLIPPY_TIMEOUTS) and DEC Unix (STICKY_TIMEOUTS).
You are advocating that it's broken applications which make use of SLIPPY_TIMEOUTS, this is not true, yes it's a Linux'ism, but the application using it is a Linux application, it has no interest or need to consider other platforms. What you are really doing is bowing down to broken application from other platforms, which presume the timeout is not modified.
Could I offer this (elegant, cough, cough) function as the basis for anyone wanting to keep the old behavior.
It's arithmetic has had very little optimizational thought put on it.
I think if you rename the function to 'select' and rename the system calls from 'select' to '__select' you may wrap your libc's select incarnation by placing the resultant object code on the linker command line.
---------------------------------------------------------------------------- #include <stdio.h> #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h>
/* Number of usecs in one second */ #define TIMER_USEC_VAL 1000000
/* If you system doesn't support gettimeofday(), hah hah ha! */
int linux_select(int maxfd, fd_set *readfd, fd_set *writefd, fd_set *exceptfd, struct timeval *timeout) { int retval;
if(timeout != NULL) { struct timeval otv; struct timeval ntv;
gettimeofday(&otv, NULL);
retval = select(maxfd, readfd, writefd, exceptfd, timeout);
gettimeofday(&ntv, NULL);
if(retval != 0) { long sec, usec; long nsec, nusec;
sec = ntv.tv_sec - otv.tv_sec; usec = ntv.tv_usec - otv.tv_usec;
/* If usec is negative then drop the second */ if(usec < 0) { /* usec is negative and (1000000 + (-500000)) = 500000 :-) */ usec = TIMER_USEC_VAL + usec; sec--; }
/* We now have the select sleep duration in 'sec' and 'usec' */
nsec = timeout->tv_sec - sec; nusec = timeout->tv_usec - usec;
if(nusec < 0) { /* nusec is negative and (1000000 + (-500000)) = 500000 :-) */ nusec = TIMER_USEC_VAL + nusec; nsec--; }
if(nsec < 0) { nsec = 0; nusec = 0; }
timeout->tv_sec = nsec; timeout->tv_usec = nusec; } else { timeout->tv_sec = 0; timeout->tv_usec = 0; } } else { retval = select(maxfd, readfd, writefd, exceptfd, timeout); }
return retval; } ----------------------------------------------------------------------------
-- Darryl Miles
| |