📄 ttysw_init.c
字号:
/* * Fork the ttysw's driving tty process. *//* ARGSUSED */intttysw_fork(ttysw0, argv, inputmask, outputmask, exceptmask) caddr_t ttysw0; char **argv; int *inputmask, *outputmask, *exceptmask;{ struct ttysubwindow *ttysw = (struct ttysubwindow *) LINT_CAST(ttysw0); *inputmask |= (1 << ttysw->ttysw_pty) | (1 << ttysw->ttysw_wfd); return (ttysw_fork_it(ttysw0, argv));}/* ARGSUSED */intttysw_fork_it(ttysw0, argv) caddr_t ttysw0; char **argv;{ struct ttysubwindow *ttysw = (struct ttysubwindow *) LINT_CAST(ttysw0); struct ttysw_createoptions opts; int pidchild; unsigned ttysw_error_sleep = 2; struct sigvec vec, ovec; register int i; ttysw->ttysw_pidchild = fork(); if (ttysw->ttysw_pidchild < 0) return (-1); if (ttysw->ttysw_pidchild) { if (((ttysw->ttysw_wfd == wfd) ? FALSE : ttysw_add_FNDELAY(wfd)) || ttysw_add_FNDELAY(ttysw->ttysw_wfd) || ttysw_add_FNDELAY(ttysw->ttysw_pty)) { perror("fcntl"); return (-1); } /* (void) signal(SIGTSTP, SIG_IGN); */ vec.sv_handler = SIG_IGN; vec.sv_mask = vec.sv_onstack = 0; sigvec(SIGTSTP, &vec, 0);#ifdef DEBUG usleep(3 << 20);#endif DEBUG return (ttysw->ttysw_pidchild); } /* (void) signal(SIGWINCH, SIG_DFL);/* we don't care about SIGWINCH's */ vec.sv_handler = SIG_DFL; vec.sv_mask = vec.sv_onstack = 0; sigvec(SIGWINCH, &vec, 0); /* * Change process group of child process (me at this point in code) so its * signal stuff doesn't affect the terminal emulator. */ pidchild = getpid(); vec.sv_handler = SIG_IGN; vec.sv_mask = vec.sv_onstack = 0; sigvec(SIGTTOU, &vec, &ovec); { /* int (*presigval) () = signal(SIGTTOU, SIG_IGN); */ if ((ioctl(ttysw->ttysw_tty, TIOCSPGRP, &pidchild)) == -1) { perror("ttysw_fork_it-TIOCSPGRP"); usleep(ttysw_error_sleep << 20); } (void) jcsetpgrp(pidchild); /* (void) signal(SIGTTOU, presigval); */ sigvec(SIGTTOU, &ovec, 0); } /* * Set up file descriptors */ (void) close(ttysw->ttysw_wfd); (void) close(ttysw->ttysw_pty); if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { int tmp_window_fd; if ((tmp_window_fd = win_get_fd((Notify_client) ttysw->ttysw_hist)) != ttysw->ttysw_wfd) (void) close(tmp_window_fd); if ((tmp_window_fd = win_get_fd((Notify_client) ttysw)) != ttysw->ttysw_wfd) (void) close(tmp_window_fd); } (void) dup2(ttysw->ttysw_tty, 0); (void) dup2(ttysw->ttysw_tty, 1); (void) dup2(ttysw->ttysw_tty, 2); (void) close(ttysw->ttysw_tty);/* i = getdtablesize(); while (--i > 2) (void) close(i);*/ if (*argv == (char *) NULL || strcmp("-c", *argv) == 0) { /* Process arg list */ int argc; for (argc = 0; argv[argc]; argc++); ttysw_parseargs(&opts, &argc, argv); argv = opts.argv; } execvp(*argv, argv); perror(*argv); /* Wait a few seconds so that message can be read on ttysw */ usleep(ttysw_error_sleep << 20); exit(1); /* NOTREACHED */}/* * Create options calls */ttysw_parseargs(opts, argcptr, argv) struct ttysw_createoptions *opts; int *argcptr; char **argv;{ char *shell; int argc = *argcptr; char **args = argv; bzero((caddr_t) opts, sizeof (*opts)); /* Get options */ while (argc > 0) { if (strcmp(argv[0], "-C") == 0 || strcmp(argv[0], "CONSOLE") == 0) { opts->becomeconsole = 1; (void)cmdline_scrunch(argcptr, argv); } else argv++; argc--; } argv = args; opts->argv = opts->args; /* Determine what shell to run. */ shell = getenv("SHELL"); if (!shell || !*shell) shell = "/bin/sh"; opts->args[0] = shell; /* Setup remainder of arguments */ if (*argv == (char *) NULL) { opts->args[1] = (char *) NULL;#ifndef someday /* this should go away */ } else if (strcmp("-c", *argv) == 0) { /* * The '-c' flag tells the shell to run following arg */ opts->args[1] = *argv; (void)cmdline_scrunch(argcptr, argv); opts->args[2] = *(argv); (void)cmdline_scrunch(argcptr, argv); opts->args[3] = (char *) NULL;#endif } else { /* * Run program not under shell */ opts->argv = argv; } return;}/* * Make ttysw the console. */ttysw_becomeconsole(ttysw0) caddr_t ttysw0;{ struct ttysubwindow *ttysw = (struct ttysubwindow *) LINT_CAST(ttysw0); if ((ioctl(ttysw->ttysw_tty, TIOCCONS, 0)) == -1) perror("ttysw-TIOCCONS");}/* * Ttysw cleanup. */ttysw_done(ttysw0) caddr_t ttysw0;{ struct ttysubwindow *ttysw = (struct ttysubwindow *) LINT_CAST(ttysw0); if (ttysw->ttysw_ttyslot) (void) updateutmp("", ttysw->ttysw_ttyslot, ttysw->ttysw_tty); if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { (void)winCleanup(); ttysel_destroy(ttysw); } if (ttysw->ttysw_menu) menu_destroy(ttysw->ttysw_menu); if (ttysw->ttysw_pty) close(ttysw->ttysw_pty); if (ttysw->ttysw_tty) close(ttysw->ttysw_tty); free((char *) ttysw);}/* * Set TERM and TERMCAP environment variables. */static voidttysw_setenv(ttysw) Ttysw *ttysw;{ char *termcap; static char *cmd_termcap = "sun-cmd:te=\\E[>4h:ti=\\E[>4l:tc=sun:"; static char *cmd_term = "sun-cmd"; if (!ttysw->ttysw_hist) return; setenv("TERM", cmd_term); termcap = getenv("TERMCAP"); if (termcap && *termcap == '/') return; setenv("TERMCAP", cmd_termcap);}/* * Do tty/pty setup */intttyinit(ttysw_client) Ttysubwindow ttysw_client;{ int tt, tmpfd, ptynum = 0; int pty = 0, tty = 0; int on = 1; char linebuf[20], *line = &linebuf[0]; char *ptyp = "pqrstuvwxyzPQRST"; struct stat stb; Ttysw *ttysw; ttysw = (Ttysw *)(LINT_CAST(ttysw_client)); ttysw_setenv(ttysw); /* * find unopened pty */needpty: while (*ptyp) { (void) strcpy(line, "/dev/ptyXX"); line[strlen("/dev/pty")] = *ptyp; line[strlen("/dev/ptyp")] = '0'; if (stat(line, &stb) < 0) break; while(ptynum < 16) { line[strlen("/dev/ptyp")] = "0123456789abcdef"[ptynum]; pty = open(line, 2); if (pty > 0) goto gotpty; ptynum++; } ptyp++; ptynum = 0; } (void) fprintf(stderr, "All pty's in use\n"); return (-1); /* NOTREACHED */gotpty: line[strlen("/dev/")] = 't'; tt = open("/dev/tty", 2); if (tt > 0) { (void) ioctl(tt, TIOCNOTTY, 0); (void) close(tt); } tty = open(line, 2); if (tty < 0) { ptynum++; (void) close(pty); goto needpty; }#define WE_TTYPARMS "WINDOW_TTYPARMS" if (ttysw_restoreparms(tty)) (void)unsetenv(WE_TTYPARMS); /* * Copy stdin. Set stdin to tty so ttyslot in updateutmp will think this * is the control terminal. Restore state. Note: ttyslot should have * companion ttyslotf(fd). */ tmpfd = dup(0); (void) close(0); (void) dup(tty); ttysw->ttysw_ttyslot = updateutmp((char *) 0, 0, tty); (void) close(0); (void) dup(tmpfd); (void) close(tmpfd); ttysw->ttysw_tty = tty; ttysw->ttysw_pty = pty; (void)ttysw_mapsetim(ttysw); /* in cmdsw, set input masks for textsw */ if (ttysw_getopt((caddr_t)ttysw, TTYOPT_TEXT)) { (void) ioctl(ttysw->ttysw_tty, TIOCGETP, &cmdsw->sgttyb); (void) ioctl(ttysw->ttysw_tty, TIOCGETC, &cmdsw->tchars); (void) ioctl(ttysw->ttysw_tty, TIOCGLTC, &cmdsw->ltchars); (void) ioctl(ttysw->ttysw_pty, TIOCREMOTE, &on); } if (ioctl(ttysw->ttysw_pty, TIOCTCNTL, &on) == -1) { perror("TTYSW - setting TIOCTCNTL to 1 failed"); } return (0);}/* * Make entry in /etc/utmp for ttyfd. Note: this is dubious usage of /etc/utmp * but many programs (e.g. sccs) look there when determining who is logged in * to the pty. */intupdateutmp(username, ttyslotuse, ttyfd) char *username; int ttyslotuse, ttyfd;{ /* * Update /etc/utmp */ struct utmp utmp; struct passwd *passwdent; extern struct passwd *getpwuid(); int f; char *ttyn; extern char *ttyname(), *rindex(); if (!username) { /* * Get login name */ if ((passwdent = getpwuid(getuid())) == (struct passwd *) NULL) { (void) fprintf(stderr, "couldn't find user name\n"); return (0); } username = passwdent->pw_name; } utmp.ut_name[0] = '\0'; /* Set incase *username is 0 */ (void) strncpy(utmp.ut_name, username, sizeof (utmp.ut_name)); /* * Get line (tty) name */ ttyn = ttyname(ttyfd); if (ttyn == (char *) NULL) ttyn = "/dev/tty??"; (void) strncpy(utmp.ut_line, rindex(ttyn, '/') + 1, sizeof (utmp.ut_line)); /* * Set host to be empty */ (void) strncpy(utmp.ut_host, "", sizeof (utmp.ut_host)); /* * Get start time */ (void) time((time_t *) (&utmp.ut_time)); /* * Put utmp in /etc/utmp */ if (ttyslotuse == 0) ttyslotuse = ttyslot(); if (TTYSLOT_NOTFOUND(ttyslotuse)) { (void) fprintf(stderr, "Cannot find slot in /etc/ttys for updating /etc/utmp.\n"); (void) fprintf(stderr, "Commands like \"who\" will not work.\n"); (void) fprintf(stderr, "Add tty[qrs][0-f] to /etc/ttys file.\n"); return (0); } if ((f = open("/etc/utmp", 1)) >= 0) { (void) lseek(f, (long) (ttyslotuse * sizeof (utmp)), 0); (void) write(f, (char *) &utmp, sizeof (utmp)); (void) close(f); } else { (void) fprintf(stderr, "make sure that you can write /etc/utmp!\n"); return (0); } return (ttyslotuse);}/* Pkg_private */voidttysw_tty_restore (fd)int fd;{ struct sigvec vec, ovec; unsigned ttysw_error_sleep = 2; int pgrp = getpgrp(getpid()); vec.sv_handler = SIG_IGN; vec.sv_mask = vec.sv_onstack = 0; sigvec(SIGTTOU, &vec, &ovec); if ((ioctl(fd, TIOCSPGRP, &pgrp)) == -1) { perror("ttysw_tty_restore-TIOCSPGRP"); usleep(ttysw_error_sleep << 20); } sigvec(SIGTTOU, &ovec, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -