On Sat, Mar 11, 2023 at 06:20:07AM +0600, NRK wrote:
> issues with the current signal handler:
> 
> 1. die() isn't async-signal-safe
> 2. there's a race-window during reinstating the signal handler allowing
>    zombies to be produced (should be rare in practice).
> 3. if waitpid fails, it will clobber the errno which can lead to
>    undesired codepath being taken on the resuming code (this one can
>    actually occur in practice).
> 
> to reproduce the 3rd issue:
> 
>       ~> ./tabbed &
>       [1] 20644
>       0x1800003
>       ~> while :; do kill -s SIGCHLD 20644; done >&2 2>/dev/null
>       XIO:  fatal IO error 10 (No child processes) on X server ":0"
>             after 47 requests (47 known processed) with 0 events remaining.
>       [1]  + exit 1     ./tabbed
> 
> set the signal handler to SIG_IGN to reap zombies automatically
> (according to POSIX.1-2001).
> 
> NOTE: this patch follows dwm's commit 712d663. according to the manpage,
> none of the sa_flags being set are meaningful since we're using SIG_IGN.
> they used to be meaningful on earlier version of the patch where it was
> using SIG_DFL, i've kept them here just in case.
> ---
>  Makefile |  2 +-
>  tabbed.c | 21 +++++++++------------
>  2 files changed, 10 insertions(+), 13 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index f8f5ba4..54ba350 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -11,7 +11,7 @@ DOCPREFIX = ${PREFIX}/share/doc/${NAME}
>  # use system flags.
>  TABBED_CFLAGS = -I/usr/X11R6/include -I/usr/include/freetype2 ${CFLAGS}
>  TABBED_LDFLAGS = -L/usr/X11R6/lib -lX11 -lfontconfig -lXft ${LDFLAGS}
> -TABBED_CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE
> +TABBED_CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE 
> -D_XOPEN_SOURCE=700L
>  
>  # OpenBSD (uncomment)
>  #TABBED_CFLAGS = -I/usr/X11R6/include -I/usr/X11R6/include/freetype2 
> ${CFLAGS}
> diff --git a/tabbed.c b/tabbed.c
> index eafe28a..477a041 100644
> --- a/tabbed.c
> +++ b/tabbed.c
> @@ -125,7 +125,6 @@ static void run(void);
>  static void sendxembed(int c, long msg, long detail, long d1, long d2);
>  static void setcmd(int argc, char *argv[], int);
>  static void setup(void);
> -static void sigchld(int unused);
>  static void spawn(const Arg *arg);
>  static int textnw(const char *text, unsigned int len);
>  static void toggle(const Arg *arg);
> @@ -976,9 +975,16 @@ setup(void)
>       XWMHints *wmh;
>       XClassHint class_hint;
>       XSizeHints *size_hint;
> +     struct sigaction sa;
>  
> -     /* clean up any zombies immediately */
> -     sigchld(0);
> +     /* do not transform children into zombies when they terminate */
> +     sigemptyset(&sa.sa_mask);
> +     sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART;
> +     sa.sa_handler = SIG_IGN;
> +     sigaction(SIGCHLD, &sa, NULL);
> +
> +     /* clean up any zombies that might have been inherited */
> +     while (waitpid(-1, NULL, WNOHANG) > 0);
>  
>       /* init screen */
>       screen = DefaultScreen(dpy);
> @@ -1078,15 +1084,6 @@ setup(void)
>       focus(-1);
>  }
>  
> -void
> -sigchld(int unused)
> -{
> -     if (signal(SIGCHLD, sigchld) == SIG_ERR)
> -             die("%s: cannot install SIGCHLD handler", argv0);
> -
> -     while (0 < waitpid(-1, NULL, WNOHANG));
> -}
> -
>  void
>  spawn(const Arg *arg)
>  {
> -- 
> 2.39.1
> 
> 

Hi NRK,

Thanks for the patch!

-- 
Kind regards,
Hiltjo

Reply via email to