simplify post-lock cmd and die if it fails - slock - simple X display locker utility
 (HTM) git clone git://git.suckless.org/slock
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a70d5d2429abf8dcb70a8817990975dc9a621d27
 (DIR) parent a34d8fb4327bbb1afd92e7527c53fcaad547a495
 (HTM) Author: NRK <nrk@disroot.org>
       Date:   Fri,  9 Sep 2022 14:50:12 +0600
       
       simplify post-lock cmd and die if it fails
       
       this patch does two things:
       
       0. simplify the code by using posix_spawn()
       1. unify the behavior of what happens if the post-lock cmd fails.
       
       currently, if `fork()` fails, slock will die without locking the screen.
       HOWEVER if `execvp()` fails it prints a message to stderr (which the
       user cannot see since the screen has been locked already) and only exits
       the child while the parent locks the screen.
       
       to reproduce:
       
               # slock some_bin_that_doesnt_exist
       
       this behavior is inconsistent, if the idea is that post-lock cmd is
       _not_ important then we shouldn't `die()` on `fork()` failure either.
       and if we assume that the post-lock cmd _is_ important, then we should
       die on exec failure as well.
       
       this patch assumes the latter and calls `die()` if `posix_spawn()`
       fails.
       
       Diffstat:
         M slock.c                             |      16 +++++++---------
       
       1 file changed, 7 insertions(+), 9 deletions(-)
       ---
 (DIR) diff --git a/slock.c b/slock.c
       @@ -13,6 +13,7 @@
        #include <stdio.h>
        #include <string.h>
        #include <unistd.h>
       +#include <spawn.h>
        #include <sys/types.h>
        #include <X11/extensions/Xrandr.h>
        #include <X11/keysym.h>
       @@ -376,15 +377,12 @@ main(int argc, char **argv) {
        
                /* run post-lock command */
                if (argc > 0) {
       -                switch (fork()) {
       -                case -1:
       -                        die("slock: fork failed: %s\n", strerror(errno));
       -                case 0:
       -                        if (close(ConnectionNumber(dpy)) < 0)
       -                                die("slock: close: %s\n", strerror(errno));
       -                        execvp(argv[0], argv);
       -                        fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno));
       -                        _exit(1);
       +                pid_t pid;
       +                extern char **environ;
       +                int err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ);
       +                if (err) {
       +                        die("slock: failed to execute post-lock command: %s: %s\n",
       +                            argv[0], strerror(err));
                        }
                }