From ba85636c1f274880ea67a3a477450c15d55f1beb Mon Sep 17 00:00:00 2001 From: brian Date: Sun, 2 Apr 2000 01:36:26 +0000 Subject: [PATCH] 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. --- usr.sbin/ppp/ppp/exec.c | 46 ++++++++++++++++++++++++++++++++++------- 1 file 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 @@ -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]); } } -- 2.20.1