summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorbrian <brian@cvs.openbsd.org>2000-04-02 01:36:27 +0000
committerbrian <brian@cvs.openbsd.org>2000-04-02 01:36:27 +0000
commitfa8efaefa291755ff81e3cdfd4db0b1ace20e01e (patch)
treeec3f47a56e749c81b1eb76eb64e40deba9996d1d /usr.sbin
parent4f6b5af467301b38639b4b79ed8feeb881f28151 (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.c46
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]);
}
}