Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site boring.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!mcvax!boring!guido From: guido@boring.UUCP Newsgroups: net.sources.mac Subject: Re: uw - multi-window tty emulator Message-ID: <6538@boring.UUCP> Date: Mon, 29-Jul-85 00:40:12 EDT Article-I.D.: boring.6538 Posted: Mon Jul 29 00:40:12 1985 Date-Received: Tue, 30-Jul-85 06:34:32 EDT References: <2718@mordor.UUCP> Reply-To: guido@mcvax.UUCP (Guido van Rossum) Distribution: net Organization: "Stamp Out BASIC" Committee, CWI, Amsterdam Lines: 283 Summary: A fix to make finding pseudo-ttys more successful Apparently-To: rnews@mcvax.LOCAL Here's a fix which may greatly enhance the usability of John Bruner's fine "uw" program. It turs out that on our system (and maybe on yours!), the fact that the master part of a pty can be opened, gives absolutely no guarantee that the slave part is equally willing. Therefore this fix will open the slave in the parent process and continue searching for a pty when this fails. It also searches the series of pty's with names /dev/pty[qrs][0-9a-f] which were ignored by the original program. Happy macing, Guido van Rossum, CWI, Amsterdam guido@mcvax --------------------------------- cut here ------------------------------------ *** uw.c.orig Sun Jul 21 18:11:31 1985 --- uw.c Sun Jul 28 22:04:48 1985 *************** *** 387,393 * hand us a terminal session running under their uid....] */ buf[cnt] = 0; ! if (strncmp(buf, "/dev/ptyp", sizeof "/dev/ptyp" - 1) || fstat(fd, &st1) < 0 || stat(buf, &st2) < 0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { (void)close(fd); --- 387,393 ----- * hand us a terminal session running under their uid....] */ buf[cnt] = 0; ! if (strncmp(buf, "/dev/pty", sizeof "/dev/pty" - 1) || fstat(fd, &st1) < 0 || stat(buf, &st2) < 0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { (void)close(fd); *************** *** 510,517 newwind(w) register struct window *w; { ! register char *cp; ! register fildes_t fd; register int pid; register char *shell; char pty[32], ptysufx[2]; --- 510,517 ----- newwind(w) register struct window *w; { ! register char *cpmajor, *cp; ! register fildes_t fd, fd2; register int pid; register char *shell; char pty[32], ptysufx[3]; *************** *** 514,520 register fildes_t fd; register int pid; register char *shell; ! char pty[32], ptysufx[2]; static char ptyidx[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static int unity = 1; extern char *getenv(); --- 514,521 ----- register fildes_t fd, fd2; register int pid; register char *shell; ! char pty[32], ptysufx[3]; ! static char ptyidmajor[] = "pqrs"; static char ptyidx[] = "0123456789abcdefghijklmnopqrstuvwxyz"; static int unity = 1; extern char *getenv(); *************** *** 521,527 /* * Create a new window using the specified component of "window". ! * This routine isn't very smart at finding pseudo-ttys. */ ptysufx[1] = '\0'; --- 522,534 ----- /* * Create a new window using the specified component of "window". ! * This routine tries to be smart at finding pseudo-ttys: ! * it tries all of /dev/pty[p-s][0-9a-z] until it finds one ! * that can be opened AND whose slave end can be opened. ! * (The latter is necessary because we often suffer from pty's ! * whose slave end is still busy while the master has been ! * closed; the slave ends are usually open exclusively ! * so another open would fail.) */ ptysufx[2] = '\0'; *************** *** 524,533 * This routine isn't very smart at finding pseudo-ttys. */ ! ptysufx[1] = '\0'; ! for (cp=ptyidx; *cp; cp++) { ! ptysufx[0] = *cp; ! (void)strncpy(pty, "/dev/ptyp", sizeof pty-1); (void)strncat(pty, ptysufx, sizeof pty-1); if ((fd = open(pty, 2)) >= 0) break; --- 531,542 ----- * so another open would fail.) */ ! ptysufx[2] = '\0'; ! for (cpmajor=ptyidmajor; *cpmajor; ++cpmajor) { ! ptysufx[0]= *cpmajor; ! for (cp=ptyidx; *cp; cp++) { ! ptysufx[1] = *cp; ! (void)strncpy(pty, "/dev/pty", sizeof pty-1); (void)strncat(pty, ptysufx, sizeof pty-1); if ((fd = open(pty, 2)) >= 0) { /* Now check slave end. */ *************** *** 529,535 ptysufx[0] = *cp; (void)strncpy(pty, "/dev/ptyp", sizeof pty-1); (void)strncat(pty, ptysufx, sizeof pty-1); ! if ((fd = open(pty, 2)) >= 0) break; } if (fd < 0) --- 538,560 ----- ptysufx[1] = *cp; (void)strncpy(pty, "/dev/pty", sizeof pty-1); (void)strncat(pty, ptysufx, sizeof pty-1); ! if ((fd = open(pty, 2)) >= 0) { ! /* Now check slave end. */ ! (void)strncpy(w->w_tty, "/dev/tty", sizeof w->w_tty-1); ! (void)strncat(w->w_tty, ptysufx, sizeof w->w_tty-1); ! if ((fd2 = open(w->w_tty, 2)) < 0) { ! close(fd); ! continue; /* Bad luck, try another. */ ! } ! goto found_one; ! } ! /* ! * If a file really isn't there, don't check the rest of ! * this major series. This avoids trying to open 48 ! * nonexistent pty's when the system is configured with ! * only 16 instead of the expected 64. ! */ ! if (errno == ENOENT) break; } } *************** *** 531,536 (void)strncat(pty, ptysufx, sizeof pty-1); if ((fd = open(pty, 2)) >= 0) break; } if (fd < 0) return(-1); --- 556,562 ----- */ if (errno == ENOENT) break; + } } return(-1); *************** *** 532,539 if ((fd = open(pty, 2)) >= 0) break; } ! if (fd < 0) ! return(-1); (void)ioctl(fd, FIONBIO, &unity); /* set non-blocking I/O */ fdmap[fd] = w; w->w_fd = fd; --- 558,566 ----- break; } } ! return(-1); ! ! found_one: (void)ioctl(fd, FIONBIO, &unity); /* set non-blocking I/O */ fdmap[fd] = w; w->w_fd = fd; *************** *** 538,545 fdmap[fd] = w; w->w_fd = fd; selmask[0].sm_rd |= (1<w_tty, "/dev/ttyp", sizeof w->w_tty-1); - (void)strncat(w->w_tty, ptysufx, sizeof w->w_tty-1); while ((pid=fork()) < 0) sleep(5); --- 565,570 ----- fdmap[fd] = w; w->w_fd = fd; selmask[0].sm_rd |= (1<w_tty, "/dev/ttyp", sizeof w->w_tty-1); (void)strncat(w->w_tty, ptysufx, sizeof w->w_tty-1); ! while ((pid=fork()) < 0) sleep(5); if (!pid) { (void)signal(SIGHUP, SIG_DFL); --- 566,572 ----- w->w_fd = fd; selmask[0].sm_rd |= (1<w_tty, 2)) < 0) - _exit(1); if (!(shell = getenv("SHELL"))) shell = "/bin/sh"; (void)dup2(fd, 0); --- 577,582 ----- (void)signal(SIGCHLD, SIG_DFL); (void)ioctl(open("/dev/tty", 2), (int)TIOCNOTTY, (char *)0); (void)setuid(getuid()); /* shouldn't need this */ if (!(shell = getenv("SHELL"))) shell = "/bin/sh"; (void)dup2(fd2, 0); *************** *** 556,562 _exit(1); if (!(shell = getenv("SHELL"))) shell = "/bin/sh"; ! (void)dup2(fd, 0); (void)dup2(0, 1); (void)dup2(0, 2); for (fd=3; fd < NFDS; fd++) --- 579,585 ----- (void)setuid(getuid()); /* shouldn't need this */ if (!(shell = getenv("SHELL"))) shell = "/bin/sh"; ! (void)dup2(fd2, 0); (void)dup2(0, 1); (void)dup2(0, 2); for (fd=3; fd < NFDS; fd++) *************** *** 566,571 _exit(1); } return(0); } --- 589,595 ----- _exit(1); } + close(fd2); return(0); }