From: Roy Marples Date: Mon, 11 Aug 2008 09:28:53 +0000 (+0000) Subject: Rename exec_script to run_script. Split the exec/fork part to static exec_script... X-Git-Tag: v4.0.2~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b842b3c9f513fcbe67e1bfca685fed4e16bee9c;p=thirdparty%2Fdhcpcd.git Rename exec_script to run_script. Split the exec/fork part to static exec_script. This allows us to use vfork and stop gcc complaining about exec stamping on the env variable. --- diff --git a/client.c b/client.c index fbb1cd54..6bef1572 100644 --- a/client.c +++ b/client.c @@ -1393,7 +1393,7 @@ handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp, get_option_addr(&lease->server.s_addr, dhcp, DHO_SERVERID); log_dhcp(LOG_INFO, "offered", dhcp); if (state->options & DHCPCD_TEST) { - exec_script(options, iface->name, "TEST", dhcp, NULL); + run_script(options, iface->name, "TEST", dhcp, NULL); return 0; } state->state = STATE_REQUESTING; diff --git a/configure.c b/configure.c index 22b7950e..db2228eb 100644 --- a/configure.c +++ b/configure.c @@ -48,20 +48,48 @@ #define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin" + +static int +exec_script(char *const *argv, char *const *env) +{ + pid_t pid; + sigset_t full; + sigset_t old; + + /* OK, we need to block signals */ + sigfillset(&full); + sigprocmask(SIG_SETMASK, &full, &old); + signal_reset(); + + switch (pid = vfork()) { + case -1: + logger(LOG_ERR, "vfork: %s", strerror(errno)); + break; + case 0: + sigprocmask(SIG_SETMASK, &old, NULL); + execve(argv[0], argv, env); + logger(LOG_ERR, "%s: %s", argv[0], strerror(errno)); + _exit(127); + /* NOTREACHED */ + } + + /* Restore our signals */ + signal_setup(); + sigprocmask(SIG_SETMASK, &old, NULL); + return pid; +} + int -exec_script(const struct options *options, const char *iface, - const char *reason, - const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo) +run_script(const struct options *options, const char *iface, + const char *reason, + const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo) { char *const argv[2] = { UNCONST(options->script), NULL }; char **env = NULL, **ep; char *path; ssize_t e, elen; - int ret = 0; pid_t pid; int status = 0; - sigset_t full; - sigset_t old; logger(LOG_DEBUG, "executing `%s', reason %s", options->script, reason); @@ -115,50 +143,17 @@ exec_script(const struct options *options, const char *iface, } env[elen] = '\0'; - /* OK, we need to block signals */ - sigfillset(&full); - sigprocmask(SIG_SETMASK, &full, &old); - -#ifdef THERE_IS_NO_FORK - signal_reset(); - pid = vfork(); -#else - pid = fork(); -#endif - - switch (pid) { - case -1: -#ifdef THERE_IS_NO_FORK - logger(LOG_ERR, "vfork: %s", strerror(errno)); -#else - logger(LOG_ERR, "fork: %s", strerror(errno)); -#endif - ret = -1; - break; - case 0: -#ifndef THERE_IS_NO_FORK - signal_reset(); -#endif - sigprocmask(SIG_SETMASK, &old, NULL); - execve(options->script, argv, env); - logger(LOG_ERR, "%s: %s", options->script, strerror(errno)); - _exit(111); - /* NOTREACHED */ - } - -#ifdef THERE_IS_NO_FORK - signal_setup(); -#endif - - /* Restore our signals */ - sigprocmask(SIG_SETMASK, &old, NULL); - - /* Wait for the script to finish */ - while (waitpid(pid, &status, 0) == -1) { - if (errno != EINTR) { - logger(LOG_ERR, "waitpid: %s", strerror(errno)); - status = -1; - break; + pid = exec_script(argv, env); + if (pid == -1) + status = -1; + else if (pid != 0) { + /* Wait for the script to finish */ + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) { + logger(LOG_ERR, "waitpid: %s", strerror(errno)); + status = -1; + break; + } } } @@ -167,7 +162,6 @@ exec_script(const struct options *options, const char *iface, while (*ep) free(*ep++); free(env); - return status; } @@ -375,7 +369,7 @@ configure(struct interface *iface, const char *reason, delete_address(iface); } - exec_script(options, iface->name, reason, NULL, old); + run_script(options, iface->name, reason, NULL, old); return 0; } @@ -419,6 +413,6 @@ configure(struct interface *iface, const char *reason, if (write_lease(iface, dhcp) == -1) logger(LOG_ERR, "write_lease: %s", strerror(errno)); - exec_script(options, iface->name, reason, dhcp, old); + run_script(options, iface->name, reason, dhcp, old); return 0; } diff --git a/configure.h b/configure.h index c4c731ce..fe065db6 100644 --- a/configure.h +++ b/configure.h @@ -32,8 +32,8 @@ #include "dhcp.h" #include "net.h" -int exec_script(const struct options *, const char *, const char *, - const struct dhcp_message *, const struct dhcp_message *); +int run_script(const struct options *, const char *, const char *, + const struct dhcp_message *, const struct dhcp_message *); int configure(struct interface *, const char *, const struct dhcp_message *, const struct dhcp_message *, const struct dhcp_lease *, const struct options *, int);