Use SOCK_STREAM for socketpair, not SOCK_DGRAM so we get consistent

semantics when the other end closes.  This should make the conversion
to poll() less problematic.
This commit is contained in:
Todd C. Miller
2013-10-12 05:39:02 -06:00
parent a6b4f41103
commit ff18c65862
2 changed files with 24 additions and 25 deletions

View File

@@ -255,7 +255,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
* 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"));
/*
@@ -374,12 +374,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
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;
@@ -391,8 +386,16 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
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) {
@@ -505,17 +508,8 @@ dispatch_signals(int sv[2], pid_t child, int log_io, struct command_status *csta
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.

View File

@@ -1170,11 +1170,16 @@ exec_monitor(struct command_details *details, int backchannel)
/* 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"),