PR/56254: RVP: Don't call non-async-signal-safe functions from signal handlers.
Establish a non-restart signal handler to avoid blocking in long I/Os.
This commit is contained in:
parent
ab67b1ab7c
commit
c3c5452ebd
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $ */
|
/* $NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1980, 1992, 1993
|
* Copyright (c) 1980, 1992, 1993
|
||||||
|
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1992, 1993\
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93";
|
static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93";
|
||||||
#endif
|
#endif
|
||||||
__RCSID("$NetBSD: script.c,v 1.30 2022/01/20 19:49:51 christos Exp $");
|
__RCSID("$NetBSD: script.c,v 1.31 2022/02/11 21:15:25 christos Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -81,6 +81,8 @@ static int usesleep, rawout;
|
||||||
static int quiet, flush;
|
static int quiet, flush;
|
||||||
static const char *fname;
|
static const char *fname;
|
||||||
|
|
||||||
|
static volatile sig_atomic_t die = 0; /* exit if 1 */
|
||||||
|
static int cstat = EXIT_SUCCESS; /* cmd. exit status */
|
||||||
static int eflag;
|
static int eflag;
|
||||||
static int isterm;
|
static int isterm;
|
||||||
static struct termios tt;
|
static struct termios tt;
|
||||||
|
@ -88,6 +90,7 @@ static struct termios tt;
|
||||||
__dead static void done(int);
|
__dead static void done(int);
|
||||||
__dead static void doshell(const char *);
|
__dead static void doshell(const char *);
|
||||||
__dead static void fail(void);
|
__dead static void fail(void);
|
||||||
|
static sig_t xsignal(int, sig_t);
|
||||||
static void dooutput(void);
|
static void dooutput(void);
|
||||||
static void finish(int);
|
static void finish(int);
|
||||||
static void scriptflush(int);
|
static void scriptflush(int);
|
||||||
|
@ -182,7 +185,7 @@ main(int argc, char *argv[])
|
||||||
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
|
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)signal(SIGCHLD, finish);
|
(void)xsignal(SIGCHLD, finish);
|
||||||
child = fork();
|
child = fork();
|
||||||
if (child == -1) {
|
if (child == -1) {
|
||||||
warn("fork");
|
warn("fork");
|
||||||
|
@ -202,35 +205,49 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (!rawout)
|
if (!rawout)
|
||||||
(void)fclose(fscript);
|
(void)fclose(fscript);
|
||||||
while ((scc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) {
|
while (!die && (scc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) {
|
||||||
cc = (size_t)scc;
|
cc = (size_t)scc;
|
||||||
if (rawout)
|
if (rawout)
|
||||||
record(fscript, ibuf, cc, 'i');
|
record(fscript, ibuf, cc, 'i');
|
||||||
(void)write(master, ibuf, cc);
|
(void)write(master, ibuf, cc);
|
||||||
}
|
}
|
||||||
finish(-1);
|
done(cstat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wrapper around sigaction() because we want POSIX semantics:
|
||||||
|
* no auto-restarting of interrupted slow syscalls.
|
||||||
|
*/
|
||||||
|
static sig_t
|
||||||
|
xsignal(int signo, sig_t handler)
|
||||||
|
{
|
||||||
|
struct sigaction sa, osa;
|
||||||
|
|
||||||
|
sa.sa_handler = handler;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
if (sigaction(signo, &sa, &osa) == -1)
|
||||||
|
return SIG_ERR;
|
||||||
|
return osa.sa_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
finish(int signo)
|
finish(int signo)
|
||||||
{
|
{
|
||||||
int die, pid, status, cstat;
|
int pid, status;
|
||||||
|
|
||||||
die = 0;
|
|
||||||
while ((pid = wait(&status)) > 0)
|
while ((pid = wait(&status)) > 0)
|
||||||
if (pid == child) {
|
if (pid == child) {
|
||||||
cstat = status;
|
cstat = status;
|
||||||
die = 1;
|
die = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!die)
|
|
||||||
return;
|
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
done(EXIT_SUCCESS);
|
cstat = EXIT_SUCCESS;
|
||||||
else if (WIFEXITED(cstat))
|
else if (WIFEXITED(cstat))
|
||||||
done(WEXITSTATUS(cstat));
|
cstat = WEXITSTATUS(cstat);
|
||||||
else
|
else
|
||||||
done(128 + WTERMSIG(cstat));
|
cstat = 128 + WTERMSIG(cstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -268,7 +285,7 @@ dooutput(void)
|
||||||
if (flush)
|
if (flush)
|
||||||
(void)fflush(fscript);
|
(void)fflush(fscript);
|
||||||
}
|
}
|
||||||
finish(-1);
|
done(cstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue