Fix SIGPIPE handling. Now that we use may use pipes for stdin/stdout
we need to pass any SIGPIPE we receive to the running command.
This commit is contained in:
31
src/script.c
31
src/script.c
@@ -413,12 +413,13 @@ io_buf_new(int rfd, int wfd, int (*action)(char *, unsigned int),
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Read/write iobufs depending on fdsr and fdsw.
|
* Read/write iobufs depending on fdsr and fdsw.
|
||||||
|
* Returns the number of errors.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
|
perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
|
||||||
{
|
{
|
||||||
struct io_buffer *iob;
|
struct io_buffer *iob;
|
||||||
int n = 0;
|
int n, errors = 0;
|
||||||
|
|
||||||
for (iob = iobufs; iob; iob = iob->next) {
|
for (iob = iobufs; iob; iob = iob->next) {
|
||||||
if (iob->rfd != -1 && FD_ISSET(iob->rfd, fdsr)) {
|
if (iob->rfd != -1 && FD_ISSET(iob->rfd, fdsr)) {
|
||||||
@@ -445,14 +446,24 @@ perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
|
|||||||
iob->len - iob->off);
|
iob->len - iob->off);
|
||||||
} while (n == -1 && errno == EINTR);
|
} while (n == -1 && errno == EINTR);
|
||||||
if (n == -1) {
|
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)
|
if (errno != EAGAIN)
|
||||||
break;
|
errors++;
|
||||||
} else {
|
} else {
|
||||||
iob->off += n;
|
iob->off += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n == -1 ? -1 : 0;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -511,11 +522,6 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
|
|||||||
zero_bytes(&sa, sizeof(sa));
|
zero_bytes(&sa, sizeof(sa));
|
||||||
sigemptyset(&sa.sa_mask);
|
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 */
|
/* Note: HP-UX select() will not be interrupted if SA_RESTART set */
|
||||||
sa.sa_flags = 0; /* do not restart syscalls */
|
sa.sa_flags = 0; /* do not restart syscalls */
|
||||||
sa.sa_handler = handler;
|
sa.sa_handler = handler;
|
||||||
@@ -523,6 +529,7 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
|
|||||||
sigaction(SIGCHLD, &sa, NULL);
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
sigaction(SIGINT, &sa, NULL);
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
sigaction(SIGPIPE, &sa, NULL);
|
||||||
sigaction(SIGQUIT, &sa, NULL);
|
sigaction(SIGQUIT, &sa, NULL);
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
|
|
||||||
@@ -811,7 +818,7 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (perform_io(iobufs, fdsr, fdsw) == -1)
|
if (perform_io(iobufs, fdsr, fdsw) != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,6 +867,7 @@ deliver_signal(pid_t pid, int signo)
|
|||||||
case SIGKILL:
|
case SIGKILL:
|
||||||
_exit(1); /* XXX */
|
_exit(1); /* XXX */
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
case SIGPIPE:
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
@@ -929,9 +937,8 @@ script_child(const char *path, char *argv[], char *envp[], int backchannel, int
|
|||||||
sigaction(SIGWINCH, &sa, NULL);
|
sigaction(SIGWINCH, &sa, NULL);
|
||||||
sigaction(SIGALRM, &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;
|
sa.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &sa, NULL);
|
|
||||||
sigaction(SIGTTIN, &sa, NULL);
|
sigaction(SIGTTIN, &sa, NULL);
|
||||||
sigaction(SIGTTOU, &sa, NULL);
|
sigaction(SIGTTOU, &sa, NULL);
|
||||||
|
|
||||||
@@ -1198,7 +1205,7 @@ flush_output(struct io_buffer *iobufs)
|
|||||||
continue;
|
continue;
|
||||||
error(1, "select failed");
|
error(1, "select failed");
|
||||||
}
|
}
|
||||||
if (perform_io(iobufs, fdsr, fdsw) == -1)
|
if (perform_io(iobufs, fdsr, fdsw) != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
efree(fdsr);
|
efree(fdsr);
|
||||||
|
Reference in New Issue
Block a user