+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
#ifndef lint
-static char *sccsid = "@(#)wwspawn.c 2.1.1.1 83/08/09";
-#endif
+static char sccsid[] = "@(#)wwspawn.c 3.13 (Berkeley) %G%";
+#endif /* not lint */
#include "ww.h"
+#include <sys/signal.h>
-wwfork(wp)
+/*
+ * There is a dead lock with vfork and closing of pseudo-ports.
+ * So we have to be sneaky about error reporting.
+ */
+wwspawn(wp, file, argv)
register struct ww *wp;
+char *file;
+char **argv;
{
- switch (wp->ww_pid = fork()) {
+ int pid;
+ int ret;
+ char erred = 0;
+ int s;
+
+ s = sigblock(sigmask(SIGCHLD));
+ switch (pid = vfork()) {
case -1:
- return -1;
+ wwerrno = WWE_SYS;
+ ret = -1;
+ break;
case 0:
- wp->ww_state = WWS_INCHILD;
- wwenviron(wp);
- return 0;
+ if (wwenviron(wp) >= 0)
+ execvp(file, argv);
+ erred = 1;
+ _exit(1);
default:
- wp->ww_state = WWS_HASPROC;
- (void) close(wp->ww_tty);
- wp->ww_tty = -1;
- return wp->ww_pid;
+ if (erred) {
+ wwerrno = WWE_SYS;
+ ret = -1;
+ } else {
+ wp->ww_pid = pid;
+ wp->ww_state = WWS_HASPROC;
+ ret = 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:li#%d:im=\\E@:mi:\
- :nd=\\EC:ta=^I:pt:up=\\EA:"
-static char *env[100];
-static char buf[1024];
-extern char **environ;
-
-wwenviron(wp)
-register struct ww *wp;
-{
- register i;
- register char **p, **q;
- char **termcap = 0;
-
- (void) dup2(wp->ww_tty, 0);
- (void) dup2(wp->ww_tty, 1);
- (void) dup2(wp->ww_tty, 2);
- for (i = wwdtablesize - 1; i > 2; i--)
- (void) close(i);
-
- i = open("/dev/tty");
- (void) ioctl(i, (int)TIOCNOTTY, (char *)0);
- (void) close(i);
- (void) open(wp->ww_ttyname, 0);
-
- 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;
+ (void) sigsetmask(s);
+ if (wp->ww_socket >= 0) {
+ (void) close(wp->ww_socket);
+ wp->ww_socket = -1;
}
- if (termcap == 0)
- termcap = q++;
- *q = 0;
- *termcap = sprintf(buf, TERMCAP, wp->ww_w.nc, wp->ww_w.nr);
- (void) strcat(buf, wwkeys);
- environ = env;
+ return ret;
}