summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/mail/aux.c14
-rw-r--r--usr.bin/mail/cmd1.c52
-rw-r--r--usr.bin/mail/cmd3.c21
-rw-r--r--usr.bin/mail/collect.c234
-rw-r--r--usr.bin/mail/def.h11
-rw-r--r--usr.bin/mail/edit.c13
-rw-r--r--usr.bin/mail/extern.h22
-rw-r--r--usr.bin/mail/fio.c107
-rw-r--r--usr.bin/mail/glob.h7
-rw-r--r--usr.bin/mail/lex.c79
-rw-r--r--usr.bin/mail/main.c77
-rw-r--r--usr.bin/mail/quit.c63
-rw-r--r--usr.bin/mail/tty.c152
13 files changed, 458 insertions, 394 deletions
diff --git a/usr.bin/mail/aux.c b/usr.bin/mail/aux.c
index 17beb8e6174..043fcea28e6 100644
--- a/usr.bin/mail/aux.c
+++ b/usr.bin/mail/aux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aux.c,v 1.18 2001/09/16 16:12:56 millert Exp $ */
+/* $OpenBSD: aux.c,v 1.19 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: aux.c,v 1.5 1997/05/13 06:15:52 mikel Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)aux.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: aux.c,v 1.18 2001/09/16 16:12:56 millert Exp $";
+static char rcsid[] = "$OpenBSD: aux.c,v 1.19 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -150,7 +150,7 @@ hfield(field, mp)
ibuf = setinput(mp);
if ((lc = mp->m_lines - 1) < 0)
return(NULL);
- if (readline(ibuf, linebuf, LINESIZE) < 0)
+ if (readline(ibuf, linebuf, LINESIZE, NULL) < 0)
return(NULL);
while (lc > 0) {
if ((lc = gethfield(ibuf, linebuf, lc, &colon)) < 0)
@@ -181,7 +181,7 @@ gethfield(f, linebuf, rem, colon)
for (;;) {
if (--rem < 0)
return(-1);
- if ((c = readline(f, linebuf, LINESIZE)) <= 0)
+ if ((c = readline(f, linebuf, LINESIZE, NULL)) <= 0)
return(-1);
for (cp = linebuf; isprint(*cp) && *cp != ' ' && *cp != ':';
cp++)
@@ -203,7 +203,7 @@ gethfield(f, linebuf, rem, colon)
ungetc(c = getc(f), f);
if (c != ' ' && c != '\t')
break;
- if ((c = readline(f, line2, LINESIZE)) < 0)
+ if ((c = readline(f, line2, LINESIZE, NULL)) < 0)
break;
rem--;
for (cp2 = line2; *cp2 == ' ' || *cp2 == '\t'; cp2++)
@@ -559,7 +559,7 @@ name1(mp, reptype)
return(cp);
ibuf = setinput(mp);
namebuf[0] = '\0';
- if (readline(ibuf, linebuf, LINESIZE) < 0)
+ if (readline(ibuf, linebuf, LINESIZE, NULL) < 0)
return(savestr(namebuf));
newname:
for (cp = linebuf; *cp && *cp != ' '; cp++)
@@ -570,7 +570,7 @@ newname:
*cp && *cp != ' ' && *cp != '\t' && cp2 < namebuf + LINESIZE - 1;)
*cp2++ = *cp++;
*cp2 = '\0';
- if (readline(ibuf, linebuf, LINESIZE) < 0)
+ if (readline(ibuf, linebuf, LINESIZE, NULL) < 0)
return(savestr(namebuf));
if ((cp = strchr(linebuf, 'F')) == NULL)
return(savestr(namebuf));
diff --git a/usr.bin/mail/cmd1.c b/usr.bin/mail/cmd1.c
index fd2315be97b..4d4c98fafb8 100644
--- a/usr.bin/mail/cmd1.c
+++ b/usr.bin/mail/cmd1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd1.c,v 1.19 2001/11/16 17:10:06 millert Exp $ */
+/* $OpenBSD: cmd1.c,v 1.20 2001/11/20 20:50:00 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.19 2001/11/16 17:10:06 millert Exp $";
+static char rcsid[] = "$OpenBSD: cmd1.c,v 1.20 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -57,6 +57,7 @@ static char rcsid[] = "$OpenBSD: cmd1.c,v 1.19 2001/11/16 17:10:06 millert Exp $
*/
static int screen;
+static volatile sig_atomic_t gothdrint;
int
headers(v)
@@ -65,6 +66,8 @@ headers(v)
int *msgvec = v;
int n, mesg, flag, size;
struct message *mp;
+ struct sigaction act, oact;
+ sigset_t oset;
size = screensize();
n = msgvec[0];
@@ -81,7 +84,15 @@ headers(v)
mesg = mp - &message[0];
if (dot != &message[n-1])
dot = mp;
- for (; mp < &message[msgCount]; mp++) {
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = hdrint;
+ if (sigaction(SIGINT, NULL, &oact) == 0 &&
+ oact.sa_handler != SIG_IGN) {
+ (void)sigaction(SIGINT, &act, &oact);
+ (void)sigprocmask(SIG_UNBLOCK, &intset, &oset);
+ }
+ for (gothdrint = 0; !gothdrint && mp < &message[msgCount]; mp++) {
mesg++;
if (mp->m_flag & MDELETED)
continue;
@@ -89,6 +100,14 @@ headers(v)
break;
printhead(mesg);
}
+ if (gothdrint) {
+ fflush(stdout);
+ fputs("\nInterrupt\n", stderr);
+ }
+ if (oact.sa_handler != SIG_IGN) {
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
+ }
if (flag == 0) {
puts("No more mail.");
return(1);
@@ -186,7 +205,7 @@ printhead(mesg)
char **ap;
mp = &message[mesg-1];
- (void)readline(setinput(mp), headline, LINESIZE);
+ (void)readline(setinput(mp), headline, LINESIZE, NULL);
if ((subjline = hfield("subject", mp)) == NULL)
subjline = hfield("subj", mp);
/*
@@ -344,8 +363,8 @@ type1(msgvec, cmd, doign, page)
int nlines, *ip, restoreterm;
struct message *mp;
struct termios tbuf;
- char * volatile cp;
- FILE * volatile obuf;
+ char *cp;
+ FILE *obuf;
obuf = stdout;
restoreterm = 0;
@@ -357,10 +376,8 @@ type1(msgvec, cmd, doign, page)
restoreterm = (tcgetattr(fileno(stdin), &tbuf) == 0);
obuf = Popen(cmd, "w");
if (obuf == NULL) {
- warn("%s", cp);
+ warn("%s", cmd);
obuf = stdout;
- } else {
- (void)signal(SIGPIPE, SIG_IGN);
}
} else if (value("interactive") != NULL &&
(page || (cp = value("crt")) != NULL)) {
@@ -375,8 +392,7 @@ type1(msgvec, cmd, doign, page)
if (obuf == NULL) {
warn("%s", cp);
obuf = stdout;
- } else
- (void)signal(SIGPIPE, SIG_IGN);
+ }
}
}
@@ -395,7 +411,6 @@ type1(msgvec, cmd, doign, page)
if (obuf != stdout) {
(void)Pclose(obuf);
- (void)signal(SIGPIPE, SIG_DFL);
if (restoreterm)
(void)tcsetattr(fileno(stdin), TCSADRAIN, &tbuf);
}
@@ -437,7 +452,7 @@ top(v)
if (!lineb)
putchar('\n');
for (lines = 0; lines < c && lines <= topl; lines++) {
- if (readline(ibuf, linebuf, sizeof(linebuf)) < 0)
+ if (readline(ibuf, linebuf, sizeof(linebuf), NULL) < 0)
break;
puts(linebuf);
lineb = blankline(linebuf);
@@ -528,3 +543,14 @@ inc(v)
return(0);
}
+
+/*
+ * User hit ^C while printing the headers.
+ */
+void
+hdrint(s)
+ int s;
+{
+
+ gothdrint = 1;
+}
diff --git a/usr.bin/mail/cmd3.c b/usr.bin/mail/cmd3.c
index 7b9d878c6f6..845350a765f 100644
--- a/usr.bin/mail/cmd3.c
+++ b/usr.bin/mail/cmd3.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd3.c,v 1.15 2001/01/19 04:11:28 millert Exp $ */
+/* $OpenBSD: cmd3.c,v 1.16 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: cmd3.c,v 1.8 1997/07/09 05:29:49 mikel Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
#else
-static char rcsid[] = "$OpenBSD: cmd3.c,v 1.15 2001/01/19 04:11:28 millert Exp $";
+static char rcsid[] = "$OpenBSD: cmd3.c,v 1.16 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -61,17 +61,19 @@ shell(v)
void *v;
{
char *str = v;
- sig_t sigint = signal(SIGINT, SIG_IGN);
char *shell;
char cmd[BUFSIZ];
+ struct sigaction oact;
+ sigset_t oset;
- (void)strncpy(cmd, str, sizeof(cmd) - 1);
- cmd[sizeof(cmd) - 1] = '\0';
+ (void)ignoresig(SIGINT, &oact, &oset);
+ (void)strlcpy(cmd, str, sizeof(cmd));
if (bangexp(cmd, sizeof(cmd)) < 0)
return(1);
shell = value("SHELL");
(void)run_command(shell, 0, 0, -1, "-c", cmd, NULL);
- (void)signal(SIGINT, sigint);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
puts("!");
return(0);
}
@@ -84,12 +86,15 @@ int
dosh(v)
void *v;
{
- sig_t sigint = signal(SIGINT, SIG_IGN);
char *shell;
+ struct sigaction oact;
+ sigset_t oset;
shell = value("SHELL");
+ (void)ignoresig(SIGINT, &oact, &oset);
(void)run_command(shell, 0, 0, -1, NULL, NULL, NULL);
- (void)signal(SIGINT, sigint);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
putchar('\n');
return(0);
}
diff --git a/usr.bin/mail/collect.c b/usr.bin/mail/collect.c
index 0274b3115c7..60d14da6a70 100644
--- a/usr.bin/mail/collect.c
+++ b/usr.bin/mail/collect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: collect.c,v 1.21 2001/06/23 23:04:21 millert Exp $ */
+/* $OpenBSD: collect.c,v 1.22 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: collect.c,v 1.9 1997/07/09 05:25:45 mikel Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)collect.c 8.2 (Berkeley) 4/19/94";
#else
-static char rcsid[] = "$OpenBSD: collect.c,v 1.21 2001/06/23 23:04:21 millert Exp $";
+static char rcsid[] = "$OpenBSD: collect.c,v 1.22 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -63,55 +63,31 @@ static char rcsid[] = "$OpenBSD: collect.c,v 1.21 2001/06/23 23:04:21 millert Ex
* away on dead.letter.
*/
-static sig_t saveint; /* Previous SIGINT value */
-static sig_t savehup; /* Previous SIGHUP value */
-static sig_t savetstp; /* Previous SIGTSTP value */
-static sig_t savettou; /* Previous SIGTTOU value */
-static sig_t savettin; /* Previous SIGTTIN value */
static FILE *collf; /* File for saving away */
static int hadintr; /* Have seen one SIGINT so far */
-static sigjmp_buf colljmp; /* To get back to work */
-static int colljmp_p; /* whether to long jump */
-static sigjmp_buf collabort; /* To end collection with error */
-
FILE *
collect(hp, printheaders)
struct header *hp;
int printheaders;
{
FILE *fbuf;
- int lc, cc, fd, c, t, lastlong, rc;
- volatile int escape, eofcount, longline;
- volatile char getsub;
+ int lc, cc, fd, c, t, lastlong, rc, sig;
+ int escape, eofcount, longline;
+ char getsub;
char linebuf[LINESIZE], tempname[PATHSIZE], *cp;
- sigset_t oset, nset;
collf = NULL;
- /*
- * Start catching signals from here, but we're still die on interrupts
- * until we're in the main loop.
- */
- sigemptyset(&nset);
- sigaddset(&nset, SIGINT);
- sigaddset(&nset, SIGHUP);
- sigprocmask(SIG_BLOCK, &nset, &oset);
- if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
- (void)signal(SIGINT, collint);
- if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
- (void)signal(SIGHUP, collhup);
- savetstp = signal(SIGTSTP, collstop);
- savettou = signal(SIGTTOU, collstop);
- savettin = signal(SIGTTIN, collstop);
- if (sigsetjmp(collabort, 1) || sigsetjmp(colljmp, 1)) {
- (void)rm(tempname);
- goto err;
- }
- sigdelset(&oset, SIGINT);
- sigdelset(&oset, SIGHUP);
- sigprocmask(SIG_SETMASK, &oset, NULL);
-
+ eofcount = 0;
+ hadintr = 0;
+ lastlong = 0;
+ longline = 0;
+ if ((cp = value("escape")) != NULL)
+ escape = *cp;
+ else
+ escape = ESCAPE;
noreset++;
+
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.RsXXXXXXXXXX", tmpdir);
if ((fd = mkstemp(tempname)) == -1 ||
@@ -135,40 +111,43 @@ collect(hp, printheaders)
puthead(hp, stdout, t);
fflush(stdout);
}
- if ((cp = value("escape")) != NULL)
- escape = *cp;
- else
- escape = ESCAPE;
- eofcount = 0;
- hadintr = 0;
- lastlong = 0;
- longline = 0;
+ if (getsub && gethfromtty(hp, GSUBJECT) == -1)
+ goto err;
- if (!sigsetjmp(colljmp, 1)) {
- if (getsub)
- gethfromtty(hp, GSUBJECT);
- } else {
- /*
- * Come here for printing the after-signal message.
- * Duplicate messages won't be printed because
- * the write is aborted if we get a SIGTTOU.
- */
+ if (0) {
cont:
- if (hadintr) {
+ /* Come here for printing the after-suspend message. */
+ if (isatty(0)) {
+ puts("(continue)");
fflush(stdout);
- fputs("\n(Interrupt -- one more to kill letter)\n",
- stderr);
- } else {
- if (isatty(0)) {
- puts("(continue)");
- fflush(stdout);
- }
}
}
for (;;) {
- colljmp_p = 1;
- c = readline(stdin, linebuf, LINESIZE);
- colljmp_p = 0;
+ c = readline(stdin, linebuf, LINESIZE, &sig);
+
+ /* Act on any signal caught during readline() ignoring 'c' */
+ switch (sig) {
+ case 0:
+ break;
+ case SIGINT:
+ if (collabort())
+ goto err;
+ continue;
+ case SIGHUP:
+ rewind(collf);
+ savedeadletter(collf);
+ /*
+ * Let's pretend nobody else wants to clean up,
+ * a true statement at this time.
+ */
+ exit(1);
+ default:
+ /* Stopped due to job control */
+ (void)kill(0, sig);
+ goto cont;
+ }
+
+ /* No signal, check for error */
if (c < 0) {
if (value("interactive") != NULL &&
value("ignoreeof") != NULL && ++eofcount < 25) {
@@ -236,8 +215,9 @@ cont:
* Act like an interrupt happened.
*/
hadintr++;
- collint(SIGINT);
- exit(1);
+ collabort();
+ fputs("Interrupt\n", stderr);
+ goto err;
case 'h':
/*
* Grab a bunch of headers.
@@ -304,7 +284,7 @@ cont:
fflush(stdout);
lc = 0;
cc = 0;
- while ((rc = readline(fbuf, linebuf, LINESIZE)) >= 0) {
+ while ((rc = readline(fbuf, linebuf, LINESIZE, NULL)) >= 0) {
if (rc != LINESIZE - 1)
lc++;
if ((t = putline(collf, linebuf,
@@ -389,10 +369,14 @@ cont:
if (value("interactive") != NULL) {
if (value("askcc") != NULL || value("askbcc") != NULL) {
- if (value("askcc") != NULL)
- gethfromtty(hp, GCC);
- if (value("askbcc") != NULL)
- gethfromtty(hp, GBCC);
+ if (value("askcc") != NULL) {
+ if (gethfromtty(hp, GCC) == -1)
+ goto err;
+ }
+ if (value("askbcc") != NULL) {
+ if (gethfromtty(hp, GBCC) == -1)
+ goto err;
+ }
} else {
puts("EOT");
(void)fflush(stdout);
@@ -408,16 +392,6 @@ out:
if (collf != NULL)
rewind(collf);
noreset--;
- (void)sigemptyset(&nset);
- (void)sigaddset(&nset, SIGINT);
- (void)sigaddset(&nset, SIGHUP);
- (void)sigprocmask(SIG_BLOCK, &nset, &oset);
- (void)signal(SIGINT, saveint);
- (void)signal(SIGHUP, savehup);
- (void)signal(SIGTSTP, savetstp);
- (void)signal(SIGTTOU, savettou);
- (void)signal(SIGTTIN, savettin);
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
return(collf);
}
@@ -477,15 +451,19 @@ mesedit(fp, c)
FILE *fp;
int c;
{
- sig_t sigint = signal(SIGINT, SIG_IGN);
- FILE *nf = run_editor(fp, (off_t)-1, c, 0);
+ FILE *nf;
+ struct sigaction oact;
+ sigset_t oset;
+ (void)ignoresig(SIGINT, &oact, &oset);
+ nf = run_editor(fp, (off_t)-1, c, 0);
if (nf != NULL) {
fseek(nf, 0L, 2);
collf = nf;
(void)Fclose(fp);
}
- (void)signal(SIGINT, sigint);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
}
/*
@@ -501,9 +479,11 @@ mespipe(fp, cmd)
{
FILE *nf;
int fd;
- sig_t sigint = signal(SIGINT, SIG_IGN);
char *shell, tempname[PATHSIZE];
+ struct sigaction oact;
+ sigset_t oset;
+ (void)ignoresig(SIGINT, &oact, &oset);
(void)snprintf(tempname, sizeof(tempname),
"%s/mail.ReXXXXXXXXXX", tmpdir);
if ((fd = mkstemp(tempname)) == -1 ||
@@ -534,7 +514,8 @@ mespipe(fp, cmd)
collf = nf;
(void)Fclose(fp);
out:
- (void)signal(SIGINT, sigint);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
}
/*
@@ -590,37 +571,11 @@ forward(ms, fp, fn, f)
}
/*
- * Print (continue) when continued after ^Z.
+ * User aborted during message composition.
+ * Save the partial message in ~/dead.letter.
*/
-/*ARGSUSED*/
-void
-collstop(s)
- int s;
-{
- sig_t old_action = signal(s, SIG_DFL);
- sigset_t nset;
-
- (void)sigemptyset(&nset);
- (void)sigaddset(&nset, s);
- (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
- (void)kill(0, s);
- (void)sigprocmask(SIG_BLOCK, &nset, NULL);
- (void)signal(s, old_action);
- if (colljmp_p) {
- colljmp_p = 0;
- hadintr = 0;
- siglongjmp(colljmp, 1);
- }
-}
-
-/*
- * On interrupt, come here to save the partial message in ~/dead.letter.
- * Then jump out of the collection loop.
- */
-/*ARGSUSED*/
-void
-collint(s)
- int s;
+int
+collabort()
{
/*
* the control flow is subtle, because we can be called from ~q.
@@ -630,29 +585,19 @@ collint(s)
puts("@");
fflush(stdout);
clearerr(stdin);
- return;
+ } else {
+ fflush(stdout);
+ fputs("\n(Interrupt -- one more to kill letter)\n",
+ stderr);
+ hadintr++;
}
- hadintr = 1;
- siglongjmp(colljmp, 1);
+ return(0);
}
+ fflush(stdout);
rewind(collf);
if (value("nosave") == NULL)
savedeadletter(collf);
- siglongjmp(collabort, 1);
-}
-
-/*ARGSUSED*/
-void
-collhup(s)
- int s;
-{
- rewind(collf);
- savedeadletter(collf);
- /*
- * Let's pretend nobody else wants to clean up,
- * a true statement at this time.
- */
- exit(1);
+ return(1);
}
void
@@ -677,19 +622,16 @@ savedeadletter(fp)
rewind(fp);
}
-void
+int
gethfromtty(hp, gflags)
struct header *hp;
int gflags;
{
- if (grabh(hp, gflags) == SIGINT) {
- fflush(stdout);
- fputs("\n(Interrupt -- one more to kill letter)\n",
- stderr);
- if (grabh(hp, gflags) == SIGINT) {
- hadintr++;
- collint(SIGINT);
- exit(1);
- }
+
+ hadintr = 0;
+ while (grabh(hp, gflags) != 0) {
+ if (collabort())
+ return(-1);
}
+ return(0);
}
diff --git a/usr.bin/mail/def.h b/usr.bin/mail/def.h
index 533a2932998..2403d47607d 100644
--- a/usr.bin/mail/def.h
+++ b/usr.bin/mail/def.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: def.h,v 1.7 2001/01/16 05:36:08 millert Exp $ */
+/* $OpenBSD: def.h,v 1.8 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: def.h,v 1.9 1996/12/28 07:11:00 tls Exp $ */
/*
* Copyright (c) 1980, 1993
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)def.h 8.4 (Berkeley) 4/20/95
- * $OpenBSD: def.h,v 1.7 2001/01/16 05:36:08 millert Exp $
+ * $OpenBSD: def.h,v 1.8 2001/11/20 20:50:00 millert Exp $
*/
/*
@@ -271,13 +271,6 @@ struct ignoretab {
#define CSEND 2 /* Execute in send mode only */
/*
- * Kludges to handle the change from setexit / reset to sigsetjmp / siglongjmp
- */
-
-#define setexit() sigsetjmp(srbuf, 1)
-#define reset(x) siglongjmp(srbuf, x)
-
-/*
* Truncate a file to the last character written. This is
* useful just before closing an old file that was opened
* for read/write.
diff --git a/usr.bin/mail/edit.c b/usr.bin/mail/edit.c
index 90cf18607fc..86cbda720fb 100644
--- a/usr.bin/mail/edit.c
+++ b/usr.bin/mail/edit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: edit.c,v 1.9 2001/01/19 04:11:28 millert Exp $ */
+/* $OpenBSD: edit.c,v 1.10 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: edit.c,v 1.5 1996/06/08 19:48:20 christos Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)edit.c 8.1 (Berkeley) 6/6/93";
#else
-static char rcsid[] = "$OpenBSD: edit.c,v 1.9 2001/01/19 04:11:28 millert Exp $";
+static char rcsid[] = "$OpenBSD: edit.c,v 1.10 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -88,6 +88,8 @@ edit1(msgvec, type)
{
int c, i;
FILE *fp;
+ struct sigaction oact;
+ sigset_t oset;
struct message *mp;
off_t size;
@@ -95,8 +97,6 @@ edit1(msgvec, type)
* Deal with each message to be edited . . .
*/
for (i = 0; msgvec[i] && i < msgCount; i++) {
- sig_t sigint;
-
if (i > 0) {
char buf[100];
char *p;
@@ -113,7 +113,7 @@ edit1(msgvec, type)
}
dot = mp = &message[msgvec[i] - 1];
touch(mp);
- sigint = signal(SIGINT, SIG_IGN);
+ (void)ignoresig(SIGINT, &oact, &oset);
fp = run_editor(setinput(mp), mp->m_size, type, readonly);
if (fp != NULL) {
(void)fseek(otf, 0L, 2);
@@ -134,7 +134,8 @@ edit1(msgvec, type)
warn("/tmp");
(void)Fclose(fp);
}
- (void)signal(SIGINT, sigint);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &oact, NULL);
}
return(0);
}
diff --git a/usr.bin/mail/extern.h b/usr.bin/mail/extern.h
index fd7ad6453c1..16024b82f3d 100644
--- a/usr.bin/mail/extern.h
+++ b/usr.bin/mail/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.17 2001/11/16 17:10:06 millert Exp $ */
+/* $OpenBSD: extern.h,v 1.18 2001/11/20 20:50:00 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.17 2001/11/16 17:10:06 millert Exp $
+ * $OpenBSD: extern.h,v 1.18 2001/11/20 20:50:00 millert Exp $
*/
struct name;
@@ -103,9 +103,7 @@ void clob1 __P((int));
int clobber __P((void *));
void close_all_files __P((void));
int cmatch __P((char *, char *));
-void collhup __P((int));
-void collint __P((int));
-void collstop __P((int));
+int collabort __P((void));
void commands __P((void));
int copycmd __P((void *));
int core __P((void *));
@@ -114,13 +112,14 @@ int delete __P((void *));
int delm __P((int []));
int deltype __P((void *));
void demail __P((void));
+void dointr __P((void));
int dosh __P((void *));
int dot_lock __P((const char *, int, FILE *, const char *));
void dot_unlock __P((const char *));
int echo __P((void *));
int edit1 __P((int *, int));
int editor __P((void *));
-void edstop __P((void));
+int edstop __P((void));
int elsecmd __P((void *));
int endifcmd __P((void *));
int evalcol __P((int));
@@ -131,6 +130,7 @@ int file __P((void *));
struct grouphead *
findgroup __P((char []));
void findmail __P((char *, char *, int));
+void fioint __P((int));
int first __P((int, int));
void fixhead __P((struct header *, struct name *));
void fmt __P((char *, struct name *, FILE *, int));
@@ -141,15 +141,14 @@ int from __P((void *));
off_t fsize __P((FILE *));
int getfold __P((char *, int));
int gethfield __P((FILE *, char [], int, char **));
-void gethfromtty __P((struct header *, int));
+int gethfromtty __P((struct header *, int));
int getmsglist __P((char *, int *, int));
int getrawlist __P((char [], char **, int));
int getuserid __P((char []));
int grabh __P((struct header *, int));
int group __P((void *));
-void hangup __P((int));
int hash __P((char *));
-void hdrstop __P((int));
+void hdrint __P((int));
int headers __P((void *));
int help __P((void *));
void holdsigs __P((void));
@@ -157,6 +156,7 @@ int ifcmd __P((void *));
int igfield __P((void *));
struct ignoretab;
int ignore1 __P((char *[], struct ignoretab *, char *));
+int ignoresig __P((int, struct sigaction *, sigset_t *));
int igshow __P((struct ignoretab *, char *));
void intr __P((int));
int inc __P((void *));
@@ -205,10 +205,10 @@ void printhead __P((int));
int puthead __P((struct header *, FILE *, int));
int putline __P((FILE *, char *, int));
int pversion __P((void *));
-void quit __P((void));
+int quit __P((void));
int quitcmd __P((void *));
int raise __P((int));
-int readline __P((FILE *, char *, int));
+int readline __P((FILE *, char *, int, int *));
void register_file __P((FILE *, int, int));
void regret __P((int));
void relsesigs __P((void));
diff --git a/usr.bin/mail/fio.c b/usr.bin/mail/fio.c
index 3589a49c3f9..3fef0ff1b8a 100644
--- a/usr.bin/mail/fio.c
+++ b/usr.bin/mail/fio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fio.c,v 1.18 2001/01/16 05:36:08 millert Exp $ */
+/* $OpenBSD: fio.c,v 1.19 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: fio.c,v 1.8 1997/07/07 22:57:55 phil Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)fio.c 8.2 (Berkeley) 4/20/95";
#else
-static char rcsid[] = "$OpenBSD: fio.c,v 1.18 2001/01/16 05:36:08 millert Exp $";
+static char rcsid[] = "$OpenBSD: fio.c,v 1.19 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -57,6 +57,8 @@ static char rcsid[] = "$OpenBSD: fio.c,v 1.18 2001/01/16 05:36:08 millert Exp $"
* File I/O.
*/
+static volatile sig_atomic_t fiosignal;
+
/*
* Wrapper for read() to catch EINTR.
*/
@@ -206,22 +208,67 @@ putline(obuf, linebuf, outlf)
* include the newline (or carriage return) at the end.
*/
int
-readline(ibuf, linebuf, linesize)
+readline(ibuf, linebuf, linesize, signo)
FILE *ibuf;
char *linebuf;
int linesize;
+ int *signo;
{
+ struct sigaction act;
+ struct sigaction savetstp;
+ struct sigaction savettou;
+ struct sigaction savettin;
+ struct sigaction saveint;
+ struct sigaction savehup;
+ sigset_t oset;
int n;
+ /*
+ * Setup signal handlers if the caller asked us to catch signals.
+ * Note that we do not restart system calls since we need the
+ * read to be interuptible.
+ */
+ if (signo) {
+ fiosignal = 0;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = fioint;
+ if (sigaction(SIGINT, NULL, &saveint) == 0 &&
+ saveint.sa_handler != SIG_IGN) {
+ (void)sigaction(SIGINT, &act, &saveint);
+ (void)sigprocmask(SIG_UNBLOCK, &intset, &oset);
+ }
+ if (sigaction(SIGHUP, NULL, &savehup) == 0 &&
+ savehup.sa_handler != SIG_IGN)
+ (void)sigaction(SIGHUP, &act, &savehup);
+ (void)sigaction(SIGTSTP, &act, &savetstp);
+ (void)sigaction(SIGTTOU, &act, &savettou);
+ (void)sigaction(SIGTTIN, &act, &savettin);
+ }
+
clearerr(ibuf);
- if (fgets(linebuf, linesize, ibuf) == NULL)
- return(-1);
+ if (fgets(linebuf, linesize, ibuf) == NULL) {
+ if (ferror(ibuf))
+ clearerr(ibuf);
+ n = -1;
+ } else {
+ n = strlen(linebuf);
+ if (n > 0 && linebuf[n - 1] == '\n')
+ linebuf[--n] = '\0';
+ if (n > 0 && linebuf[n - 1] == '\r')
+ linebuf[--n] = '\0';
+ }
+
+ if (signo) {
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGINT, &saveint, NULL);
+ (void)sigaction(SIGHUP, &savehup, NULL);
+ (void)sigaction(SIGTSTP, &savetstp, NULL);
+ (void)sigaction(SIGTTOU, &savettou, NULL);
+ (void)sigaction(SIGTTIN, &savettin, NULL);
+ *signo = fiosignal;
+ }
- n = strlen(linebuf);
- if (n > 0 && linebuf[n - 1] == '\n')
- linebuf[--n] = '\0';
- if (n > 0 && linebuf[n - 1] == '\r')
- linebuf[--n] = '\0';
return(n);
}
@@ -340,6 +387,34 @@ relsesigs()
}
/*
+ * Unblock and ignore a signal
+ */
+int
+ignoresig(sig, oact, oset)
+ int sig;
+ struct sigaction *oact;
+ sigset_t *oset;
+{
+ struct sigaction act;
+ sigset_t nset;
+ int error;
+
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = SIG_IGN;
+ error = sigaction(sig, &act, oact);
+
+ if (error == 0) {
+ sigemptyset(&nset);
+ sigaddset(&nset, sig);
+ (void)sigprocmask(SIG_UNBLOCK, &nset, oset);
+ } else if (oset != NULL)
+ (void)sigprocmask(SIG_BLOCK, NULL, oset);
+
+ return(error);
+}
+
+/*
* Determine the size of the file possessed by
* the passed buffer.
*/
@@ -493,3 +568,15 @@ getdeadletter()
}
return(cp);
}
+
+/*
+ * Signal handler used by readline() to catch SIGINT, SIGHUP, SIGTSTP,
+ * SIGTTOU, SIGTTIN.
+ */
+void
+fioint(s)
+ int s;
+{
+
+ fiosignal = s;
+}
diff --git a/usr.bin/mail/glob.h b/usr.bin/mail/glob.h
index 4a43011bc1a..d82df7d78a0 100644
--- a/usr.bin/mail/glob.h
+++ b/usr.bin/mail/glob.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: glob.h,v 1.4 1998/09/27 21:16:42 millert Exp $ */
+/* $OpenBSD: glob.h,v 1.5 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: glob.h,v 1.4 1996/06/08 19:48:25 christos Exp $ */
/*
@@ -84,10 +84,7 @@ int screenheight; /* Screen height, or best guess,
for "header" command */
int realscreenheight; /* the real screen height */
int uflag; /* Are we in -u mode? */
-
-#include <setjmp.h>
-
-sigjmp_buf srbuf;
+sigset_t intset; /* Signal set that is just SIGINT */
/*
diff --git a/usr.bin/mail/lex.c b/usr.bin/mail/lex.c
index ff068f48529..a17a2d89b4a 100644
--- a/usr.bin/mail/lex.c
+++ b/usr.bin/mail/lex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lex.c,v 1.24 2001/11/17 19:10:25 deraadt Exp $ */
+/* $OpenBSD: lex.c,v 1.25 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: lex.c,v 1.10 1997/05/17 19:55:13 pk Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)lex.c 8.2 (Berkeley) 4/20/95";
#else
-static char rcsid[] = "$OpenBSD: lex.c,v 1.24 2001/11/17 19:10:25 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: lex.c,v 1.25 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -209,7 +209,7 @@ incfile()
int *msgvec;
-int reset_on_stop; /* do a reset() if stopped */
+int reset_on_stop; /* reset prompt if stopped */
/*
* Interpret user commands one by one. If standard input is not a tty,
@@ -218,20 +218,11 @@ int reset_on_stop; /* do a reset() if stopped */
void
commands()
{
- int n;
- volatile int eofloop = 0;
+ int n, sig, *sigp;
+ int eofloop = 0;
char linebuf[LINESIZE];
- if (!sourcing) {
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void)signal(SIGINT, intr);
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
- (void)signal(SIGHUP, hangup);
- (void)signal(SIGTSTP, stop);
- (void)signal(SIGTTOU, stop);
- (void)signal(SIGTTIN, stop);
- }
- setexit();
+ prompt:
for (;;) {
/*
* Print the prompt, if needed. Clear out
@@ -250,8 +241,24 @@ commands()
* and handle end of file specially.
*/
n = 0;
+ sig = 0;
+ sigp = sourcing ? NULL : &sig;
for (;;) {
- if (readline(input, &linebuf[n], LINESIZE - n) < 0) {
+ if (readline(input, &linebuf[n], LINESIZE - n, sigp) < 0) {
+ if (sig) {
+ if (sig == SIGINT)
+ dointr();
+ else if (sig == SIGHUP)
+ /* nothing to do? */
+ exit(1);
+ else {
+ /* Stopped by job control */
+ (void)kill(0, sig);
+ if (reset_on_stop)
+ reset_on_stop = 0;
+ }
+ goto prompt;
+ }
if (n == 0)
n = -1;
break;
@@ -597,10 +604,8 @@ isprefix(as1, as2)
int inithdr; /* am printing startup headers */
-/*ARGSUSED*/
void
-intr(s)
- int s;
+dointr()
{
noreset = 0;
@@ -617,42 +622,6 @@ intr(s)
image = -1;
}
fputs("Interrupt\n", stderr);
- reset(0);
-}
-
-/*
- * When we wake up after ^Z, reprint the prompt.
- */
-void
-stop(s)
- int s;
-{
- sig_t old_action = signal(s, SIG_DFL);
- sigset_t nset;
-
- (void)sigemptyset(&nset);
- (void)sigaddset(&nset, s);
- (void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
- (void)kill(0, s);
- (void)sigprocmask(SIG_BLOCK, &nset, NULL);
- (void)signal(s, old_action);
- if (reset_on_stop) {
- reset_on_stop = 0;
- reset(0);
- }
-}
-
-/*
- * Branch here on hangup signal and simulate "exit".
- */
-/*ARGSUSED*/
-void
-hangup(s)
- int s;
-{
-
- /* nothing to do? */
- exit(1);
}
/*
diff --git a/usr.bin/mail/main.c b/usr.bin/mail/main.c
index e8ffac609eb..e08b15135fd 100644
--- a/usr.bin/mail/main.c
+++ b/usr.bin/mail/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.14 2001/10/11 20:59:46 millert Exp $ */
+/* $OpenBSD: main.c,v 1.15 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: main.c,v 1.7 1997/05/13 06:15:57 mikel Exp $ */
/*
@@ -44,7 +44,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 4/20/95";
#else
-static char rcsid[] = "$OpenBSD: main.c,v 1.14 2001/10/11 20:59:46 millert Exp $";
+static char rcsid[] = "$OpenBSD: main.c,v 1.15 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -54,6 +54,7 @@ static char rcsid[] = "$OpenBSD: main.c,v 1.14 2001/10/11 20:59:46 millert Exp $
#include "extern.h"
int main __P((int, char **));
+__dead void usage __P((void));
/*
* Mail -- a mail program
@@ -61,8 +62,6 @@ int main __P((int, char **));
* Startup -- interface with user.
*/
-sigjmp_buf hdrjmp;
-
int
main(argc, argv)
int argc;
@@ -73,8 +72,8 @@ main(argc, argv)
char *subject;
char *ef;
char nosrc = 0;
- sig_t prevint;
char *rc;
+ extern char *version;
/*
* Set up a reasonable environment.
@@ -82,6 +81,7 @@ main(argc, argv)
* start the SIGCHLD catcher, and so forth.
*/
(void)signal(SIGCHLD, sigchild);
+ (void)signal(SIGPIPE, SIG_IGN);
if (isatty(0))
assign("interactive", "");
image = -1;
@@ -188,13 +188,9 @@ main(argc, argv)
*/
bcc = cat(bcc, nalloc(optarg, GBCC));
break;
- case '?':
- fprintf(stderr, "\
-Usage: %s [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
- [- sendmail-options ...]\n\
- %s [-iInNv] -f [name]\n\
- %s [-iInNv] [-u user]\n", __progname, __progname, __progname);
- exit(1);
+ default:
+ usage();
+ /*NOTREACHED*/
}
}
for (i = optind; (argv[i]) && (*argv[i] != '-'); i++)
@@ -208,6 +204,15 @@ Usage: %s [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
errx(1, "You must specify direct recipients with -s, -c, or -b");
if (ef != NULL && to != NIL)
errx(1, "Cannot give -f and people to send to");
+ /*
+ * Block SIGINT except where we install an explicit handler for it.
+ */
+ sigemptyset(&intset);
+ sigaddset(&intset, SIGINT);
+ (void)sigprocmask(SIG_BLOCK, &intset, NULL);
+ /*
+ * Initialization.
+ */
tinit();
setscreensize();
input = stdin;
@@ -238,40 +243,21 @@ Usage: %s [-iInv] [-s subject] [-c cc-addr] [-b bcc-addr] to-addr ...\n\
ef = "%";
if (setfile(ef) < 0)
exit(1); /* error already reported */
- if (sigsetjmp(hdrjmp, 1) == 0) {
- extern char *version;
- if ((prevint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
- (void)signal(SIGINT, hdrstop);
- if (value("quiet") == NULL)
- (void)printf("Mail version %s. Type ? for help.\n",
- version);
- announce();
- (void)fflush(stdout);
- (void)signal(SIGINT, prevint);
- }
+ if (value("quiet") == NULL)
+ (void)printf("Mail version %s. Type ? for help.\n",
+ version);
+ announce();
+ (void)fflush(stdout);
commands();
- (void)signal(SIGHUP, SIG_IGN);
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGQUIT, SIG_IGN);
+ (void)ignoresig(SIGHUP, NULL, NULL);
+ (void)ignoresig(SIGINT, NULL, NULL);
+ (void)ignoresig(SIGQUIT, NULL, NULL);
quit();
exit(0);
}
/*
- * Interrupt printing of the headers.
- */
-void
-hdrstop(signo)
- int signo;
-{
-
- fflush(stdout);
- fputs("\nInterrupt\n", stderr);
- siglongjmp(hdrjmp, 1);
-}
-
-/*
* Compute what the screen size for printing headers should be.
* We use the following algorithm for the height:
* If baud rate < 1200, use 9
@@ -305,3 +291,16 @@ setscreensize()
if ((screenwidth = ws.ws_col) == 0)
screenwidth = 80;
}
+
+__dead void
+usage()
+{
+
+ fprintf(stderr, "usage: %s [-iInv] [-s subject] [-c cc-addr] "
+ "[-b bcc-addr] to-addr ...\n", __progname);
+ fprintf(stderr, " %*s [- sendmail-options ...]\n",
+ (int)strlen(__progname), "");
+ fprintf(stderr, " %s [-iInNv] -f [name]\n", __progname);
+ fprintf(stderr, " %s [-iInNv] [-u user]\n", __progname);
+ exit(1);
+}
diff --git a/usr.bin/mail/quit.c b/usr.bin/mail/quit.c
index 1fe4b088a27..2f2ba2987e6 100644
--- a/usr.bin/mail/quit.c
+++ b/usr.bin/mail/quit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: quit.c,v 1.14 2001/01/16 05:36:09 millert Exp $ */
+/* $OpenBSD: quit.c,v 1.15 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: quit.c,v 1.6 1996/12/28 07:11:07 tls Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)quit.c 8.2 (Berkeley) 4/28/95";
#else
-static char rcsid[] = "$OpenBSD: quit.c,v 1.14 2001/01/16 05:36:09 millert Exp $";
+static char rcsid[] = "$OpenBSD: quit.c,v 1.15 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -73,7 +73,7 @@ quitcmd(v)
* Save all untouched messages back in the system mailbox.
* Remove the system mailbox, if none saved there.
*/
-void
+int
quit()
{
int mcount, p, modify, autohold, anystat, holdbit, nohold;
@@ -88,15 +88,13 @@ quit()
* so just return quickly.
*/
if (readonly)
- return;
+ return(0);
/*
* If editing (not reading system mail box), then do the work
* in edstop()
*/
- if (edit) {
- edstop();
- return;
- }
+ if (edit)
+ return(edstop());
/*
* See if there any messages to save in mbox. If no, we
@@ -114,11 +112,11 @@ quit()
if (flock(fileno(fbuf), LOCK_EX) == -1) {
warn("Unable to lock mailbox");
(void)Fclose(fbuf);
- return;
+ return(-1);
}
if (!spool_lock()) {
(void)Fclose(fbuf);
- return; /* lockspool printed error for us */
+ return(-1); /* lockspool printed error for us */
}
rbuf = NULL;
if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
@@ -195,14 +193,14 @@ quit()
p, p == 1 ? "" : "s", mailname);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(0);
}
if (c == 0) {
if (p != 0) {
writeback(rbuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(0);
}
goto cream;
}
@@ -224,7 +222,7 @@ quit()
warn("%s", tempname);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
if ((ibuf = Fopen(tempname, "r")) == NULL) {
warn("%s", tempname);
@@ -232,7 +230,7 @@ quit()
(void)Fclose(obuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
(void)rm(tempname);
if ((abuf = Fopen(mbox, "r")) != NULL) {
@@ -246,7 +244,7 @@ quit()
(void)Fclose(obuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
(void)Fclose(obuf);
(void)close(creat(mbox, 0600));
@@ -255,15 +253,14 @@ quit()
(void)Fclose(ibuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
- }
- else {
+ } else {
if ((obuf = Fopen(mbox, "a")) == NULL) {
warn("%s", mbox);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
fchmod(fileno(obuf), 0600);
}
@@ -275,7 +272,7 @@ quit()
(void)Fclose(obuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
/*
@@ -302,7 +299,7 @@ quit()
(void)Fclose(obuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(-1);
}
(void)Fclose(obuf);
if (mcount == 1)
@@ -319,7 +316,7 @@ quit()
writeback(rbuf);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(0);
}
/*
@@ -340,12 +337,12 @@ cream:
alter(mailname);
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(0);
}
demail();
(void)Fclose(fbuf);
spool_unlock();
- return;
+ return(0);;
newmail:
puts("Thou hast new mail.");
@@ -353,6 +350,7 @@ newmail:
(void)Fclose(fbuf);
spool_unlock();
}
+ return(0);
}
/*
@@ -415,7 +413,7 @@ writeback(res)
* Terminate an editing session by attempting to write out the user's
* file from the temporary. Save any new stuff appended to the file.
*/
-void
+int
edstop()
{
int gotcha, c;
@@ -425,7 +423,7 @@ edstop()
char tempname[PATHSIZE];
if (readonly)
- return;
+ return(0);
holdsigs();
if (Tflag != NULL) {
if ((readstat = Fopen(Tflag, "w")) == NULL)
@@ -459,14 +457,14 @@ edstop()
(obuf = Fdopen(fd, "w")) == NULL) {
warn("%s", tempname);
relsesigs();
- reset(0);
+ return(-1);
}
if ((ibuf = Fopen(mailname, "r")) == NULL) {
warn("%s", mailname);
(void)Fclose(obuf);
(void)rm(tempname);
relsesigs();
- reset(0);
+ return(-1);
}
fseek(ibuf, (long)mailsize, 0);
while ((c = getc(ibuf)) != EOF)
@@ -477,7 +475,7 @@ edstop()
warn("%s", tempname);
(void)rm(tempname);
relsesigs();
- reset(0);
+ return(-1);
}
(void)rm(tempname);
}
@@ -486,7 +484,7 @@ edstop()
if ((obuf = Fopen(mailname, "r+")) == NULL) {
warn("%s", mailname);
relsesigs();
- reset(0);
+ return(-1);
}
trunc(obuf);
c = 0;
@@ -497,7 +495,7 @@ edstop()
if (sendmessage(mp, obuf, NULL, NULL) < 0) {
warn("%s", mailname);
relsesigs();
- reset(0);
+ return(-1);
}
}
gotcha = (c == 0 && ibuf == NULL);
@@ -510,7 +508,7 @@ edstop()
if (ferror(obuf)) {
warn("%s", mailname);
relsesigs();
- reset(0);
+ return(-1);
}
(void)Fclose(obuf);
if (gotcha) {
@@ -522,4 +520,5 @@ edstop()
done:
relsesigs();
+ return(0);
}
diff --git a/usr.bin/mail/tty.c b/usr.bin/mail/tty.c
index 0bfb6006ebc..0acd5bf1861 100644
--- a/usr.bin/mail/tty.c
+++ b/usr.bin/mail/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.12 2001/06/23 23:04:23 millert Exp $ */
+/* $OpenBSD: tty.c,v 1.13 2001/11/20 20:50:00 millert Exp $ */
/* $NetBSD: tty.c,v 1.7 1997/07/09 05:25:46 mikel Exp $ */
/*
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)tty.c 8.2 (Berkeley) 4/20/95";
#else
-static char rcsid[] = "$OpenBSD: tty.c,v 1.12 2001/06/23 23:04:23 millert Exp $";
+static char rcsid[] = "$OpenBSD: tty.c,v 1.13 2001/11/20 20:50:00 millert Exp $";
#endif
#endif /* not lint */
@@ -51,14 +51,14 @@ static char rcsid[] = "$OpenBSD: tty.c,v 1.12 2001/06/23 23:04:23 millert Exp $"
#include "rcv.h"
#include "extern.h"
#include <sys/ioctl.h>
+#include <errno.h>
static cc_t c_erase; /* Current erase char */
static cc_t c_kill; /* Current kill char */
-static sigjmp_buf rewrite; /* Place to go when continued */
-static sigjmp_buf intjmp; /* Place to go when interrupted */
#ifndef TIOCSTI
static int ttyset; /* We must now do erase/kill */
#endif
+static volatile sig_atomic_t ttysignal; /* Interrupted by a signal? */
/*
* Read all relevant header fields.
@@ -70,24 +70,28 @@ grabh(hp, gflags)
int gflags;
{
struct termios ttybuf;
- volatile sig_t saveint;
#ifndef TIOCSTI
- sig_t savequit;
+ struct sigaction savequit;
#else
# ifdef TIOCEXT
- volatile int extproc;
+ int extproc;
int flag;
# endif /* TIOCEXT */
#endif
- sig_t savetstp;
- sig_t savettou;
- sig_t savettin;
- volatile int errs = 0;
+ struct sigaction savetstp;
+ struct sigaction savettou;
+ struct sigaction savettin;
+ struct sigaction act;
+ char *s;
+ int error;
- savetstp = signal(SIGTSTP, SIG_DFL);
- savettou = signal(SIGTTOU, SIG_DFL);
- savettin = signal(SIGTTIN, SIG_DFL);
- errs = 0;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = SIG_DFL;
+ (void)sigaction(SIGTSTP, &act, &savetstp);
+ (void)sigaction(SIGTTOU, &act, &savettou);
+ (void)sigaction(SIGTTIN, &act, &savettin);
+ error = 1;
#ifndef TIOCSTI
ttyset = 0;
#endif
@@ -100,10 +104,10 @@ grabh(hp, gflags)
#ifndef TIOCSTI
ttybuf.c_cc[VERASE] = 0;
ttybuf.c_cc[VKILL] = 0;
- if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)
- (void)signal(SIGINT, SIG_DFL);
- if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
- (void)signal(SIGQUIT, SIG_DFL);
+ act.sa_handler = SIG_IGN;
+ if (sigaction(SIGQUIT, &act, &savequit) == 0 &&
+ savequit.sa_handler == SIG_DFL)
+ (void)sigaction(SIGQUIT, &savequit, NULL);
#else
# ifdef TIOCEXT
extproc = ((ttybuf.c_lflag & EXTPROC) ? 1 : 0);
@@ -113,53 +117,58 @@ grabh(hp, gflags)
warn("TIOCEXT: off");
}
# endif /* TIOCEXT */
- if (sigsetjmp(intjmp, 1)) {
- errs = SIGINT;
- goto out;
- }
- saveint = signal(SIGINT, ttyint);
#endif
if (gflags & GTO) {
#ifndef TIOCSTI
if (!ttyset && hp->h_to != NIL)
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
- hp->h_to =
- extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
+ s = readtty("To: ", detract(hp->h_to, 0));
+ if (s == NULL)
+ goto out;
+ hp->h_to = extract(s, GTO);
}
if (gflags & GSUBJECT) {
#ifndef TIOCSTI
if (!ttyset && hp->h_subject != NULL)
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
- hp->h_subject = readtty("Subject: ", hp->h_subject);
+ s = readtty("Subject: ", hp->h_subject);
+ if (s == NULL)
+ goto out;
+ hp->h_subject = s;
}
if (gflags & GCC) {
#ifndef TIOCSTI
if (!ttyset && hp->h_cc != NIL)
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
- hp->h_cc =
- extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
+ s = readtty("Cc: ", detract(hp->h_cc, 0));
+ if (s == NULL)
+ goto out;
+ hp->h_cc = extract(s, GCC);
}
if (gflags & GBCC) {
#ifndef TIOCSTI
if (!ttyset && hp->h_bcc != NIL)
ttyset++, tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
#endif
- hp->h_bcc =
- extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
+ s = readtty("Bcc: ", detract(hp->h_bcc, 0));
+ if (s == NULL)
+ goto out;
+ hp->h_bcc = extract(s, GBCC);
}
+ error = 0;
out:
- (void)signal(SIGTSTP, savetstp);
- (void)signal(SIGTTOU, savettou);
- (void)signal(SIGTTIN, savettin);
+ (void)sigaction(SIGTSTP, &savetstp, NULL);
+ (void)sigaction(SIGTTOU, &savettou, NULL);
+ (void)sigaction(SIGTTIN, &savettin, NULL);
#ifndef TIOCSTI
ttybuf.c_cc[VERASE] = c_erase;
ttybuf.c_cc[VKILL] = c_kill;
if (ttyset)
tcsetattr(fileno(stdin), TCSADRAIN, &ttybuf);
- (void)signal(SIGQUIT, savequit);
+ (void)sigaction(SIGQUIT, &savequit, NULL);
#else
# ifdef TIOCEXT
if (extproc) {
@@ -169,8 +178,7 @@ out:
}
# endif /* TIOCEXT */
#endif
- (void)signal(SIGINT, saveint);
- return(errs);
+ return(error);
}
/*
@@ -184,9 +192,11 @@ char *
readtty(pr, src)
char pr[], src[];
{
+ struct sigaction act, oact;
+ sigset_t oset;
char ch, canonb[BUFSIZ];
- volatile int c;
- char *cp, * volatile cp2;
+ char *cp, *cp2;
+ int c;
fputs(pr, stdout);
fflush(stdout);
@@ -219,26 +229,50 @@ readtty(pr, src)
while (cp2 < canonb + BUFSIZ)
*cp2++ = 0;
cp2 = cp;
- if (sigsetjmp(rewrite, 1))
- goto redo;
- (void)signal(SIGTSTP, ttystop);
- (void)signal(SIGTTOU, ttystop);
- (void)signal(SIGTTIN, ttystop);
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0; /* Note: will not restart syscalls */
+ act.sa_handler = ttyint;
+ (void)sigaction(SIGINT, &act, &oact);
+ act.sa_handler = ttystop;
+ (void)sigaction(SIGTSTP, &act, NULL);
+ (void)sigaction(SIGTTOU, &act, NULL);
+ (void)sigaction(SIGTTIN, &act, NULL);
+ (void)sigprocmask(SIG_UNBLOCK, &intset, &oset);
clearerr(stdin);
while (cp2 < canonb + BUFSIZ) {
c = getc(stdin);
+ switch (ttysignal) {
+ case SIGINT:
+ ttysignal = 0;
+ cp2 = NULL;
+ c = EOF;
+ /* FALLTHROUGH */
+ case 0:
+ break;
+ default:
+ ttysignal = 0;
+ goto redo;
+ }
if (c == EOF || c == '\n')
break;
*cp2++ = c;
}
- *cp2 = 0;
- (void)signal(SIGTSTP, SIG_DFL);
- (void)signal(SIGTTOU, SIG_DFL);
- (void)signal(SIGTTIN, SIG_DFL);
+ act.sa_handler = SIG_DFL;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigaction(SIGTSTP, &act, NULL);
+ (void)sigaction(SIGTTOU, &act, NULL);
+ (void)sigaction(SIGTTIN, &act, NULL);
+ (void)sigaction(SIGTTIN, &oact, NULL);
+ if (cp2 == NULL)
+ return(NULL); /* user hit ^C */
+ *cp2 = '\0';
if (c == EOF && ferror(stdin)) {
redo:
cp = strlen(canonb) > 0 ? canonb : NULL;
clearerr(stdin);
+ /* XXX - make iterative, not recursive */
return(readtty(pr, cp));
}
#ifndef TIOCSTI
@@ -274,7 +308,7 @@ redo:
*cp2 = '\0';
#endif
if (equal("", canonb))
- return(NULL);
+ return("");
return(savestr(canonb));
}
@@ -285,16 +319,27 @@ void
ttystop(s)
int s;
{
- sig_t old_action = signal(s, SIG_DFL);
+ struct sigaction act, oact;
sigset_t nset;
+ int save_errno;
+ /*
+ * Save old handler and set to default.
+ * Unblock receipt of 's' and then resend it.
+ */
+ save_errno = errno;
+ (void)sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = SIG_DFL;
+ (void)sigaction(s, &act, &oact);
(void)sigemptyset(&nset);
(void)sigaddset(&nset, s);
(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
(void)kill(0, s);
(void)sigprocmask(SIG_BLOCK, &nset, NULL);
- (void)signal(s, old_action);
- siglongjmp(rewrite, 1);
+ (void)sigaction(s, &oact, NULL);
+ ttysignal = s;
+ errno = save_errno;
}
/*ARGSUSED*/
@@ -302,5 +347,6 @@ void
ttyint(s)
int s;
{
- siglongjmp(intjmp, 1);
+
+ ttysignal = s;
}