summaryrefslogtreecommitdiffstats
path: root/configure.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-08-11 09:28:53 +0000
committerRoy Marples <roy@marples.name>2008-08-11 09:28:53 +0000
commit6b842b3c9f513fcbe67e1bfca685fed4e16bee9c (patch)
treefe09c4bd43cd1ac5ddaeb77f5070c11424431140 /configure.c
parentef53de735fad7fb3036e4bb83824f3b36aac3e9d (diff)
downloaddhcpcd-6b842b3c9f513fcbe67e1bfca685fed4e16bee9c.tar.xz
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.
Diffstat (limited to 'configure.c')
-rw-r--r--configure.c100
1 files changed, 47 insertions, 53 deletions
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;
}