📄 main.c
字号:
*/#ifdef DEBUGGING fprintf(stderr, "Opened!\n");#endif (void) devindex++; return 0; }#ifdef DEBUGGING fprintf(stderr, "Didn't open!\n");#endif devindex++; } devindex = 0; (void) letter++; }#endif /* CRAY else */ /* * We were unable to allocate a pty master! Return an error * condition and let our caller terminate cleanly. */ return 1;}get_terminal ()/* * sets up X and initializes the terminal structure except for term.buf.fildes. */{ register TScreen *screen = &term->screen; #ifdef DEBUGGING fprintf(stderr, "entered get_terminal\n");#endif screen->arrow = make_colored_cursor (XC_left_ptr, screen->mousecolor, screen->mousecolorback);}/* * The only difference in /etc/termcap between 4014 and 4015 is that * the latter has support for switching character sets. We support the * 4015 protocol, but ignore the character switches. Therefore, we * choose 4014 over 4015. * * Features of the 4014 over the 4012: larger (19") screen, 12-bit * graphics addressing (compatible with 4012 10-bit addressing), * special point plot mode, incremental plot mode (not implemented in * later Tektronix terminals), and 4 character sizes. * All of these are supported by xterm. */static char *tekterm[] = { "tek4014", "tek4015", /* 4014 with APL character set support */ "tek4012", /* 4010 with lower case */ "tek4013", /* 4012 with APL character set support */ "tek4010", /* small screen, upper-case only */ "dumb", 0};/* The VT102 is a VT100 with the Advanced Video Option included standard. * It also adds Escape sequences for insert/delete character/line. * The VT220 adds 8-bit character sets, selective erase. * The VT320 adds a 25th status line, terminal state interrogation. * The VT420 has up to 48 lines on the screen. */static char *vtterm[] = {#ifdef USE_X11TERM "x11term", /* for people who want special term name */#endif "color_xterm", "xterm", /* the prefered name, should be fastest */ "vt102", "vt100", "ansi", "dumb", 0};/* ARGSUSED */SIGNAL_T hungtty(i) int i;{#ifdef DEBUGGING fprintf(stderr, "entered hungtty\n");#endif longjmp(env, 1); SIGNAL_RETURN;}#ifdef USE_HANDSHAKEtypedef enum { /* c == child, p == parent */ PTY_BAD, /* c->p: can't open pty slave for some reason */ PTY_FATALERROR, /* c->p: we had a fatal error with the pty */ PTY_GOOD, /* c->p: we have a good pty, let's go on */ PTY_NEW, /* p->c: here is a new pty slave, try this */ PTY_NOMORE, /* p->c; no more pty's, terminate */ UTMP_ADDED, /* c->p: utmp entry has been added */ UTMP_TTYSLOT, /* c->p: here is my ttyslot */ PTY_EXEC /* p->c: window has been mapped the first time */} status_t;typedef struct { status_t status; int error; int fatal_error; int tty_slot; int rows; int cols; char buffer[1024];} handshake_t;/* HsSysError() * * This routine does the equivalent of a SysError but it handshakes * over the errno and error exit to the master process so that it can * display our error message and exit with our exit code so that the * user can see it. */voidHsSysError(pf, error)int pf;int error;{ handshake_t handshake;#ifdef DEBUGGING fprintf(stderr, "entered HsSysError\n");#endif handshake.status = PTY_FATALERROR; handshake.error = errno; handshake.fatal_error = error; strcpy(handshake.buffer, ttydev); write(pf, (char *) &handshake, sizeof(handshake)); exit(error);}static int pc_pipe[2]; /* this pipe is used for parent to child transfer */static int cp_pipe[2]; /* this pipe is used for child to parent transfer */void first_map_occurred (){ handshake_t handshake; register TScreen *screen = &term->screen;#ifdef DEBUGGING fprintf(stderr, "entered first_map_occurred\n");#endif handshake.status = PTY_EXEC; handshake.rows = screen->max_row; handshake.cols = screen->max_col; write (pc_pipe[1], (char *) &handshake, sizeof(handshake)); close (cp_pipe[0]); close (pc_pipe[1]); waiting_for_initial_map = False;}#else/* * temporary hack to get xterm working on att ptys */void first_map_occurred (){ return;}#define HsSysError(a,b)#endif /* USE_HANDSHAKE else !USE_HANDSHAKE */spawn ()/* * Inits pty and tty and forks a login process. * Does not close fd Xsocket. * If slave, the pty named in passedPty is already open for use */{ extern char *SysErrorMsg(); register TScreen *screen = &term->screen; int Xsocket = ConnectionNumber(screen->display);#ifdef USE_HANDSHAKE handshake_t handshake;#else int fds[2];#endif int tty = -1; int discipline; int done;#ifdef USE_SYSV_TERMIO struct termio tio; struct termio dummy_tio;#ifdef TIOCLSET unsigned lmode;#endif /* TIOCLSET */#ifdef TIOCSLTC struct ltchars ltc;#endif /* TIOCSLTC */ int one = 1; int zero = 0; int status;#else /* else not USE_SYSV_TERMIO */ unsigned lmode; struct tchars tc; struct ltchars ltc; struct sgttyb sg;#ifdef sony int jmode; struct jtchars jtc;#endif /* sony */#endif /* USE_SYSV_TERMIO */ char termcap [1024]; char newtc [1024]; char *ptr, *shname, *shname_minus; int i, no_dev_tty = FALSE;#ifdef USE_SYSV_TERMIO char *dev_tty_name = (char *) 0; int fd; /* for /etc/wtmp */#endif /* USE_SYSV_TERMIO */ char **envnew; /* new environment */ int envsize; /* elements in new environment */ char buf[64]; char *TermName = NULL; int ldisc = 0;#ifdef sun#ifdef TIOCSSIZE struct ttysize ts;#endif /* TIOCSSIZE */#else /* not sun */#ifdef TIOCSWINSZ struct winsize ws;#endif /* TIOCSWINSZ */#endif /* sun */ struct passwd *pw = NULL;#ifdef UTMP struct utmp utmp;#ifdef LASTLOG struct lastlog lastlog;#endif /* LASTLOG */#endif /* UTMP */#ifdef DEBUGGING fprintf(stderr, "entered spawn()\n");#endif screen->uid = getuid(); screen->gid = getgid();#ifdef SIGTTOU /* so that TIOCSWINSZ || TIOCSIZE doesn't block */ signal(SIGTTOU,SIG_IGN);#endif if (am_slave) { screen->respond = am_slave; ptydev[strlen(ptydev) - 2] = ttydev[strlen(ttydev) - 2] = passedPty[0]; ptydev[strlen(ptydev) - 1] = ttydev[strlen(ttydev) - 1] = passedPty[1]; setgid (screen->gid);#ifdef GAPING_SECURITY_HOLE if (resetuid)#endif setuid (screen->uid); } else { Bool tty_got_hung = False; /* * Sometimes /dev/tty hangs on open (as in the case of a pty * that has gone away). Simply make up some reasonable * defaults. */ signal(SIGALRM, hungtty); alarm(2); /* alarm(1) might return too soon */ if (! setjmp(env)) { tty = open ("/dev/tty", O_RDWR, 0); alarm(0); } else { tty_got_hung = True; tty = -1; errno = ENXIO; } signal(SIGALRM, SIG_DFL); /* * Check results and ignore current control terminal if * necessary. ENXIO is what is normally returned if there is * no controlling terminal, but some systems (e.g. SunOS 4.0) * seem to return EIO. */ if (tty < 0) { DBG("Problem with tty.") if (tty_got_hung || errno == ENXIO || errno == EIO || errno == ENOTTY) { no_dev_tty = TRUE;#ifdef TIOCSLTC ltc = d_ltc;#endif /* TIOCSLTC */#ifdef TIOCLSET lmode = d_lmode;#endif /* TIOCLSET */#ifdef USE_SYSV_TERMIO tio = d_tio;#else /* not USE_SYSV_TERMIO */ sg = d_sg; tc = d_tc; discipline = d_disipline;#ifdef sony jmode = d_jmode; jtc = d_jtc;#endif /* sony */#endif /* USE_SYSV_TERMIO */ } else { SysError(ERROR_OPDEVTTY); } } else { /* Get a copy of the current terminal's state, * if we can. Some systems (e.g., SVR4 and MacII) * may not have a controlling terminal at this point * if started directly from xdm or xinit, * in which case we just use the defaults as above. */#ifdef TIOCSLTC if(ioctl(tty, TIOCGLTC, <c) == -1) ltc = d_ltc;#endif /* TIOCSLTC */#ifdef TIOCLSET if(ioctl(tty, TIOCLGET, &lmode) == -1) lmode = d_lmode;#endif /* TIOCLSET */#ifdef USE_SYSV_TERMIO if(ioctl(tty, TCGETA, &tio) == -1) tio = d_tio;#else /* not USE_SYSV_TERMIO */ if(ioctl(tty, TIOCGETP, (char *)&sg) == -1) sg = d_sg; if(ioctl(tty, TIOCGETC, (char *)&tc) == -1) tc = d_tc; if(ioctl(tty, TIOCGETD, (char *)&discipline) == -1) discipline = d_disipline;#ifdef sony if(ioctl(tty, TIOCKGET, (char *)&jmode) == -1) jmode = d_jmode; if(ioctl(tty, TIOCKGETC, (char *)&jtc) == -1) jtc = d_jtc;#endif /* sony */#endif /* USE_SYSV_TERMIO */ close (tty); /* tty is no longer an open fd! */ tty = -1; }#ifdef PUCC_PTYD if(-1 == (screen->respond = openrpty(ttydev, ptydev, (resource.utmpInhibit ? OPTY_NOP : OPTY_LOGIN), getuid(), XDisplayString(screen->display)))) {#else /* not PUCC_PTYD */ if (get_pty (&screen->respond)) {#endif /* PUCC_PTYD */ /* no ptys! */ (void) fprintf(stderr, "%s: no available ptys\n", xterm_name); exit (ERROR_PTYS);#ifdef PUCC_PTYD }#else } /* keep braces balanced for emacs */#endif#ifdef PUCC_PTYD else { /* * set the fd of the master in a global var so * we can undo all this on exit * */ Ptyfd = screen->respond; }#endif /* PUCC_PTYD */ } /* avoid double MapWindow requests */ XtSetMappedWhenManaged( screen->TekEmu ? XtParent(tekWidget) : XtParent(term), False ); wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", False); if (!screen->TekEmu) VTInit(); /* realize now so know window size for tty driver */#ifdef TIOCCONS if (Console) { /* * Inform any running xconsole program * that we are going to steal the console. */ XmuGetHostname (mit_console_name + MIT_CONSOLE_LEN, 255); mit_console = XInternAtom(screen->display, mit_console_name, False); /* the user told us to be the console, so we can use CurrentTime */ XtOwnSelection(screen->TekEmu ? XtParent(tekWidget) : XtParent(term), mit_console, CurrentTime, ConvertConsoleSelection, NULL, NULL); }#endif if(screen->TekEmu) { envnew = tekterm; ptr = newtc; } else { envnew = vtterm; ptr = termcap; } TermName = NULL; if (resource.term_name) { if (tgetent (ptr, resource.term_name) == 1) { TermName = resource.term_name; if (!screen->TekEmu) resize (screen, TermName, termcap, newtc); } else { fprintf (stderr, "%s: invalid termcap entry \"%s\".\n", ProgramName, resource.term_name); } } if (!TermName) { while (*envnew != NULL) { if(tgetent(ptr, *envnew) == 1) { TermName = *envnew; if(!screen->TekEmu) resize(screen, TermName, termcap, newtc); break; } envnew++; } if (TermName == NULL) { fprintf (stderr, "%s: unable to find usable termcap entry.\n", ProgramName); Exit (1); } }#ifdef sun#ifdef TIOCSSIZE /* tell tty how big window is */ if(screen->TekEmu) { ts.ts_lines = 38; ts.ts_cols = 81; } else { ts.ts_lines = screen->max_row + 1; ts.ts_cols = screen->max_col + 1; }#endif /* TIOCSSIZE */#else /* not sun */#ifdef TIOCSWINSZ /* tell tty how big window is */ if(screen->TekEmu) { ws.ws_row = 38; ws.ws_col = 81; ws.ws_xpixel = TFullWidth(screen); ws.ws_ypixel = TFullHeight(screen); } else { ws.ws_row = screen->max_row + 1; ws.ws_col = screen->max_col + 1; ws.ws_xpixel = FullWidth(screen); ws.ws_ypixel = FullHeight(screen); }#endif /* TIOCSWINSZ */#endif /* sun */ if (!am_slave) {#ifdef USE_HANDSHAKE if (pipe(pc_pipe) || pipe(cp_pipe)) SysError (ERROR_FORK);#endif if ((screen->pid = fork ()) == -1) SysError (ERROR_FORK); if (screen->pid == 0) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -