X-Git-Url: https://git.distorted.org.uk/~mdw/xtoys/blobdiff_plain/566df6918473da40008c3871420ba9c44d454110..d0499b4efd7fd2731d1b6fbe10e7503709f7501a:/xcatch.c diff --git a/xcatch.c b/xcatch.c index 43d3b02..6ddb4ea 100644 --- a/xcatch.c +++ b/xcatch.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: xcatch.c,v 1.4 1999/03/24 22:23:57 mdw Exp $ + * $Id: xcatch.c,v 1.10 2004/04/08 01:36:29 mdw Exp $ * * Catch input and trap it in an X window * @@ -26,25 +26,6 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: xcatch.c,v $ - * Revision 1.4 1999/03/24 22:23:57 mdw - * Improve display for large files. Keep newly added material in view if - * scrolled to bottom of window. - * - * Revision 1.3 1998/12/20 17:19:16 mdw - * Return exit status of child process, rather than always returning - * success. - * - * Revision 1.2 1998/12/16 00:10:58 mdw - * Fix tabbing in help text. - * - * Revision 1.1 1998/12/15 23:46:50 mdw - * New program: captures input and puts it in a window. - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -73,10 +54,8 @@ static unsigned int flags; -enum { - f_closed = 1, - f_bogus = 2 -}; +#define f_closed 1u +#define f_bogus 2u static GtkWidget *textbox = 0; static GdkFont *font; @@ -102,8 +81,8 @@ static void ready(gpointer data, gint fd, GdkInputCondition c) { char buf[1024]; int doscroll = 1; - GtkText *t; - GtkAdjustment *va; + GtkText *t = 0; + GtkAdjustment *va = 0; /* --- If not ready to read then go away --- */ @@ -138,7 +117,7 @@ static void ready(gpointer data, gint fd, GdkInputCondition c) if (r < 0) { if (errno == EWOULDBLOCK) break; - msg(":~OK", "error reading data: %s", strerror(errno)); + msg(QUIS, ":~OK", "error reading data: %s", strerror(errno)); exit(EXIT_FAILURE); } @@ -165,12 +144,13 @@ static void ready(gpointer data, gint fd, GdkInputCondition c) GtkWidget *w; win = gtk_dialog_new(); + gtk_window_set_policy(GTK_WINDOW(win), 1, 1, 0); gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(killwin), 0); tbl = gtk_table_new(2, 2, 0); gtk_container_border_width(GTK_CONTAINER(tbl), 8); - gtk_box_pack_start(GTK_BOX(GTK_DIALOG(win)->vbox), tbl, 1, 1, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(win)->vbox), tbl, 1, 1, 1); gtk_widget_show(tbl); textbox = gtk_text_new(0, 0); @@ -225,6 +205,7 @@ static void reap(int sig) { pid_t k; int s; + int e = errno; for (;;) { k = waitpid(-1, &s, WNOHANG); @@ -237,6 +218,7 @@ static void reap(int sig) status = 127; } } + errno = e; } /* --- Main program --- */ @@ -264,11 +246,11 @@ int main(int argc, char *argv[]) { "help", 0, 0, 'h' }, { "usage", 0, 0, 'u' }, { "version", 0, 0, 'v' }, - { "file", gFlag_argReq, 0, 'f' }, - { "font", gFlag_argReq, 0, 'F' }, + { "file", OPTF_ARGREQ, 0, 'f' }, + { "font", OPTF_ARGREQ, 0, 'F' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "huvf:F:", opt, 0, 0, 0); + int i = mdwopt(argc, argv, "+huvf:F:", opt, 0, 0, 0); if (i < 0) break; @@ -327,23 +309,32 @@ int main(int argc, char *argv[]) else { int pfd[2]; struct sigaction sa; + sigset_t newmask, oldmask; /* --- Set up a signal handler --- */ sa.sa_handler = reap; sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; + sa.sa_flags = SA_NOCLDSTOP; +#ifdef SA_RESTART + sa.sa_flags |= SA_RESTART; +#endif sigaction(SIGCHLD, &sa, 0); /* --- Start a child program --- */ if (pipe(pfd)) die(1, "couldn't open pipe: %s", strerror(errno)); + + sigemptyset(&newmask); + sigaddset(&newmask, SIGCHLD); + sigprocmask(SIG_BLOCK, &newmask, &oldmask); + kid = fork(); if (kid < 0) die(1, "couldn't fork: %s", strerror(errno)); if (kid == 0) { - dstr d; + dstr d = DSTR_INIT; close(pfd[0]); if (pfd[1] != STDOUT_FILENO) @@ -354,12 +345,14 @@ int main(int argc, char *argv[]) close(pfd[1]); execvp(argv[optind], argv + optind); - dstr_create(&d); dstr_putf(&d, "%s: couldn't run `%s': %s\n", QUIS, argv[optind], strerror(errno)); write(STDERR_FILENO, d.buf, d.len); + dstr_destroy(&d); _exit(127); } + + sigprocmask(SIG_SETMASK, &oldmask, 0); fd = pfd[0]; close(pfd[1]); }