diff options
author | brian <brian@cvs.openbsd.org> | 2000-04-02 01:36:27 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 2000-04-02 01:36:27 +0000 |
commit | fa8efaefa291755ff81e3cdfd4db0b1ace20e01e (patch) | |
tree | ec3f47a56e749c81b1eb76eb64e40deba9996d1d /usr.sbin | |
parent | 4f6b5af467301b38639b4b79ed8feeb881f28151 (diff) |
When a link is ``!program'', realise when the process we're
exec()ing couldn't be exec'd and fail the device open rather
than thinking the open succeeded but the first read() got zero.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/ppp/ppp/exec.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/usr.sbin/ppp/ppp/exec.c b/usr.sbin/ppp/ppp/exec.c index 40c146b7e70..233cea903b3 100644 --- a/usr.sbin/ppp/ppp/exec.c +++ b/usr.sbin/ppp/ppp/exec.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: exec.c,v 1.11 2000/02/27 01:38:25 brian Exp $ + * $OpenBSD: exec.c,v 1.12 2000/04/02 01:36:26 brian Exp $ */ #include <sys/param.h> @@ -108,7 +108,8 @@ exec_Create(struct physical *p) log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", strerror(errno)); else { - int stat, argc, i; + static int child_status; + int stat, argc, i, ret, wret; pid_t pid, realpid; char *argv[MAXARGS]; @@ -122,6 +123,7 @@ exec_Create(struct physical *p) case -1: log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", strerror(errno)); + close(fids[1]); break; case 0: @@ -129,15 +131,20 @@ exec_Create(struct physical *p) timer_TermService(); setuid(ID0realuid()); - switch (fork()) { + child_status = 0; + switch (vfork()) { case 0: break; case -1: + ret = errno; log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n", strerror(errno)); + _exit(ret); + break; + default: - _exit(127); + _exit(child_status); /* The error from exec() ! */ } log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); @@ -145,7 +152,7 @@ exec_Create(struct physical *p) if ((argc = MakeArgs(p->name.base, argv, VECSIZE(argv), PARSE_REDUCE|PARSE_NOHASH)) < 0) { log_Printf(LogWARN, "Syntax error in exec command\n"); - _exit(127); + _exit(ESRCH); } command_Expand(argv, argc, (char const *const *)argv, @@ -158,20 +165,43 @@ exec_Create(struct physical *p) fcntl(i, F_SETFD, 1); execvp(*argv, argv); - printf("execvp failed: %s: %s\r\n", *argv, strerror(errno)); - _exit(127); + child_status = errno; /* Only works for vfork() */ + printf("execvp failed: %s: %s\r\n", *argv, strerror(child_status)); + _exit(child_status); break; default: close(fids[1]); + while ((wret = waitpid(pid, &stat, 0)) == -1 && errno == EINTR) + ; + if (wret == -1) { + log_Printf(LogWARN, "Waiting for child process: %s\n", + strerror(errno)); + close(fids[0]); + break; + } else if (WIFSIGNALED(stat)) { + log_Printf(LogWARN, "Child process received sig %d !\n", + WTERMSIG(stat)); + close(fids[0]); + break; + } else if (WIFSTOPPED(stat)) { + log_Printf(LogWARN, "Child process received stop sig %d !\n", + WSTOPSIG(stat)); + /* I guess that's ok.... */ + } else if ((ret = WEXITSTATUS(stat))) { + log_Printf(LogWARN, "Cannot exec \"%s\": %s\n", p->name.base, + strerror(ret)); + close(fids[0]); + break; + } p->fd = fids[0]; - waitpid(pid, &stat, 0); log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); if (p->cfg.cd.necessity != CD_DEFAULT) log_Printf(LogWARN, "Carrier settings ignored\n"); return &execdevice; } + close(fids[0]); } } |