* Trap as many fatal signals as we can in the hope of having * the best chance to clean up utmp before termination.
* Stamp utmp (that is, tell the utmp helper process to do so), * or not.
static char *pty_init(char *host, int port, char **realhost, int nodelay){    int slavefd;    char name[FILENAME_MAX];    pid_t pid, pgrp;#ifdef BSD_PTYS    {	const char chars1[] = "pqrstuvwxyz";	const char chars2[] = "0123456789abcdef";	const char *p1, *p2;	char master_name[20];	for (p1 = chars1; *p1; p1++)	    for (p2 = chars2; *p2; p2++) {		sprintf(master_name, "/dev/pty%c%c", *p1, *p2);		pty_master_fd = open(master_name, O_RDWR);		if (pty_master_fd >= 0) {		    if (geteuid() == 0 ||			access(master_name, R_OK | W_OK) == 0)			goto got_one;		    close(pty_master_fd);		}	    }	/* If we get here, we couldn't get a tty at all. */	fprintf(stderr, "pterm: unable to open a pseudo-terminal device\n");	exit(1);	got_one:	strcpy(name, master_name);	name[5] = 't';		       /* /dev/ptyXX -> /dev/ttyXX */    }#else    pty_master_fd = open("/dev/ptmx", O_RDWR);    if (pty_master_fd < 0) {	perror("/dev/ptmx: open");	exit(1);    }    if (grantpt(pty_master_fd) < 0) {	perror("grantpt");	exit(1);    }        if (unlockpt(pty_master_fd) < 0) {	perror("unlockpt");	exit(1);    }    name[FILENAME_MAX-1] = '\0';    strncpy(name, ptsname(pty_master_fd), FILENAME_MAX-1);#endif    /*     * Set the backspace character to be whichever of ^H and ^? is     * specified by bksp_is_delete.     */    {	struct termios attrs;	tcgetattr(pty_master_fd, &attrs);	attrs.c_cc[VERASE] = cfg.bksp_is_delete ? '\177' : '\010';	tcsetattr(pty_master_fd, TCSANOW, &attrs);    }    /*     * Trap as many fatal signals as we can in the hope of having     * the best chance to clean up utmp before termination.     */    signal(SIGHUP, fatal_sig_handler);    signal(SIGINT, fatal_sig_handler);    signal(SIGQUIT, fatal_sig_handler);    signal(SIGILL, fatal_sig_handler);    signal(SIGABRT, fatal_sig_handler);    signal(SIGFPE, fatal_sig_handler);    signal(SIGPIPE, fatal_sig_handler);    signal(SIGALRM, fatal_sig_handler);    signal(SIGTERM, fatal_sig_handler);    signal(SIGSEGV, fatal_sig_handler);    signal(SIGUSR1, fatal_sig_handler);    signal(SIGUSR2, fatal_sig_handler);#ifdef SIGBUS    signal(SIGBUS, fatal_sig_handler);#endif#ifdef SIGPOLL    signal(SIGPOLL, fatal_sig_handler);#endif#ifdef SIGPROF    signal(SIGPROF, fatal_sig_handler);#endif#ifdef SIGSYS    signal(SIGSYS, fatal_sig_handler);#endif#ifdef SIGTRAP    signal(SIGTRAP, fatal_sig_handler);#endif#ifdef SIGVTALRM    signal(SIGVTALRM, fatal_sig_handler);#endif#ifdef SIGXCPU    signal(SIGXCPU, fatal_sig_handler);#endif#ifdef SIGXFSZ    signal(SIGXFSZ, fatal_sig_handler);#endif#ifdef SIGIO    signal(SIGIO, fatal_sig_handler);#endif    /* Also clean up utmp on normal exit. */    atexit(cleanup_utmp);    setup_utmp(name);    /*     * Fork and execute the command.     */    pid = fork();    if (pid < 0) {	perror("fork");	exit(1);    }    if (pid == 0) {	int i;	/*	 * We are the child.	 */	slavefd = open(name, O_RDWR);	if (slavefd < 0) {	    perror("slave pty: open");	    exit(1);	}#ifdef BSD_PTYS	/* We need to chown/chmod the /dev/ttyXX device. */	{	    struct group *gp = getgrnam("tty");	    fchown(slavefd, getuid(), gp ? gp->gr_gid : -1);	    fchmod(slavefd, 0600);	}#endif	close(pty_master_fd);	close(0);	close(1);	close(2);	fcntl(slavefd, F_SETFD, 0);    /* don't close on exec */	dup2(slavefd, 0);	dup2(slavefd, 1);	dup2(slavefd, 2);	setsid();	ioctl(slavefd, TIOCSCTTY, 1);	pgrp = getpid();	tcsetpgrp(slavefd, pgrp);	setpgrp();	close(open(name, O_WRONLY, 0));	setpgrp();	/* In case we were setgid-utmp or setuid-root, drop privs. */	setgid(getgid());	setuid(getuid());	/* Close everything _else_, for tidiness. */	for (i = 3; i < 1024; i++)	    close(i);	{	    char term_env_var[10 + sizeof(cfg.termtype)];	    sprintf(term_env_var, "TERM=%s", cfg.termtype);	    putenv(term_env_var);	}	if (pty_argv)	    execvp(pty_argv[0], pty_argv);	else {	    char *shell = getenv("SHELL");	    char *shellname;	    if (cfg.login_shell) {		char *p = strrchr(shell, '/');		shellname = smalloc(2+strlen(shell));		p = p ? p+1 : shell;		sprintf(shellname, "-%s", p);	    } else		shellname = shell;	    execl(getenv("SHELL"), shellname, NULL);	}	/*	 * If we're here, exec has gone badly foom.	 */	perror("exec");	exit(127);    } else {	close(slavefd);	pty_child_pid = pid;	pty_child_dead = FALSE;	signal(SIGCHLD, sigchld_handler);    }    return NULL;}