xref: /original-bsd/usr.bin/window/wwspawn.c (revision 18f6d767)
1 #ifndef lint
2 static char sccsid[] = "@(#)wwspawn.c	3.11 04/24/85";
3 #endif
4 
5 /*
6  * Copyright (c) 1983 Regents of the University of California,
7  * All rights reserved.  Redistribution permitted subject to
8  * the terms of the Berkeley Software License Agreement.
9  */
10 
11 #include "ww.h"
12 #include <sys/signal.h>
13 
14 /*
15  * There is a dead lock with vfork and closing of pseudo-ports.
16  * So we have to be sneaky about error reporting.
17  */
18 wwspawn(wp, file, argv)
19 register struct ww *wp;
20 char *file;
21 char **argv;
22 {
23 	int pid;
24 	int ret;
25 	char erred = 0;
26 	int s;
27 
28 	s = sigblock(sigmask(SIGCHLD));
29 	switch (pid = vfork()) {
30 	case -1:
31 		wwerrno = WWE_SYS;
32 		ret = -1;
33 		break;
34 	case 0:
35 		if (wwenviron(wp) >= 0)
36 			execvp(file, argv);
37 		erred = 1;
38 		_exit(1);
39 	default:
40 		if (erred) {
41 			wwerrno = WWE_SYS;
42 			ret = -1;
43 		} else {
44 			wp->ww_pid = pid;
45 			wp->ww_state = WWS_HASPROC;
46 			ret = pid;
47 		}
48 	}
49 	(void) sigsetmask(s);
50 	if (wp->ww_socket >= 0) {
51 		(void) close(wp->ww_socket);
52 		wp->ww_socket = -1;
53 	}
54 	return ret;
55 }
56