I found another xdm bug. This time it's a race condition in xc/programs/xdm/policy.c:Willing
around line numbers 140--145, which reads if ((fd = popen(willing, "r"))) { char *s = NULL; while(!(s = fgets(statusBuf, 256, fd)) && errno == EINTR) ; Here's the problem. The "popen" call creates a child process and a pipe to communicate with it. If the child process exits during the "fgets" call without generating any output, the parent process receives SIGCHLD and the read system call gets interrupted. Therefore errno == EINTR, and since the child has exited the pipe never returns any data. xdm goes into an infinite loop. I think the problem is that fgets doesn't reset errno to zero; we have to do that manually. The fix is the trivial patch attached to this email. (The child process is the "Xwilling" script; in the case of the default Debian configuration it is "su nobody -c /usr/X11R6/lib/X11/xdm/Xwilling") Chip -- Charles M. "Chip" Coldwell System Administrator Harvard Physics Department 617-495-3388
--- xc/programs/xdm/policy.c~ 2002-12-07 15:31:04.000000000 -0500 +++ xc/programs/xdm/policy.c 2004-06-24 09:56:19.000000000 -0400 @@ -140,8 +140,9 @@ if ((fd = popen(willing, "r"))) { char *s = NULL; + errno = 0; while(!(s = fgets(statusBuf, 256, fd)) && errno == EINTR) - ; + errno = 0; if (s && strlen(statusBuf) > 0) statusBuf[strlen(statusBuf)-1] = 0; /* chop newline */ else