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
This commit is contained in:
NRK 2023-01-31 05:23:33 +06:00 committed by William Hubbs
parent 8f52c64c37
commit 5f04dcc951

View File

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
#include <spawn.h>
/* Yay for linux and its non liking of POSIX functions. /* Yay for linux and its non liking of POSIX functions.
Okay, we could use getfsent but the man page says use getmntent instead Okay, we could use getfsent but the man page says use getmntent instead
@ -63,6 +64,8 @@
#include "_usage.h" #include "_usage.h"
#include "helpers.h" #include "helpers.h"
extern char **environ;
const char *applet = NULL; const char *applet = NULL;
const char *extraopts = NULL; const char *extraopts = NULL;
const char getoptstring[] = "MRbmop:t:" getoptstring_COMMON; const char getoptstring[] = "MRbmop:t:" getoptstring_COMMON;
@ -112,7 +115,7 @@ do_mount(struct ENT *ent, bool remount)
{ {
char *argv[10]; char *argv[10];
pid_t pid; pid_t pid;
int status; int status, err;
argv[0] = UNCONST("mount"); argv[0] = UNCONST("mount");
argv[1] = UNCONST("-o"); argv[1] = UNCONST("-o");
@ -137,23 +140,14 @@ do_mount(struct ENT *ent, bool remount)
argv[8] = NULL; argv[8] = NULL;
#endif #endif
} }
switch (pid = vfork()) { err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ);
case -1: if (err)
eerrorx("%s: vfork: %s", applet, strerror(errno)); eerrorx("%s: posix_spawnp: %s", applet, strerror(err));
/* NOTREACHED */ waitpid(pid, &status, 0);
case 0: if (WIFEXITED(status))
execvp(argv[0], argv); return WEXITSTATUS(status);
eerror("%s: execvp: %s", applet, strerror(errno)); else
_exit(EXIT_FAILURE); return -1;
/* NOTREACHED */
default:
waitpid(pid, &status, 0);
if (WIFEXITED(status))
return WEXITSTATUS(status);
else
return -1;
/* NOTREACHED */
}
} }
#define OUTPUT_FILE (1 << 1) #define OUTPUT_FILE (1 << 1)