This is uw_win.c in view mode; [Download] [Up]
/* * uw_win - window handling for UW * * Copyright 1986 by John D. Bruner. All rights reserved. Permission to * copy this program is given provided that the copy is not sold and that * this copyright notice is included. */ #include <sys/types.h> #include <sys/file.h> #include <sys/ioctl.h> #include <signal.h> #include <strings.h> #include <stdio.h> #include "openpty.h" #include "uw_param.h" #include "uw_opt.h" #include "uw_win.h" #include "uw_fd.h" /* * "defwtype" specifies the default window type. This type is used when * more specific information is not available. */ wtype_t defwtype = WT_ADM31; /* * "window" is declared in "uw_win.h" Here we define it. */ struct window window[NWINDOW]; /* window data structures */ /* * "emulation" describes window emulation-specific data. "generic_emul" * describes emulations which do not require special server attention * (e.g. file transfer, all of whose real work is done by a separate process). */ extern struct emulation adm31_emul, vt52_emul, ansi_emul, tek_emul; static struct emulation generic_emul; static struct emulation *emulation[WT_MAXTYPE+1] = { &adm31_emul, &vt52_emul, &ansi_emul, &tek_emul, &generic_emul, &generic_emul, &generic_emul, }; extern char *win_getopt(); extern void win_setopt(); static woptarg_t woa_vis[] = { WOA_UDATA(1), WOA_END }; static woptarg_t woa_type[] = { WOA_UDATA(6), WOA_END }; static woptarg_t woa_pos[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END }; static woptarg_t woa_title[] = { WOA_STRING(255), WOA_END }; static woptarg_t woa_size[] = { WOA_UDATA(12), WOA_UDATA(12), WOA_END }; static struct woptdefn genwinopt = { (1<<WOG_VIS), 0, 0, 0, (1<<WOG_VIS)|(1<<WOG_TYPE)|(1<<WOG_POS)|(1<<WOG_TITLE)|(1<<WOG_SIZE), { /* WOG_END */ { NULL, NULL, NULL }, /* WOG_VIS */ { woa_vis, win_getopt, win_setopt }, /* WOG_TYPE */ { woa_type, win_getopt, win_setopt }, /* WOG_POS */ { woa_pos, win_getopt, win_setopt }, /* WOG_TITLE */ { woa_title, win_getopt, win_setopt }, /* WOG_SIZE */ { woa_size, win_getopt, win_setopt }, /* WOG_6 */ { NULL, NULL, NULL }, /* WOG_7 */ { NULL, NULL, NULL } } }; /* * This is a violation of the level structure, but it is expedient. */ extern void ipc_optmsg(); win_init() { register struct window *w; /* * Initialize. Mark all windows unallocated. */ for (w=window; w < window+NWINDOW; w++) w->w_alloc = 0; } long win_mkid() { static unsigned short i = 0; static long pid = -1; if (pid == -1) pid = getpid(); return((pid << (NBBY*(sizeof(long)/sizeof(short)))) | i++); } struct window * win_search(wid, maxwin) long wid; nwin_t maxwin; { register struct window *w; for (w=window; w < window+maxwin; w++) if (w->w_alloc && w->w_id == wid) return(w); return((struct window *)0); } struct window * win_neww(wclass, wtype, wnum, maxwin, wid, datafd, ctlfd, options) wclass_t wclass; wtype_t wtype; nwin_t wnum; nwin_t maxwin; long wid; fildes_t datafd; fildes_t ctlfd; struct woptdefn *options; { fildes_t fd; int pid; struct window *w; char *tty, *shell; auto struct ptydesc pt; extern char *getenv(); /* * Create a new window. "wclass" specifies the window wclass. * If "wnum" is negative, choose a window number; otherwise, * "wnum" is the window number. "datafd" and "ctlfd" are the * data and control file descriptors to be associated with * this window. If "datafd" is negative and "wclass" is * WC_INTERNAL, allocate a pseudo-terminal. * * If "options" is non-NULL it specifies the address of an * option definition structure; otherwise, a new one is constructed * from the generic and emulation-specific prototype structures. * * If "wid" is nonzero it is a proposed window ID. It must be * unique (not in use). If "wid" is zero, a new ID is assigned. * * The window type "wtype" will always be a terminal emulation * if the wclass is WC_INTERNAL. * * Internal-class windows are visible by default, while external * ones are initially invisible. * * Return the address of the window structure or NULL if * none could be created. */ tty = (char *)0; if (wtype > WT_MAXTYPE) return((struct window *)0); if (wid == 0) { while (win_search(wid=win_mkid(), maxwin) != NULL) ; } else if (win_search(wid, maxwin) != NULL) return((struct window *)0); if (datafd < 0 && wclass == WC_INTERNAL) { if (!openpty(&pt)) { datafd = pt.pt_pfd; tty = pt.pt_tname; while ((pid = fork()) < 0) sleep(5); if (!pid) { win_envinit(wtype, wid); (void)signal(SIGHUP, SIG_DFL); (void)signal(SIGINT, SIG_DFL); (void)signal(SIGQUIT, SIG_DFL); (void)signal(SIGTERM, SIG_DFL); (void)signal(SIGTSTP, SIG_IGN); (void)signal(SIGCHLD, SIG_DFL); (void)ioctl(open("/dev/tty",O_RDWR), (int)TIOCNOTTY, (char *)0); (void)close(open(pt.pt_tname, O_RDONLY)); (void)setuid(getuid()); if (!(shell = getenv("SHELL"))) shell = "/bin/sh"; if (pt.pt_tfd != 0) (void)dup2(pt.pt_tfd, 0); if (pt.pt_tfd != 1); (void)dup2(pt.pt_tfd, 1); if (pt.pt_tfd != 2) (void)dup2(pt.pt_tfd, 2); for (fd=3; fd < nfds; fd++) (void)close(fd); tty_mode(0); /* HACK! */ execl(shell, shell, (char *)0); _exit(1); } else { utmp_add(tty); (void)close(pt.pt_tfd); } } } if (datafd >= 0) { if (wnum > 0) { w = WIN_PTR(wnum); if (w->w_alloc) w = (struct window *)0; } else { for (w=window; w < window+maxwin && w->w_alloc; w++) ; if (w >= window+maxwin) w = (struct window *)0; } } else w = (struct window *)0; if (w) { w->w_alloc = 1; w->w_id = wid; w->w_class = wclass; w->w_type = wtype; w->w_visible = (w->w_class == WC_INTERNAL); w->w_position.h = w->w_position.v = 0; w->w_size.h = w->w_size.v = 0; w->w_title[0] = '\0'; if (emulation[wtype]->we_start && !(*emulation[wtype]->we_start)(w)) { if (options) w->w_optdefn = *options; else opt_new(&w->w_optdefn, &genwinopt, (struct woptdefn *)0); } else { if (options) w->w_optdefn = *options; else opt_new(&w->w_optdefn, &genwinopt, &emulation[wtype]->we_optdefn); } w->w_datafd = datafd; (void)fcntl(datafd, F_SETFL, FNDELAY); FD_SET(datafd, &selmask[0].sm_rd); fdmap[datafd].f_type = FDT_DATA; fdmap[datafd].f_win = w; if (w->w_class == WC_INTERNAL) { if (tty) (void)strncpy(w->w_tty, tty, sizeof w->w_tty); } else { w->w_ctlfd = ctlfd; if (ctlfd >= 0) { (void)fcntl(ctlfd, F_SETFL, FNDELAY); FD_SET(ctlfd, &selmask[0].sm_rd); fdmap[ctlfd].f_type = FDT_CTL; fdmap[ctlfd].f_win = w; if (emulation[wtype]->we_setext) (*emulation[wtype]->we_setext)(&w->w_optdefn); opt_setext(&w->w_optdefn, ipc_optmsg); } } } return(w); } win_killw(w) register struct window *w; { /* * Kill the window "w". This is pretty simple; we just close * the data and control file descriptors and mark the structure * inactive. */ if (w && w->w_alloc) { if (w->w_datafd >= 0) { if (w->w_class == WC_INTERNAL) utmp_rm(w->w_tty); FD_CLR(w->w_datafd, &selmask[0].sm_rd); FD_CLR(w->w_datafd, &selmask[0].sm_wt); FD_CLR(w->w_datafd, &selmask[0].sm_ex); fdmap[w->w_datafd].f_type = FDT_NONE; (void)close(w->w_datafd); } if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) { FD_CLR(w->w_ctlfd, &selmask[0].sm_rd); FD_CLR(w->w_ctlfd, &selmask[0].sm_wt); FD_CLR(w->w_ctlfd, &selmask[0].sm_ex); fdmap[w->w_ctlfd].f_type = FDT_NONE; (void)close(w->w_ctlfd); } w->w_alloc = 0; } } win_renew(w, report) struct window *w; int report; { /* * Reinitialize (re-NEW) the window "w". Report the state of the * window to the Mac if "report" is nonzero. */ opt_renew(&w->w_optdefn, report); } win_newtype(w, wtype) register struct window *w; register wtype_t wtype; { /* * Change the window emulation type to "wtype". */ if (wtype <= WT_MAXTYPE && wtype != w->w_type) { if (emulation[w->w_type]->we_stop) (*emulation[w->w_type]->we_stop)(w); w->w_type = wtype; if (emulation[wtype]->we_start && !(*emulation[wtype]->we_start)(w)) { opt_newtype(&w->w_optdefn, &genwinopt, (struct woptdefn *)0); } else { opt_newtype(&w->w_optdefn, &genwinopt, &emulation[wtype]->we_optdefn); } if (w->w_class == WC_EXTERNAL && w->w_ctlfd >= 0) { if (emulation[wtype]->we_setext) (*emulation[wtype]->we_setext)(&w->w_optdefn); opt_setext(&w->w_optdefn, ipc_optmsg); } } } win_envinit(wtype, wid) register wtype_t wtype; long wid; { register char *widstr; auto char *env[2]; /* * Set up the environment according to the new window type and * window ID. * * A 64-bit integer will fit in 20 digits. If a "long" is wider * than this, then this code will have to be adjusted. */ if (wtype <= WT_TEK4010) tty_envinit(wtype); if ((widstr = malloc(sizeof "UW_ID=" + 20)) != NULL) { sprintf(widstr, "UW_ID=%ld", wid); env[0] = widstr; env[1] = (char *)0; env_set(env); } } static char * win_getopt(win, num) caddr_t win; woption_t num; { register struct window *w; static union optvalue ov; /* * Get the value of window option "num". It is arguably wrong to * always return the address of "ov" (even if the window isn't * allocated or an unknown option type was requested); however, * we're already in trouble and there is no good way to recover * at this point. */ if ((w = (struct window *)win) != NULL && w->w_alloc) { switch (num) { case WOG_VIS: ov.ov_udata1 = w->w_visible; break; case WOG_TYPE: ov.ov_udata6 = w->w_type; break; case WOG_POS: ov.ov_point.h = w->w_position.h; ov.ov_point.v = w->w_position.v; break; case WOG_TITLE: (void)strncpy(ov.ov_string, w->w_title, sizeof ov.ov_string); ov.ov_string[sizeof ov.ov_string-1] = '\0'; break; case WOG_SIZE: ov.ov_point.h = w->w_size.h; ov.ov_point.v = w->w_size.v; break; } } return((char *)&ov); } static void win_setopt(win, num, value) caddr_t win; woption_t num; char *value; { register struct window *w; register union optvalue *ov; /* * Set window option "num" to "value" */ if ((w = (struct window *)win) != NULL && w->w_alloc && (ov = (union optvalue *)value) != NULL) { switch (num) { case WOG_VIS: w->w_visible = ov->ov_udata1; break; case WOG_TYPE: win_newtype(w, (wtype_t)ov->ov_udata6); break; case WOG_POS: w->w_position.h = ov->ov_point.h; w->w_position.v = ov->ov_point.v; break; case WOG_TITLE: (void)strncpy(w->w_title, ov->ov_string, sizeof w->w_title); w->w_title[sizeof w->w_title-1] = '\0'; break; case WOG_SIZE: w->w_size.h = ov->ov_point.h; w->w_size.v = ov->ov_point.v; break; } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.