#ifndef lint
-static char *sccsid = "@(#)wwspawn.c 1.2 83/07/17";
+static char *sccsid = "@(#)wwspawn.c 3.7 84/01/13";
#endif
#include "ww.h"
+#include <signal.h>
-wwfork(wp)
+/*
+ * There is a dead lock with vfork and closing of pseudo-ports.
+ * So we have to be sneaky.
+ */
+/*VARARGS3*/
+wwspawn(wp, file, argv0)
register struct ww *wp;
+char *file, *argv0;
{
- switch (wp->ww_pid = fork()) {
+ extern int errno;
+ extern char *sys_errlist[];
+ int pid;
+
+ (void) sighold(SIGCHLD);
+ switch (pid = vfork()) {
case -1:
+ wwerrno = WWE_SYS;
+ (void) sigrelse(SIGCHLD);
return -1;
case 0:
- wp->ww_state = WW_INCHILD;
wwenviron(wp);
- return 0;
+ errno = 0;
+ execv(file, &argv0);
+ _exit(1);
default:
- wp->ww_state = WW_HASPROC;
- return wp->ww_pid;
- }
-}
-
-#define TERM "TERM=window"
-#define TERMCAP "TERMCAP=WW|window|window package:\
- :cr=^M:nl=^J:bl=^G:\
- :al=\\EL:am:le=^H:bs:cd=\\EJ:ce=\\EK:cl=\\EE:cm=\\EY%%+ %%+ :\
- :co#%d:dc=\\EN:dl=\\EM:do=\\EB:ei=\\EO:ho=\\EH:im=\\E@:li#%d:mi:\
- :nd=\\EC:ta=^I:pt:up=\\EA:"
-static char *env[100];
-static char buf[sizeof TERMCAP + 10];
-extern char **environ;
-
-wwenviron(wp)
-register struct ww *wp;
-{
- register i;
- register char **p, **q;
- char **termcap = 0;
-
- dup2(wp->ww_tty, 0);
- dup2(wp->ww_tty, 1);
- dup2(wp->ww_tty, 2);
- for (i = getdtablesize() - 1; i > 2; i--)
- close(i);
-
- for (p = environ, q = env; *p; p++, q++) {
- if (strncmp(*p, "TERM=", 5) == 0)
- *q = TERM;
- else if (strncmp(*p, "TERMCAP=", 8) == 0)
- termcap = q;
- else
- *q = *p;
+ if (errno != 0) {
+ wwerrno = WWE_SYS;
+ (void) sigrelse(SIGCHLD);
+ return -1;
+ } else {
+ wp->ww_pid = pid;
+ wp->ww_state = WWS_HASPROC;
+ (void) sigrelse(SIGCHLD);
+ return pid;
+ }
}
- if (termcap == 0)
- termcap = q++;
- *q = 0;
- *termcap = sprintf(buf, TERMCAP, wp->ww_ncol, wp->ww_nrow);
- environ = env;
}