diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2001-11-16 17:10:07 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2001-11-16 17:10:07 +0000 |
commit | ea3df69903ba07d2a69c47af08cc3c0da9764b8d (patch) | |
tree | f60a6dd4b5516d879ae7e4040979a92c78201124 | |
parent | cb8b27e414038a9ede4e7df3653fdb54a0f836b3 (diff) |
Instead of using a longjmp to catch SIGPIPE, just set to SIG_IGN and
check the return value on writes for error.
Save and restore terminal modes when piping to a command so we end
up with a known good state if the command terminates uncleanly.
-rw-r--r-- | usr.bin/mail/cmd1.c | 38 | ||||
-rw-r--r-- | usr.bin/mail/extern.h | 5 |
2 files changed, 15 insertions, 28 deletions
diff --git a/usr.bin/mail/cmd1.c b/usr.bin/mail/cmd1.c index 647d1891fa4..fd2315be97b 100644 --- a/usr.bin/mail/cmd1.c +++ b/usr.bin/mail/cmd1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd1.c,v 1.18 2001/06/23 23:04:21 millert Exp $ */ +/* $OpenBSD: cmd1.c,v 1.19 2001/11/16 17:10:06 millert Exp $ */ /* $NetBSD: cmd1.c,v 1.9 1997/07/09 05:29:48 mikel Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)cmd1.c 8.2 (Berkeley) 4/20/95"; #else -static char rcsid[] = "$OpenBSD: cmd1.c,v 1.18 2001/06/23 23:04:21 millert Exp $"; +static char rcsid[] = "$OpenBSD: cmd1.c,v 1.19 2001/11/16 17:10:06 millert Exp $"; #endif #endif /* not lint */ @@ -335,32 +335,32 @@ Type(v) /* * Type out the messages requested. */ -sigjmp_buf pipestop; int type1(msgvec, cmd, doign, page) int *msgvec; char *cmd; int doign, page; { - int nlines, *ip; + int nlines, *ip, restoreterm; struct message *mp; + struct termios tbuf; char * volatile cp; FILE * volatile obuf; obuf = stdout; - if (sigsetjmp(pipestop, 1)) - goto close_pipe; + restoreterm = 0; /* * start a pipe if needed. */ if (cmd) { + restoreterm = (tcgetattr(fileno(stdin), &tbuf) == 0); obuf = Popen(cmd, "w"); if (obuf == NULL) { warn("%s", cp); obuf = stdout; } else { - (void)signal(SIGPIPE, brokpipe); + (void)signal(SIGPIPE, SIG_IGN); } } else if (value("interactive") != NULL && (page || (cp = value("crt")) != NULL)) { @@ -370,12 +370,13 @@ type1(msgvec, cmd, doign, page) nlines += message[*ip - 1].m_lines; } if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) { + restoreterm = (tcgetattr(fileno(stdin), &tbuf) == 0); obuf = Popen(value("PAGER"), "w"); if (obuf == NULL) { warn("%s", cp); obuf = stdout; } else - (void)signal(SIGPIPE, brokpipe); + (void)signal(SIGPIPE, SIG_IGN); } } @@ -388,33 +389,20 @@ type1(msgvec, cmd, doign, page) dot = mp; if (cmd == NULL && value("quiet") == NULL) fprintf(obuf, "Message %d:\n", *ip); - (void)sendmessage(mp, obuf, doign ? ignore : 0, NULL); + if (sendmessage(mp, obuf, doign ? ignore : 0, NULL) == -1) + break; } -close_pipe: if (obuf != stdout) { - /* - * Ignore SIGPIPE so it can't cause a duplicate close. - */ - (void)signal(SIGPIPE, SIG_IGN); (void)Pclose(obuf); (void)signal(SIGPIPE, SIG_DFL); + if (restoreterm) + (void)tcsetattr(fileno(stdin), TCSADRAIN, &tbuf); } return(0); } /* - * Respond to a broken pipe signal -- - * probably caused by quitting more. - */ -void -brokpipe(signo) - int signo; -{ - siglongjmp(pipestop, 1); -} - -/* * Print the top so many lines of each desired message. * The number of lines is taken from the variable "toplines" * and defaults to 5. diff --git a/usr.bin/mail/extern.h b/usr.bin/mail/extern.h index d3698d96308..fd7ad6453c1 100644 --- a/usr.bin/mail/extern.h +++ b/usr.bin/mail/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.16 2001/01/16 05:36:08 millert Exp $ */ +/* $OpenBSD: extern.h,v 1.17 2001/11/16 17:10:06 millert Exp $ */ /* $NetBSD: extern.h,v 1.7 1997/07/09 05:22:00 mikel Exp $ */ /*- @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)extern.h 8.2 (Berkeley) 4/20/95 - * $OpenBSD: extern.h,v 1.16 2001/01/16 05:36:08 millert Exp $ + * $OpenBSD: extern.h,v 1.17 2001/11/16 17:10:06 millert Exp $ */ struct name; @@ -96,7 +96,6 @@ int argcount __P((char **)); void assign __P((char [], char [])); int bangexp __P((char *, size_t)); int blankline __P((char [])); -void brokpipe __P((int)); int charcount __P((char *, int)); int check __P((int, int)); void clearnew __P((void)); |