jordan@morgan.COM (Jordan Hayes) (03/12/90)
Sun4/110, X11R4 patches 1-5 installed, SunOS 4.0.3 ... but i've seen it since R3 about a year ago. Symptom: Xt clients enter spin loop warning select() failed: errno 22 ----- I got some mail about this from someone who tipped me off. Somehow (don't ask me!) ntpd (the network time protocol daemon) is screwing up the system time on Sparcs so that the return from gettimeofday() contains an unusable time. The macros ADD_TIME and TIME_DELTA in mit/lib/Xt/NextEvent.c do a good job of sanity checking the two time values, but don't go far enough in the face of stupid input. This is not their fault. However, here's a more bullet-proof version of these macros, ones that will avoid similar problems in the future. After adjusting for the border conditions, if there are still negative numbers involved in tv_sec or tv_usec (refused as invalid input for the timeout argument to select()) they are quashed. *** NextEvent.c Mon Mar 12 10:44:29 1990 --- NextEvent.c.old Mon Mar 12 10:37:19 1990 *************** *** 53,71 **** * Private routines */ #define ADD_TIME(dest, src1, src2) { \ ! if(((dest).tv_usec = (src1).tv_usec + (src2).tv_usec) >= 1000000) {\ ! (dest).tv_usec -= 1000000;\ ! (dest).tv_sec = (src1).tv_sec + (src2).tv_sec + 1 ; \ ! } else { (dest).tv_sec = (src1).tv_sec + (src2).tv_sec ; \ ! if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { \ ! (dest).tv_sec --;(dest).tv_usec += 1000000; } } } - #define TIMEDELTA(dest, src1, src2) { \ ! if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) {\ ! (dest).tv_usec += 1000000;\ ! (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1;\ ! } else (dest).tv_sec = (src1).tv_sec - (src2).tv_sec; } #define IS_AFTER(t1, t2) (((t2).tv_sec > (t1).tv_sec) \ || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec > (t1).tv_usec))) --- 53,71 ---- * Private routines */ #define ADD_TIME(dest, src1, src2) { \ ! (dest).tv_sec = (src1).tv_sec + (src2).tv_sec; \ ! (dest).tv_usec = (src1).tv_usec + (src2).tv_usec; \ ! while ((dest).tv_usec >= 1000000) { \ ! (dest).tv_usec -= 1000000; (dest).tv_sec++; } \ ! if ((dest).tv_sec < 0) (dest)tv_sec = 0; \ ! if ((dest).tv_usec < 0) (dest)tv_usec = 0; } #define TIMEDELTA(dest, src1, src2) { \ ! (dest).tv_sec = (src1).tv_sec - (src2).tv_sec; \ ! (dest).tv_usec = (src1).tv_usec - (src2).tv_usec; \ ! while ((dest).tv_usec < 0) { \ ! (dest).tv_usec += 1000000; (dest).tv_sec--; } \ ! if ((dest).tv_sec < 0) (dest)tv_sec = 0; } #define IS_AFTER(t1, t2) (((t2).tv_sec > (t1).tv_sec) \ || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec > (t1).tv_usec))) ----- /jordan