From 5f04dcc951c51b33ed8fabe50c9d3284944b5609 Mon Sep 17 00:00:00 2001 From: NRK Date: Tue, 31 Jan 2023 05:23:33 +0600 Subject: [PATCH] fstabinfo: replace vfork with posix_spawnp problem: * vfork has been removed from POSIX [0]. * clang-tidy flags the `strerror` and `eerror` call inside the vfork-ed child as undefined behavior. solution: use posix_spawnp, which is serves similar purpose and is specified in posix. and as an added bonus, it's also easier to use and less lines of code. [0]: https://www.man7.org/linux/man-pages/man2/vfork.2.html#CONFORMING_TO --- src/fstabinfo/fstabinfo.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/fstabinfo/fstabinfo.c b/src/fstabinfo/fstabinfo.c index 36d4d27c..09cf5977 100644 --- a/src/fstabinfo/fstabinfo.c +++ b/src/fstabinfo/fstabinfo.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Yay for linux and its non liking of POSIX functions. Okay, we could use getfsent but the man page says use getmntent instead @@ -63,6 +64,8 @@ #include "_usage.h" #include "helpers.h" +extern char **environ; + const char *applet = NULL; const char *extraopts = NULL; const char getoptstring[] = "MRbmop:t:" getoptstring_COMMON; @@ -112,7 +115,7 @@ do_mount(struct ENT *ent, bool remount) { char *argv[10]; pid_t pid; - int status; + int status, err; argv[0] = UNCONST("mount"); argv[1] = UNCONST("-o"); @@ -137,23 +140,14 @@ do_mount(struct ENT *ent, bool remount) argv[8] = NULL; #endif } - switch (pid = vfork()) { - case -1: - eerrorx("%s: vfork: %s", applet, strerror(errno)); - /* NOTREACHED */ - case 0: - execvp(argv[0], argv); - eerror("%s: execvp: %s", applet, strerror(errno)); - _exit(EXIT_FAILURE); - /* NOTREACHED */ - default: - waitpid(pid, &status, 0); - if (WIFEXITED(status)) - return WEXITSTATUS(status); - else - return -1; - /* NOTREACHED */ - } + err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ); + if (err) + eerrorx("%s: posix_spawnp: %s", applet, strerror(err)); + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return -1; } #define OUTPUT_FILE (1 << 1)