aboutsummaryrefslogtreecommitdiffstats
path: root/sbin/sysinstall/exec.c
blob: 00f6cd76281fb5f43ebdf2bb14df4ad3901cc381 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <phk@login.dkuug.dk> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 *
 * $Id: exec.c,v 1.6 1994/11/08 14:04:16 jkh Exp $
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <dialog.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/reboot.h>

#include "sysinstall.h"

int
exec(int magic, char *cmd, char *args, ...)
{
	int pid, w, status;
	char *argv[EXEC_MAXARG];
	int arg = 0;
	va_list ap;
	struct stat dummy;

	if (stat(cmd, &dummy) == -1) {
		sprintf(errmsg, "Executable %s does not exist\n", cmd);
		return(-1);
	}

	va_start(ap, args);
	argv[arg++] = (char *)args;
	do {
		if (arg >= EXEC_MAXARG) 
			Fatal("Too many arguments");
	} while ((argv[arg++] = va_arg(ap, char *)));
	va_end(ap);

	if ((pid = fork()) == 0) {
		switch (magic) {
		case 0:
			close(0); dup(debug_fd);
			close(1); dup(debug_fd);
			close(2); dup(debug_fd);
			close(debug_fd);
			break;
		case 1:
			close(2); dup(debug_fd);
			close(debug_fd);
			break;
		case 2:
		case 3:
			close(debug_fd);
		default:
			break;
		}
		execv(cmd, argv);
		exit(1);
	}
	
	while ((w = wait(&status)) != pid && w != -1)
		;
	if ((status >> 8) == 20 && magic == 3)	/* special case for bininst */
		reboot(RB_AUTOBOOT);
	if (w == -1)
		Fatal("Child process %s terminated abnormally\n", cmd);
	return(status);
}