From: Roy Marples Date: Sun, 11 Nov 2012 00:25:58 +0000 (+0000) Subject: Log posix_spawn(2) errors better. X-Git-Tag: v5.99.3~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9530feed8ab30c96f639b521bed1d6ef982df018;p=thirdparty%2Fdhcpcd.git Log posix_spawn(2) errors better. In our compat shim, use fork(2) if we have it, otherwise vfork(2). This makes us a lot better in terms of reliability, but sucks for reporting errors. --- diff --git a/compat/posix_spawn.c b/compat/posix_spawn.c index 3de3f301..00f0cb3d 100644 --- a/compat/posix_spawn.c +++ b/compat/posix_spawn.c @@ -26,9 +26,7 @@ */ /* This implementation of posix_spawn is only suitable for the needs of dhcpcd - * but it could easily be extended to other applications. - * Also, it does rely on the system being able to modify signals safely within - * the vfork process which is undefined behaviour, but seems sane in testing. */ + * but it could easily be extended to other applications. */ #include #include @@ -86,7 +84,12 @@ posix_spawn(pid_t *pid, const char * path, volatile int error; error = 0; +#ifdef THERE_IS_NO_FORK + /* Pray we can sanely modify signal foo */ p = vfork(); +#else + p = fork(); +#endif switch (p) { case -1: return errno; diff --git a/configure.c b/configure.c index 78b470c9..03e24555 100644 --- a/configure.c +++ b/configure.c @@ -101,8 +101,10 @@ exec_script(char *const *argv, char *const *env) posix_spawnattr_setsigmask(&attr, &dhcpcd_sigset); errno = 0; i = posix_spawn(&pid, argv[0], NULL, &attr, argv, env); - if (i) + if (i) { + errno = i; return -1; + } return pid; } @@ -422,10 +424,9 @@ run_script_reason(const struct interface *iface, const char *reason) env[++elen] = '\0'; pid = exec_script(argv, env); - if (pid == -1) { - syslog(LOG_ERR, "exec_script: %m"); - status = -1; - } else if (pid != 0) { + if (pid == -1) + syslog(LOG_ERR, "exec_script: %s: %m", argv[0]); + else if (pid != 0) { /* Wait for the script to finish */ while (waitpid(pid, &status, 0) == -1) { if (errno != EINTR) { @@ -462,7 +463,7 @@ run_script_reason(const struct interface *iface, const char *reason) while (*ep) free(*ep++); free(env); - return status; + return WEXITSTATUS(status); } static struct rt *