* We communicate with the child over a bi-directional pair of sockets.
* Parent sends signal info to child and child sends back wait status.
*/
- if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
fatal(_("unable to create sockets"));
/*
if (n == -1) {
if (errno == EINTR)
continue;
- /*
- * If not logging I/O we may receive ECONNRESET when
- * the command is executed and sv is closed.
- * It is safe to ignore this.
- */
- if (log_io && errno != EAGAIN) {
+ if (errno != EAGAIN) {
cstat->type = CMD_ERRNO;
cstat->val = errno;
break;
sudo_debug_printf(SUDO_DEBUG_ERROR,
"failed to read child status: %s",
n ? "short read" : "EOF");
- /* XXX - should set cstat */
- break;
+ /*
+ * If not logging I/O we may get EOF when the command is
+ * executed and sv is closed. It is safe to ignore this.
+ */
+ if (log_io || n != 0) {
+ /* XXX - need new CMD_ type for monitor errors. */
+ cstat->type = CMD_ERRNO;
+ cstat->val = n ? EIO : ECONNRESET;
+ break;
+ }
}
}
if (cstat->type == CMD_PID) {
do {
pid = waitpid(child, &status, WUNTRACED|WNOHANG);
} while (pid == -1 && errno == EINTR);
- if (pid == child) {
- if (log_io) {
- /*
- * On BSD we get ECONNRESET on sv[0] if monitor dies
- * and select() will return with sv[0] readable.
- * On Linux that doesn't appear to happen so if the
- * monitor dies, shut down the socketpair to force a
- * select() notification.
- */
- (void) shutdown(sv[0], SHUT_WR);
- } else if (WIFSTOPPED(status)) {
+ if (pid == child && !log_io) {
+ if (WIFSTOPPED(status)) {
/*
* Save the controlling terminal's process group
* so we can restore it after we resume, if needed.
/* read command from backchannel, should be a signal */
n = recv(backchannel, &cstmp, sizeof(cstmp), 0);
- if (n == -1) {
- if (errno == EINTR)
- continue;
- warning(_("error reading from socketpair"));
- goto done;
+ if (n != sizeof(cstmp)) {
+ if (n == -1) {
+ if (errno == EINTR)
+ continue;
+ warning(_("error reading from socketpair"));
+ goto done;
+ } else {
+ /* /* short read or EOF, parent process died? */
+ goto done;
+ }
}
if (cstmp.type != CMD_SIGNO) {
warningx(_("unexpected reply type on backchannel: %d"),