summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-11-16 17:10:07 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-11-16 17:10:07 +0000
commitea3df69903ba07d2a69c47af08cc3c0da9764b8d (patch)
treef60a6dd4b5516d879ae7e4040979a92c78201124
parentcb8b27e414038a9ede4e7df3653fdb54a0f836b3 (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.c38
-rw-r--r--usr.bin/mail/extern.h5
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));