+/*
+ * 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 = "@(#)wwenviron.c 3.8 84/01/13";
-#endif
+static char sccsid[] = "@(#)wwenviron.c 3.20 (Berkeley) %G%";
+#endif /* not lint */
#include "ww.h"
+#include <sys/signal.h>
/*
* Set up the environment of this process to run in window 'wp'.
- * Can't report errors in any intelligent way, because the parent
- * hangs in vfork() until we die, but we can't die until output
- * drains (i.e. deadlock). So don't say anything.
*/
wwenviron(wp)
register struct ww *wp;
{
- static char **termcap = 0;
- static char *tbuf;
register i;
int pgrp = getpid();
+ char buf[1024];
- i = open("/dev/tty", 0);
- if (i < 0)
- return;
- if (ioctl(i, (int)TIOCNOTTY, (char *)0) < 0)
- return;
+ if ((i = open("/dev/tty", 0)) < 0)
+ goto bad;
+ if (ioctl(i, TIOCNOTTY, (char *)0) < 0)
+ goto bad;
(void) close(i);
- if ((i = open(wp->ww_ttyname, 2)) < 0)
- return;
+ if ((i = wp->ww_socket) < 0 && (i = open(wp->ww_ttyname, 2)) < 0)
+ goto bad;
(void) dup2(i, 0);
(void) dup2(i, 1);
(void) dup2(i, 2);
for (i = wwdtablesize - 1; i > 2; i--)
(void) close(i);
- if (ioctl(0, (int)TIOCSPGRP, (char *)&pgrp) < 0)
- return;
+ (void) ioctl(0, TIOCSPGRP, (char *)&pgrp);
(void) setpgrp(pgrp, pgrp);
-
+ /* SIGPIPE is the only one we ignore */
+ (void) signal(SIGPIPE, SIG_DFL);
+ (void) sigsetmask(0);
/*
- * Do this only once if vfork().
+ * Two conditions that make destructive setenv ok:
+ * 1. setenv() copies the string,
+ * 2. we've already called tgetent which copies the termcap entry.
*/
- if (termcap == 0) {
- extern char **environ;
- static char **env;
- register char **p, **q;
-
- for (i = 0, p = environ; *p; p++, i++)
- ;
- env = (char **)malloc((unsigned)(i + 3) * sizeof (char *));
- if (env == 0)
- return;
- if ((tbuf = malloc((unsigned) 1024)) == 0)
- return;
- for (p = environ, q = env; *p; p++, q++) {
- if (strncmp(*p, "TERM=", 5) == 0)
- *q = WWT_TERM;
- else if (strncmp(*p, "TERMCAP=", 8) == 0)
- termcap = q;
- else
- *q = *p;
- }
- if (termcap == 0)
- termcap = q++;
- *q = 0;
- environ = env;
- }
- *termcap = sprintf(tbuf, "TERMCAP=%sco#%d:li#%d:%s%s%s%s",
- WWT_TERMCAP, wp->ww_w.nc, wp->ww_w.nr,
- wwavailmodes & WWM_REV ? WWT_REV : "",
- wwavailmodes & WWM_UL ? WWT_UL : "",
- wwavailmodes & WWM_GRP ? WWT_GRP : "",
- wwkeys);
+ (void) sprintf(buf, "%sco#%d:li#%d:%s",
+ WWT_TERMCAP, wp->ww_w.nc, wp->ww_w.nr, wwwintermcap);
+ (void) setenv("TERMCAP", buf, 1);
+ (void) sprintf(buf, "%d", wp->ww_id + 1);
+ (void) setenv("WINDOW_ID", buf, 1);
+ return 0;
+bad:
+ wwerrno = WWE_SYS;
+ return -1;
}