/*
* Read/write iobufs depending on fdsr and fdsw.
+ * Returns the number of errors.
*/
static int
perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
{
struct io_buffer *iob;
- int n = 0;
+ int n, errors = 0;
for (iob = iobufs; iob; iob = iob->next) {
if (iob->rfd != -1 && FD_ISSET(iob->rfd, fdsr)) {
iob->len - iob->off);
} while (n == -1 && errno == EINTR);
if (n == -1) {
+ if (errno == EPIPE) {
+ /* other end of pipe closed */
+ if (iob->rfd != -1) {
+ close(iob->rfd);
+ iob->rfd = -1;
+ }
+ close(iob->wfd);
+ iob->wfd = -1;
+ continue;
+ }
if (errno != EAGAIN)
- break;
+ errors++;
} else {
iob->off += n;
}
}
}
- return n == -1 ? -1 : 0;
+ return errors;
}
/*
zero_bytes(&sa, sizeof(sa));
sigemptyset(&sa.sa_mask);
- /* Ignore SIGPIPE, check errno instead... */
- sa.sa_flags = SA_RESTART;
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
-
/* Note: HP-UX select() will not be interrupted if SA_RESTART set */
sa.sa_flags = 0; /* do not restart syscalls */
sa.sa_handler = handler;
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
}
}
}
- if (perform_io(iobufs, fdsr, fdsw) == -1)
+ if (perform_io(iobufs, fdsr, fdsw) != 0)
break;
}
case SIGKILL:
_exit(1); /* XXX */
/* NOTREACHED */
+ case SIGPIPE:
case SIGHUP:
case SIGTERM:
case SIGINT:
sigaction(SIGWINCH, &sa, NULL);
sigaction(SIGALRM, &sa, NULL);
- /* Ignore any SIGTT{IN,OU} or SIGPIPE we get. */
+ /* Ignore any SIGTTIN or SIGTTOU we get. */
sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
sigaction(SIGTTIN, &sa, NULL);
sigaction(SIGTTOU, &sa, NULL);
continue;
error(1, "select failed");
}
- if (perform_io(iobufs, fdsr, fdsw) == -1)
+ if (perform_io(iobufs, fdsr, fdsw) != 0)
break;
}
efree(fdsr);