Skip to content

Commit

Permalink
openrc-shutdown: broadcast: simplify non-blocking logic
Browse files Browse the repository at this point in the history
Get rid of the setjmp/longjmp and just handle EINTR. This avoids messing
with the stack and simplifies program flow.

Bug: https://bugs.gentoo.org/923326
Signed-off-by: Mike Gilbert <[email protected]>
  • Loading branch information
floppym committed May 24, 2024
1 parent 3d30b6f commit 735d796
Showing 1 changed file with 19 additions and 25 deletions.
44 changes: 19 additions & 25 deletions src/openrc-shutdown/broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
*/


#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -37,14 +37,12 @@
# define _PATH_DEV "/dev/"
#endif

static sigjmp_buf jbuf;

/*
* Alarm handler
*/
RC_NORETURN static void handler(int arg RC_UNUSED)
static void handler(int arg RC_UNUSED)
{
siglongjmp(jbuf, 1);
/* do nothing */
}

static void getuidtty(char **userp, char **ttyp)
Expand Down Expand Up @@ -124,15 +122,11 @@ void broadcast(char *text)
char *p;
char *line = NULL;
struct sigaction sa;
int fd;
FILE *tp;
int flags;
char *term = NULL;
struct utmpx *utmp;
/*
* These are set across the sigsetjmp call, so they can't be stored on
* the stack, otherwise they might be clobbered.
*/
static int fd;
static FILE *tp;

getuidtty(&user, &tty);

Expand All @@ -159,6 +153,7 @@ void broadcast(char *text)
if (fork() != 0)
return;

/* Set up a noop signal handler to generate EINTR */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
Expand All @@ -179,24 +174,23 @@ void broadcast(char *text)
}

/*
* Open it non-delay
* Open it non-delay
* Set an alarm to generate EINTR in case we block.
*/
if (sigsetjmp(jbuf, 1) == 0) {
alarm(2);
flags = O_WRONLY|O_NDELAY|O_NOCTTY;
if (file_isatty(term) && (fd = open(term, flags)) >= 0) {
if (isatty(fd) && (tp = fdopen(fd, "w")) != NULL) {
fputs(line, tp);
fputs(text, tp);
fflush(tp);
}
alarm(2);
flags = O_WRONLY|O_NDELAY|O_NOCTTY;
if (file_isatty(term) && (fd = open(term, flags)) >= 0) {
if (isatty(fd) && (tp = fdopen(fd, "w")) != NULL) {
if ((fputs(line, tp) == EOF || fputs(text, tp) == EOF)
&& errno == EINTR)
/* Set another alarm for fclose */
alarm(1);
fclose(tp);
}
else
close(fd);
}
alarm(0);
if (fd >= 0)
close(fd);
if (tp != NULL)
fclose(tp);
free(term);
}
endutxent();
Expand Down

0 comments on commit 735d796

Please sign in to comment.