📄 main.c
字号:
*/ XtAppAddActions(app_con, actionProcs, XtNumber(actionProcs)); /* * fill in terminal modes */ if (resource.tty_modes) { int n = parse_tty_modes (resource.tty_modes, ttymodelist); if (n < 0) { fprintf (stderr, "%s: bad tty modes \"%s\"\n", ProgramName, resource.tty_modes); } else if (n > 0) { override_tty_modes = 1; } } xterm_name = resource.xterm_name; sunFunctionKeys = resource.sunFunctionKeys; if (strcmp(xterm_name, "-") == 0) xterm_name = "xterm"; if (resource.icon_geometry != NULL) { int scr, junk; int ix, iy; Arg args[2]; for(scr = 0; /* yyuucchh */ XtScreen(toplevel) != ScreenOfDisplay(XtDisplay(toplevel),scr); scr++); args[0].name = XtNiconX; args[1].name = XtNiconY; XGeometry(XtDisplay(toplevel), scr, resource.icon_geometry, "", 0, 0, 0, 0, 0, &ix, &iy, &junk, &junk); args[0].value = (XtArgVal) ix; args[1].value = (XtArgVal) iy; XtSetValues( toplevel, args, 2); } XtSetValues (toplevel, ourTopLevelShellArgs, number_ourTopLevelShellArgs); /* Parse the rest of the command line */ for (argc--, argv++ ; argc > 0 ; argc--, argv++) { if(**argv != '-') Syntax (*argv); switch(argv[0][1]) { case 'h': Help (); /* NOTREACHED */ case 'C':#ifdef TIOCCONS { struct stat sbuf; /* Must be owner and have read/write permission. xdm cooperates to give the console the right user. */ if ( !stat("/dev/console", &sbuf) && (sbuf.st_uid == getuid()) && !access("/dev/console", R_OK|W_OK)) { Console = TRUE; } else Console = FALSE; }#endif /* TIOCCONS */ continue; case 'S': if (sscanf(*argv + 2, "%c%c%d", passedPty, passedPty+1, &am_slave) != 3) Syntax(*argv); continue;#ifdef DEBUG case 'D': debug = TRUE; continue;#endif /* DEBUG */ case 'e': if (argc <= 1) Syntax (*argv); command_to_exec = ++argv; break; case 'j': if (!strcmp(*argv+2, "obs")) { jobs = 1; continue; } else { Syntax(*argv); }#ifdef GAPING_SECURITY_HOLE case 'n': if (!strcmp(*argv+2, "oresetuid")) { resetuid = 0; setuid(geteuid()); continue; } else { Syntax(*argv); }#endif case 'v': if (!strcmp(*argv+2, "ersion")) { fputs(VERSIONINFO, stderr); continue; } default: Syntax (*argv); } break; } XawSimpleMenuAddGlobalActions (app_con); XtRegisterGrabAction (HandlePopupMenu, True, (ButtonPressMask|ButtonReleaseMask), GrabModeAsync, GrabModeAsync); term = (XtermWidget) XtCreateManagedWidget( "vt100", xtermWidgetClass, toplevel, NULL, 0); /* this causes the initialize method to be called */ screen = &term->screen; if (screen->savelines < 0) screen->savelines = 0; term->flags = 0; if (!screen->jumpscroll) { term->flags |= SMOOTHSCROLL; update_jumpscroll(); } if (term->misc.reverseWrap) { term->flags |= REVERSEWRAP; update_reversewrap(); } if (term->misc.autoWrap) { term->flags |= WRAPAROUND; update_autowrap(); } if (term->misc.re_verse) { term->flags |= REVERSE_VIDEO; update_reversevideo(); } inhibit = 0;#ifdef ALLOWLOGGING if (term->misc.logInhibit) inhibit |= I_LOG;#endif if (term->misc.signalInhibit) inhibit |= I_SIGNAL; if (term->misc.tekInhibit) inhibit |= I_TEK; term->initflags = term->flags; if (term->misc.appcursorDefault) { term->keyboard.flags |= CURSOR_APL; update_appcursor(); } if (term->misc.appkeypadDefault) { term->keyboard.flags |= KYPD_APL; update_appkeypad(); }/* * Set title and icon name if not specified */ if (command_to_exec) { Arg args[2]; if (!resource.title) { if (command_to_exec) { resource.title = base_name (command_to_exec[0]); } /* else not reached */ } if (!resource.icon_name) resource.icon_name = resource.title; XtSetArg (args[0], XtNtitle, resource.title); XtSetArg (args[1], XtNiconName, resource.icon_name); XtSetValues (toplevel, args, 2); } if(inhibit & I_TEK) screen->TekEmu = FALSE; if(screen->TekEmu && !TekInit()) exit(ERROR_INIT);#ifdef DEBUG { /* Set up stderr properly. Opening this log file cannot be done securely by a privileged xterm process (although we try), so the debug feature is disabled by default. */ int i = -1; if(debug) { creat_as (getuid(), getgid(), "xterm.debug.log", 0666); i = open ("xterm.debug.log", O_WRONLY | O_TRUNC, 0666); } if(i >= 0) {#if defined(USE_SYSV_TERMIO) && !defined(SVR4) /* SYSV has another pointer which should be part of the ** FILE structure but is actually a seperate array. */#ifndef sgi unsigned char *old_bufend; old_bufend = (unsigned char *) _bufend(stderr);#if defined(hpux) && OSMAJORVERSION == 8 /* HP-UX version 8 broke up the int FILE._file into ** char FILE.__fileL for low order byte and ** char FILE.__fileH for high order byte and ** ** Patch by Kevin O'Conner <kevin@ctp.com> */ stderr->__fileL = (char) ((unsigned)i & 0x0FF); stderr->__fileH = (char) (((unsigned)i & 0xFF00) >> 8);#else /* stderr->_file = i; */#endif _bufend(stderr) = old_bufend;#endif#else /* USE_SYSV_TERMIO */ stderr->_file = i;#endif /* USE_SYSV_TERMIO */ /* mark this file as close on exec */ (void) fcntl(i, F_SETFD, 1); } }#endif /* DEBUG */ /* open a terminal for client */ get_terminal (); spawn (); /* Child process is out there, let's catch its termination */ if (!jobs) signal (SIGCHLD, reapchild); /* Realize procs have now been executed */ Xsocket = ConnectionNumber(screen->display); pty = screen->respond; if (am_slave) { /* Write window id so master end can read and use */ char buf[80]; buf[0] = '\0'; sprintf (buf, "%lx\n", screen->TekEmu ? XtWindow (XtParent (tekWidget)) : XtWindow (XtParent (term))); write (pty, buf, strlen (buf)); }#ifdef ALLOWLOGGING if (term->misc.log_on) { StartLog(screen); }#endif screen->inhibit = inhibit;#ifdef AIXV3 /* In AIXV3, xterms started from /dev/console have CLOCAL set. * This means we need to clear CLOCAL so that SIGHUP gets sent * to the slave-pty process when xterm exits. */ { struct termio tio; if(ioctl(pty, TCGETA, &tio) == -1) SysError(ERROR_TIOCGETP); tio.c_cflag &= ~(CLOCAL); if (ioctl (pty, TCSETA, &tio) == -1) SysError(ERROR_TIOCSETP); }#endif#ifdef USE_SYSV_TERMIO if (0 > (mode = fcntl(pty, F_GETFL, 0))) Error();#ifdef O_NDELAY mode |= O_NDELAY;#else mode |= O_NONBLOCK;#endif /* O_NDELAY */ if (fcntl(pty, F_SETFL, mode)) Error();#else /* USE_SYSV_TERMIO */ mode = 1; if (ioctl (pty, FIONBIO, (char *)&mode) == -1) SysError (ERROR_FIONBIO);#endif /* USE_SYSV_TERMIO */ pty_mask = 1 << pty; X_mask = 1 << Xsocket; Select_mask = pty_mask | X_mask; max_plus1 = (pty < Xsocket) ? (1 + Xsocket) : (1 + pty);#ifdef DEBUG if (debug) printf ("debugging on\n");#endif /* DEBUG */ XSetErrorHandler(xerror); XSetIOErrorHandler(xioerror); for( ; ; ) { if(screen->TekEmu) { TekRun(); } else VTRun(); }}char *base_name(name)char *name;{ register char *cp;#ifdef DEBUGGING fprintf(stderr, "entered base_name\n");#endif cp = rindex(name, '/'); return(cp ? cp + 1 : name);}/* This function opens up a pty master and stuffs its value into pty. * If it finds one, it returns a value of 0. If it does not find one, * it returns a value of !0. This routine is designed to be re-entrant, * so that if a pty master is found and later, we find that the slave * has problems, we can re-enter this function and get another one. */get_pty (pty) int *pty;{ #ifdef DEBUGGING fprintf(stderr, "entered get_pty\n");#endif#if defined(SYSV) && defined(SYSV386) /* The order of this code is *important*. On SYSV/386 we want to open a /dev/ttyp? first if at all possible. If none are available, then we'll try to open a /dev/pts??? device. The reason for this is because /dev/ttyp? works correctly, where as /dev/pts??? devices have a number of bugs, (won't update screen correcly, will hang -- it more or less works, but you really don't want to use it). Most importantly, for boxes of this nature, one of the major "features" is that you can emulate a 8086 by spawning off a UNIX program on 80386/80486 in v86 mode. In other words, you can spawn off multiple MS-DOS environments. On ISC the program that does this is named "vpix." The catcher is that "vpix" will *not* work with a /dev/pts??? device, will only work with a /dev/ttyp? device. Since we can open either a /dev/ttyp? or a /dev/pts??? device, the flag "IsPts" is set here so that we know which type of device we're dealing with in routine spawn(). That's the reason for the "if (IsPts)" statement in spawn(); we have two different device types which need to be handled differently. */ if (pty_search(pty) == 0) return 0;#endif /* SYSV && SYSV386 */#ifdef ATT if ((*pty = open ("/dev/ptmx", O_RDWR)) < 0) { return 1; }#if defined(SVR4) || defined(SYSV386) strcpy(ttydev, ptsname(*pty));#if defined (SYSV) && defined(SYSV386) IsPts = True;#endif#endif return 0;#else /* ATT else */#ifdef AIXV3 if ((*pty = open ("/dev/ptc", O_RDWR)) < 0) { return 1; } strcpy(ttydev, ttyname(*pty)); return 0;#endif#if defined(sgi) && OSMAJORVERSION >= 4 { char *tty_name; tty_name = _getpty (pty, O_RDWR, 0622, 0); if (tty_name == 0) return 1; strcpy (ttydev, tty_name); return 0; }#endif#ifdef __convex__ { char *pty_name, *getpty(); while ((pty_name = getpty()) != NULL) { if ((*pty = open (pty_name, O_RDWR)) >= 0) { strcpy(ptydev, pty_name); strcpy(ttydev, pty_name); ttydev[5] = 't'; return 0; } } return 1; }#endif /* __convex__ */#ifdef USE_GET_PSEUDOTTY return ((*pty = getpseudotty (&ttydev, &ptydev)) >= 0 ? 0 : 1);#else#if (defined(sgi) && OSMAJORVERSION < 4) || (defined(umips) && defined (SYSTYPE_SYSV)) { struct stat fstat_buf; *pty = open ("/dev/ptc", O_RDWR); if (*pty < 0 || (fstat (*pty, &fstat_buf)) < 0) { return(1); } sprintf (ttydev, "/dev/ttyq%d", minor(fstat_buf.st_rdev));#ifndef sgi sprintf (ptydev, "/dev/ptyq%d", minor(fstat_buf.st_rdev)); if ((*tty = open (ttydev, O_RDWR)) < 0) { close (*pty); return(1); }#endif /* !sgi */ /* got one! */ return(0); }#else /* sgi or umips */ return pty_search(pty);#endif /* sgi or umips else */#endif /* USE_GET_PSEUDOTTY else */#endif /* ATT else */}/* * Called from get_pty to iterate over likely pseudo terminals * we might allocate. Used on those systems that do not have * a functional interface for allocating a pty. * Returns 0 if found a pty, 1 if fails. */int pty_search(pty) int *pty;{ static int devindex, letter = 0;#ifdef DEBUGGING fprintf(stderr, "entered pty_search\n");#endif#ifdef CRAY for (; devindex < 256; devindex++) { sprintf (ttydev, "/dev/ttyp%03d", devindex); sprintf (ptydev, "/dev/pty/%03d", devindex); if ((*pty = open (ptydev, O_RDWR)) >= 0) { /* We need to set things up for our next entry * into this function! */ (void) devindex++; return 0; } }#else /* CRAY */#ifdef DEBUGGING fprintf(stderr, "ptydev is: '%s'", ptydev);#endif while (PTYCHAR1[letter]) { ttydev [strlen(ttydev) - 2] = ptydev [strlen(ptydev) - 2] = PTYCHAR1 [letter]; while (PTYCHAR2[devindex]) { ttydev [strlen(ttydev) - 1] = ptydev [strlen(ptydev) - 1] = PTYCHAR2 [devindex];#ifdef DEBUGGING fprintf(stderr, "Trying to open '%s'", ptydev);#endif if ((*pty = open (ptydev, O_RDWR)) >= 0) { /* We need to set things up for our next entry * into this function!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -