mirror of
git://git.suckless.org/st
synced 2026-07-06 08:24:47 +01:00
fix async-unsafe error paths in sigchld()
die() calls vfprintf(3) and exit(3), which are not async-signal-safe. If SIGCHLD is handled while exiting, this can make st hang or crash. Commit d6ea0a1 replaced exit(3) by _exit(2) in sigchld() but the error paths still call die(). Fix that by using _exit(2) there as well.
This commit is contained in:
parent
688f70add0
commit
04ce0d643e
21
st.c
21
st.c
@ -712,19 +712,24 @@ execsh(char *cmd, char **args)
|
|||||||
void
|
void
|
||||||
sigchld(int a)
|
sigchld(int a)
|
||||||
{
|
{
|
||||||
int stat;
|
int stat, olderrno;
|
||||||
pid_t p;
|
pid_t p;
|
||||||
|
|
||||||
if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
|
olderrno = errno;
|
||||||
die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
|
do {
|
||||||
|
p = waitpid(pid, &stat, WNOHANG);
|
||||||
|
} while (p < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (pid != p)
|
if (p < 0)
|
||||||
|
_exit(1);
|
||||||
|
|
||||||
|
if (pid != p) {
|
||||||
|
errno = olderrno;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (WIFEXITED(stat) && WEXITSTATUS(stat))
|
if ((WIFEXITED(stat) && WEXITSTATUS(stat)) || WIFSIGNALED(stat))
|
||||||
die("child exited with status %d\n", WEXITSTATUS(stat));
|
_exit(1);
|
||||||
else if (WIFSIGNALED(stat))
|
|
||||||
die("child terminated due to signal %d\n", WTERMSIG(stat));
|
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user