Skip to content

Commit

Permalink
Fix a race in echo-signal
Browse files Browse the repository at this point in the history
Sadly a kind of mistake of which I'm well aware these days;
previously, you can imagine that we pause, some other signal gets
delivered, then, after we test sig != got but before we re-invoke
pause, our desired signal arrives.  Then, we hang in pause until
another signal arrives (an arbitrarily long time).

Also, might as well write our message without using buffered IO, to be
safe.
  • Loading branch information
tokenrove committed Nov 27, 2023
1 parent 05f5bb0 commit ee9bd1d
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions helpers/echo-signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ exec ${CC:-cc} ${CFLAGS:--Wall -Wextra -g} $0 -o $1
#include <string.h>
#include <unistd.h>

static sig_atomic_t got;

static int int_of_signal_name(char *name)
{
if (!strcmp(name, "INT")) return SIGINT;
Expand All @@ -23,16 +21,18 @@ static int int_of_signal_name(char *name)
abort();
}

static void handler(int n) { got = n; }

int main(int argc, char **argv)
{
struct sigaction action = { .sa_handler = handler };
if (2 != argc) abort();
int sig = int_of_signal_name(argv[1]);
sigaction(sig, &action, NULL);
puts("ready");
do { pause(); } while (sig != got);

sigset_t set, prev;
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_BLOCK, &set, &prev);
write(1, "ready\n", 6);
int got;
do { sigwait(&set, &got); } while (sig != got);
puts(argv[1]);
return 0;
}

0 comments on commit ee9bd1d

Please sign in to comment.