Rich: -Peter wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, wait_for_cell, wait_proc, just_wait_proc) int time_limit, microsecs, read_kbd, do_display; Lisp_Object wait_for_cell; struct Lisp_Process *wait_proc; int just_wait_proc; { [... code elided ...] for (channel = 0; channel <= max_process_desc; channel++) { >>>> if (FD_ISSET (channel, &Available) && FD_ISSET (channel, &non_keyboard_wait_mask)) { int nread; /* If waiting for this channel, arrange to return as soon as no more input to be processed. No more waiting. */ if (wait_channel == channel) { wait_channel = -1; time_limit = -1; got_some_input = 1; } proc = chan_process[channel]; if (NILP (proc)) continue; /* If this is a server stream socket, accept connection. */ if (EQ (XPROCESS (proc)->status, Qlisten)) { server_accept_connection (proc, channel); continue; } /* Read data from the process, starting with our buffered-ahead character if we have one. */ nread = read_process_output (proc, channel); if (nread > 0) { /* Since read_process_output can run a filter, which can call accept-process-output, don't try to read from any other processes before doing the select again. */ FD_ZERO (&Available); if (do_display) redisplay_preserve_echo_area (12); } #ifdef EWOULDBLOCK else if (nread == -1 && errno == EWOULDBLOCK) ; #endif /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK, and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */ #ifdef O_NONBLOCK else if (nread == -1 && errno == EAGAIN) ; #else #ifdef O_NDELAY else if (nread == -1 && errno == EAGAIN) ; /* Note that we cannot distinguish between no input available now and a closed pipe. With luck, a closed pipe will be accompanied by subprocess termination and SIGCHLD. */ else if (nread == 0 && !NETCONN_P (proc)) ; #endif /* O_NDELAY */ #endif /* O_NONBLOCK */ #ifdef HAVE_PTYS /* On some OSs with ptys, when the process on one end of a pty exits, the other end gets an error reading with errno = EIO instead of getting an EOF (0 bytes read). Therefore, if we get an error reading and errno = EIO, just continue, because the child process has exited and should clean itself up soon (e.g. when we get a SIGCHLD). However, it has been known to happen that the SIGCHLD got lost. So raise the signl again just in case. It can't hurt. */ else if (nread == -1 && errno == EIO) kill (getpid (), SIGCHLD); #endif /* HAVE_PTYS */ /* If we can detect process termination, don't consider the process gone just because its pipe is closed. */ #ifdef SIGCHLD else if (nread == 0 && !NETCONN_P (proc)) ; #endif else { /* Preserve status of processes already terminated. */ XSETINT (XPROCESS (proc)->tick, ++process_tick); deactivate_process (proc); if (!NILP (XPROCESS (proc)->raw_status_low)) update_status (XPROCESS (proc)); if (EQ (XPROCESS (proc)->status, Qrun)) XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); } } #ifdef NON_BLOCKING_CONNECT >>>> if (check_connect && FD_ISSET (channel, &Connecting) && FD_ISSET (channel, &connect_wait_mask)) { struct Lisp_Process *p; FD_CLR (channel, &connect_wait_mask); if (--num_pending_connects < 0) abort (); proc = chan_process[channel]; if (NILP (proc)) continue; p = XPROCESS (proc); #ifdef GNU_LINUX /* getsockopt(,,SO_ERROR,,) is said to hang on some systems. So only use it on systems where it is known to work. */ { int xlen = sizeof(xerrno); if (getsockopt(channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen)) xerrno = errno; } #else { struct sockaddr pname; int pnamelen = sizeof(pname); /* If connection failed, getpeername will fail. */ xerrno = 0; if (getpeername(channel, &pname, &pnamelen) < 0) { /* Obtain connect failure code through error slippage. */ char dummy; xerrno = errno; if (errno == ENOTCONN && read(channel, &dummy, 1) < 0) xerrno = errno; } } #endif if (xerrno) { XSETINT (p->tick, ++process_tick); p->status = Fcons (Qfailed, Fcons (make_number (xerrno), Qnil)); deactivate_process (proc); } else { p->status = Qrun; /* Execute the sentinel here. If we had relied on status_notify to do it later, it will read input from the process before calling the sentinel. */ exec_sentinel (proc, build_string ("open\n")); if (!EQ (p->filter, Qt) && !EQ (p->command, Qt)) { FD_SET (XINT (p->infd), &input_wait_mask); FD_SET (XINT (p->infd), &non_keyboard_wait_mask); } } >>> } #endif /* NON_BLOCKING_CONNECT */ } /* end for each file descriptor */ -- Peter Seibel address@hidden Lisp is the red pill. -- John Fraser, comp.lang.lisp