⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttysw_init.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -