aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2024-02-16 03:52:31 +0000
committerWarner Losh <imp@FreeBSD.org>2024-02-16 03:59:22 +0000
commit33a2406eed009dbffd7dfa44285c23f0db5a3750 (patch)
tree3cfd914ffcc315a4d79d767e89a4ca061ad1cb74
parent62b1faa3b7495de22a3225e42dabe6ce8c371e86 (diff)
downloadsrc-33a2406eed009dbffd7dfa44285c23f0db5a3750.tar.gz
src-33a2406eed009dbffd7dfa44285c23f0db5a3750.zip
reboot: Use posix_spawn instead of system
Use posix_spawn to avoid having to allocate memory needed for the system command line. Sponsored by: Netflix Reviewed by: jrtc27 Differential Revision: https://reviews.freebsd.org/D43860
-rw-r--r--sbin/reboot/reboot.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index e9d6487da6a5..d3f1fc9bbb86 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -29,19 +29,21 @@
* SUCH DAMAGE.
*/
-#include <sys/types.h>
#include <sys/boottrace.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
+#include <spawn.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -69,23 +71,43 @@ static bool donextboot;
static void
zfsbootcfg(const char *pool, bool force)
{
- char *k;
- int rv;
-
- asprintf(&k,
- "zfsbootcfg -z %s -n freebsd:nvstore -k nextboot_enable -v YES",
- pool);
- if (k == NULL)
- E("No memory for zfsbootcfg");
-
- rv = system(k);
- if (rv == 0)
- return;
+ const char * const av[] = {
+ "zfsbootcfg",
+ "-z",
+ pool,
+ "-n",
+ "freebsd:nvstore",
+ "-k",
+ "nextboot_enable"
+ "-v",
+ "YES",
+ NULL
+ };
+ int rv, status;
+ pid_t p;
+ extern char **environ;
+
+ rv = posix_spawnp(&p, av[0], NULL, NULL, __DECONST(char **, av),
+ environ);
if (rv == -1)
E("system zfsbootcfg");
- if (rv == 127)
- E("zfsbootcfg not found in path");
- E("zfsbootcfg returned %d", rv);
+ if (waitpid(p, &status, WEXITED) < 0) {
+ if (errno == EINTR)
+ return;
+ E("waitpid zfsbootcfg");
+ }
+ if (WIFEXITED(status)) {
+ int e = WEXITSTATUS(status);
+
+ if (e == 0)
+ return;
+ if (e == 127)
+ E("zfsbootcfg not found in path");
+ E("zfsbootcfg returned %d", e);
+ }
+ if (WIFSIGNALED(status))
+ E("zfsbootcfg died with signal %d", WTERMSIG(status));
+ E("zfsbootcfg unexpected status %d", status);
}
static void