rewrite errpipe callbacks
This commit is contained in:
@@ -301,46 +301,44 @@ static void
|
|||||||
mon_errpipe_cb(int fd, int what, void *v)
|
mon_errpipe_cb(int fd, int what, void *v)
|
||||||
{
|
{
|
||||||
struct monitor_closure *mc = v;
|
struct monitor_closure *mc = v;
|
||||||
ssize_t n;
|
ssize_t nread;
|
||||||
int errval;
|
int errval;
|
||||||
debug_decl(mon_errpipe_cb, SUDO_DEBUG_EXEC);
|
debug_decl(mon_errpipe_cb, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
/* read errno from child or EOF when command is executed. */
|
/*
|
||||||
n = read(fd, &errval, sizeof(errval));
|
* Read errno from child or EOF when command is executed.
|
||||||
switch (n) {
|
* Note that the error pipe is *blocking*.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
nread = read(fd, &errval, sizeof(errval));
|
||||||
|
} while (nread == -1 && errno == EINTR);
|
||||||
|
|
||||||
|
switch (nread) {
|
||||||
case -1:
|
case -1:
|
||||||
switch (errno) {
|
if (errno != EAGAIN) {
|
||||||
case EINTR:
|
if (mc->cstat->val == CMD_INVALID) {
|
||||||
/* got a signal, restart loop to service it. */
|
/* XXX - need a way to distinguish non-exec error. */
|
||||||
sudo_ev_loopcontinue(mc->evbase);
|
|
||||||
break;
|
|
||||||
case EAGAIN:
|
|
||||||
/* not ready after all... */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR,
|
|
||||||
"failed to read error pipe: %s", strerror(errno));
|
|
||||||
mc->cstat->type = CMD_ERRNO;
|
mc->cstat->type = CMD_ERRNO;
|
||||||
mc->cstat->val = errno;
|
mc->cstat->val = errno;
|
||||||
|
}
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
|
"%s: failed to read error pipe", __func__);
|
||||||
sudo_ev_loopbreak(mc->evbase);
|
sudo_ev_loopbreak(mc->evbase);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0:
|
|
||||||
/*
|
|
||||||
* We get EOF when the command is executed and the other
|
|
||||||
* end of the error pipe is closed. Just remove the event.
|
|
||||||
*/
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe, removing event");
|
|
||||||
sudo_ev_del(mc->evbase, mc->errpipe_event);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
if (nread == 0) {
|
||||||
|
/* The error pipe closes when the command is executed. */
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe");
|
||||||
|
} else {
|
||||||
/* Errno value when child is unable to execute command. */
|
/* Errno value when child is unable to execute command. */
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
|
||||||
strerror(errval));
|
strerror(errval));
|
||||||
mc->cstat->type = CMD_ERRNO;
|
mc->cstat->type = CMD_ERRNO;
|
||||||
mc->cstat->val = errval;
|
mc->cstat->val = errval;
|
||||||
|
}
|
||||||
sudo_ev_del(mc->evbase, mc->errpipe_event);
|
sudo_ev_del(mc->evbase, mc->errpipe_event);
|
||||||
|
close(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
|
@@ -56,46 +56,44 @@ static void
|
|||||||
errpipe_cb(int fd, int what, void *v)
|
errpipe_cb(int fd, int what, void *v)
|
||||||
{
|
{
|
||||||
struct exec_closure_nopty *ec = v;
|
struct exec_closure_nopty *ec = v;
|
||||||
ssize_t n;
|
ssize_t nread;
|
||||||
int errval;
|
int errval;
|
||||||
debug_decl(errpipe_cb, SUDO_DEBUG_EXEC)
|
debug_decl(errpipe_cb, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
/* read errno from child or EOF when command is executed. */
|
/*
|
||||||
n = read(fd, &errval, sizeof(errval));
|
* Read errno from child or EOF when command is executed.
|
||||||
switch (n) {
|
* Note that the error pipe is *blocking*.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
nread = read(fd, &errval, sizeof(errval));
|
||||||
|
} while (nread == -1 && errno == EINTR);
|
||||||
|
|
||||||
|
switch (nread) {
|
||||||
case -1:
|
case -1:
|
||||||
switch (errno) {
|
if (errno != EAGAIN) {
|
||||||
case EINTR:
|
if (ec->cstat->val == CMD_INVALID) {
|
||||||
/* got a signal, restart loop to service it. */
|
/* XXX - need a way to distinguish non-exec error. */
|
||||||
sudo_ev_loopcontinue(ec->evbase);
|
|
||||||
break;
|
|
||||||
case EAGAIN:
|
|
||||||
/* not ready after all... */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR,
|
|
||||||
"failed to read error pipe: %s", strerror(errno));
|
|
||||||
ec->cstat->type = CMD_ERRNO;
|
ec->cstat->type = CMD_ERRNO;
|
||||||
ec->cstat->val = errno;
|
ec->cstat->val = errno;
|
||||||
|
}
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
|
"%s: failed to read error pipe", __func__);
|
||||||
sudo_ev_loopbreak(ec->evbase);
|
sudo_ev_loopbreak(ec->evbase);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0:
|
|
||||||
/*
|
|
||||||
* We get EOF when the command is executed and the other
|
|
||||||
* end of the error pipe is closed. Just remove the event.
|
|
||||||
*/
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe, removing event");
|
|
||||||
sudo_ev_del(ec->evbase, ec->errpipe_event);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
if (nread == 0) {
|
||||||
|
/* The error pipe closes when the command is executed. */
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO, "EOF on error pipe");
|
||||||
|
} else {
|
||||||
/* Errno value when child is unable to execute command. */
|
/* Errno value when child is unable to execute command. */
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "errno from child: %s",
|
||||||
strerror(errval));
|
strerror(errval));
|
||||||
ec->cstat->type = CMD_ERRNO;
|
ec->cstat->type = CMD_ERRNO;
|
||||||
ec->cstat->val = errval;
|
ec->cstat->val = errval;
|
||||||
|
}
|
||||||
sudo_ev_del(ec->evbase, ec->errpipe_event);
|
sudo_ev_del(ec->evbase, ec->errpipe_event);
|
||||||
|
close(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
|
Reference in New Issue
Block a user