Skip to content

Commit

Permalink
Handle SIGPIPE.
Browse files Browse the repository at this point in the history
Record exit status of failed shell command.
  • Loading branch information
slewsys committed Jan 5, 2025
1 parent 274974d commit 9ba8582
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
31 changes: 29 additions & 2 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ int
read_pipe (const char *fn, off_t after, off_t *addr,
off_t *size, ed_buffer_t *ed)
{
static char exit_status[BUFSIZ];

FILE *fp;
int status;

Expand All @@ -171,8 +173,14 @@ read_pipe (const char *fn, off_t after, off_t *addr,
*addr = ed->state->dot - after;

/* Ignore "no child" error. */
pclose (fp);
if ((status = pclose (fp)) != 0) {
snprintf (exit_status, sizeof exit_status, _("Exit status: %#x"),
WEXITSTATUS(status));
ed->exec->err = exit_status;
}
printf (ed->exec->opt & SCRIPTED ? "" : "!\n");

/* A shell command error is not an ed error, so always return 0. */
return 0;
}

Expand Down Expand Up @@ -540,6 +548,11 @@ get_stream_line (FILE *fp, size_t *len, ed_buffer_t *ed)
clearerr (fp);
errno = 0;
goto top;
case EPIPE:
ed->exec->err = _("Broken pipe");

/* Propagate stream status - don't call clearerr(3). */
return NULL;
default:
#ifdef F_GETPATH

Expand Down Expand Up @@ -671,6 +684,8 @@ int
write_pipe (const char *fn, off_t from, off_t to, off_t *addr,
off_t *size, ed_buffer_t *ed)
{
static char exit_status[BUFSIZ];

FILE *fp;
ed_line_node_t *lp = get_line_node (from, ed);
off_t n = from ? to - from + 1 : 0;
Expand All @@ -689,8 +704,14 @@ write_pipe (const char *fn, off_t from, off_t to, off_t *addr,
*addr = n;

/* Ignore "no child" error. */
pclose (fp);
if ((status = pclose (fp)) != 0) {
snprintf (exit_status, sizeof exit_status, _("Exit status: %#x"),
WEXITSTATUS(status));
ed->exec->err = exit_status;
}
printf (ed->exec->opt & SCRIPTED ? "" : "!\n");

/* A shell command error is not an ed error, so always return 0. */
return 0;
}

Expand Down Expand Up @@ -764,7 +785,13 @@ put_stream_line (FILE *fp, const char *s, size_t len, ed_buffer_t *ed)
{
case EINTR:
clearerr (fp);
errno = 0;
goto top;
case EPIPE:
ed->exec->err = _("Broken pipe");

/* Propagate stream status - don't call clearerr(3). */
return ERR;
default:
fprintf (stderr, "%s\n", strerror (errno));
ed->exec->err = _("File write error");
Expand Down
16 changes: 16 additions & 0 deletions src/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ signal_t sighandler[NSIG];
/* Static function declarations. */
static void handle_hup (int);
static void handle_int (int);
static void handle_sigpipe (int);
static void handle_winch (int);
static signal_t reliable_signal (int, signal_t);

Expand Down Expand Up @@ -84,6 +85,19 @@ handle_int (int signo)
}


static void
handle_sigpipe (int signo)
{
extern ed_buffer_t *ed;

if (!_sigactive)
quit (1, ed);
_sigflags &= ~(1 << (signo - 1));

/* Interrupted syscall should report broken pipe. */
}


static void
handle_winch (int signo)
{
Expand Down Expand Up @@ -117,6 +131,7 @@ init_signal_handler (ed_buffer_t *ed)
{
/* Override signo-indexed LUT for handlers of interest. */
sighandler[SIGHUP - 1] = handle_hup;
sighandler[SIGPIPE - 1] = handle_sigpipe;
sighandler[SIGINT - 1] = handle_int;
#ifdef SIGWINCH
sighandler[SIGWINCH - 1] = handle_winch;
Expand All @@ -126,6 +141,7 @@ init_signal_handler (ed_buffer_t *ed)
if (reliable_signal (SIGCHLD, SIG_DFL) == SIG_ERR
|| reliable_signal (SIGHUP, signal_handler) == SIG_ERR
|| reliable_signal (SIGINT, signal_handler) == SIG_ERR
|| reliable_signal (SIGPIPE, signal_handler) == SIG_ERR
|| reliable_signal (SIGQUIT, SIG_IGN) == SIG_ERR
#ifdef SIGWINCH
|| (isatty (0) && reliable_signal (SIGWINCH, signal_handler) == SIG_ERR)
Expand Down

0 comments on commit 9ba8582

Please sign in to comment.