Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.emacs Subject: Re: GNU Emacs hanging... Message-ID: <3908@umcp-cs.UUCP> Date: Fri, 17-Oct-86 00:53:48 EDT Article-I.D.: umcp-cs.3908 Posted: Fri Oct 17 00:53:48 1986 Date-Received: Fri, 17-Oct-86 04:05:08 EDT References: <2536@utai.UUCP> <1456@jade.BERKELEY.EDU> Organization: Computer Sci. Dept, U of Maryland, College Park, MD Lines: 707 In article <1456@jade.BERKELEY.EDU> mwm@eris.berkeley.edu (Mike Meyer) writes: >Ditto, except for more data points: > >rlogged in from either a Sun-3 any of a 4.[23] 750, a 4.3beta 8600, a >4.3 8600, or an Ultrix 2.0beta 8800. Also from a uvax ][ to either a >4.2 750 or a 4.3beta 8600. I cannot quite parse that, but I gather the problem shows when running rlogin within a window, whenever the remote host is `fast'. >I suspect a kernel bug, myself, but would be interested to see any >solution. Rlogin bugs are more likely. The 4.2 version was thoroughly broken. The 4.3 version was significantly reworked but still not quite right. The Sun version was hopeless; I replaced it with a fixed 4.3 version. I know naught of the Ultrix rlogin. The Solution (as far as I know): Copy your 4.3 rlogin.c and your 4.3 /usr/src/lib/libc/net/rcmd.c files to your Sun or uVax-II. Apply the changes shown below to rlogin.c. Compile rlogin.c and rcmd.c to .o's, then link together and test. This requires super-user privileges (alas!). You may discover that you need to reverse the sense of the `pid' arguments to the fcntl(F_SETOWN) calls; I forget whether they work as is on the Suns. (4.2 had pid and pgrp logically reversed; `fixed in 4.3' means `incompatible with 4.2'. So it goes.) You may want to pull out the `isswitch' code. We used to use a local hack to allow remote logins without local accounts, by adding /etc/passwd entries of the form imladris::20:199:& Switch:/tmp:/usr/ucb/rswtch Logging in as `imladris' (ah, the name evokes such memories) would send you over to my Sun-3/50, where you would then be asked for a login name and password. We now have a different local hack; I just log in as `chris@imladris' if I wish. Anyway, here are the fixes for a 4.3 rlogin.c. Do not be concerned by the size: I fixed all the lint fluff, and reworked some of the Sun-specific window code for readability. *** /x/chris/4.3tape/src/ucb/rlogin.c Sun Mar 30 19:39:06 1986 --- rlogin.c Thu Aug 7 02:24:40 1986 *************** *** 22,25 **** --- 22,27 ---- #include #include + #include + #include #include *************** *** 38,42 **** # endif TIOCPKT_WINDOW ! char *index(), *rindex(), *malloc(), *getenv(); struct passwd *getpwuid(); char *name; --- 40,49 ---- # endif TIOCPKT_WINDOW ! /* concession to sun */ ! # ifndef SIGUSR1 ! # define SIGUSR1 30 ! # endif SIGUSR1 ! ! char *index(), *rindex(), *malloc(), *getenv(), *strcat(), *strcpy(); struct passwd *getpwuid(); char *name; *************** *** 43,46 **** --- 50,54 ---- int rem; char cmdchar = '~'; + int isswitch; int eight; int litout; *************** *** 56,60 **** #endif #ifdef sun - struct ttysize winsize; struct winsize { unsigned short ws_row, ws_col; --- 64,67 ---- *************** *** 61,69 **** unsigned short ws_xpixel, ws_ypixel; }; - #else sun - struct winsize winsize; #endif sun int sigwinch(), oob(); main(argc, argv) int argc; --- 68,101 ---- unsigned short ws_xpixel, ws_ypixel; }; #endif sun + struct winsize winsize; int sigwinch(), oob(); + /* + * The following routine provides compatibility (such as it is) + * between 4.2BSD Suns and others. Suns have only a `ttysize', + * so we convert it to a winsize. + */ + #ifdef sun + int + get_window_size(fd, wp) + int fd; + struct winsize *wp; + { + struct ttysize ts; + int error; + + if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0) + return (error); + wp->ws_row = ts.ts_lines; + wp->ws_col = ts.ts_cols; + wp->ws_xpixel = 0; + wp->ws_ypixel = 0; + return (0); + } + #else sun + #define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp) + #endif sun + main(argc, argv) int argc; *************** *** 85,88 **** --- 117,143 ---- if (!strcmp(host, "rlogin")) host = *argv++, --argc; + else if (!strcmp(host, "rswtch")) { + printf("You really don't want to run this.\n"); + exit(1); + } else if (argc == 0 && host[0] == '-') { + static char namebuf[128]; + char *getlogin(); + + /* + * This is a hack. If you log in with "rswtch" as + * your shell, we assume you really want to remotely + * log in to some other host. This disables commands + * and makes us prompt for a login name. + */ + if ((host = getlogin()) == NULL) { + printf("Oops - getlogin\n"); + exit(1); + } + isswitch++; + (void) printf("Remote login name: "); + (void) fflush(stdout); + (void) gets(namebuf); + name = namebuf; + } another: if (argc > 0 && !strcmp(*argv, "-d")) { *************** *** 117,124 **** if (argc > 0) goto usage; ! pwd = getpwuid(getuid()); ! if (pwd == 0) { ! fprintf(stderr, "Who are you?\n"); ! exit(1); } sp = getservbyname("login", "tcp"); --- 172,181 ---- if (argc > 0) goto usage; ! if (!isswitch) { ! pwd = getpwuid(getuid()); ! if (pwd == 0) { ! fprintf(stderr, "Who are you?\n"); ! exit(1); ! } } sp = getservbyname("login", "tcp"); *************** *** 129,146 **** cp = getenv("TERM"); if (cp) ! strcpy(term, cp); if (ioctl(0, TIOCGETP, &ttyb) == 0) { ! strcat(term, "/"); ! strcat(term, speeds[ttyb.sg_ospeed]); } ! #ifdef sun ! (void) ioctl(0, TIOCGSIZE, &winsize); ! #else sun ! (void) ioctl(0, TIOCGWINSZ, &winsize); ! #endif sun ! signal(SIGPIPE, lostpeer); ! signal(SIGURG, oob); ! oldmask = sigblock(sigmask(SIGURG)); ! rem = rcmd(&host, sp->s_port, pwd->pw_name, name ? name : pwd->pw_name, term, 0); if (rem < 0) --- 186,199 ---- cp = getenv("TERM"); if (cp) ! (void) strcpy(term, cp); if (ioctl(0, TIOCGETP, &ttyb) == 0) { ! (void) strcat(term, "/"); ! (void) strcat(term, speeds[ttyb.sg_ospeed]); } ! (void) get_window_size(0, &winsize); ! (void) signal(SIGPIPE, lostpeer); ! /* will use SIGUSR1 for window size hack, so hold it off */ ! oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1)); ! rem = rcmd(&host, sp->s_port, isswitch ? "anybody" : pwd->pw_name, name ? name : pwd->pw_name, term, 0); if (rem < 0) *************** *** 166,170 **** int child; int catchild(); ! int writeroob(); int defflags, tabflag; --- 219,223 ---- int child; int catchild(); ! int copytochild(), writeroob(); int defflags, tabflag; *************** *** 181,185 **** struct sgttyb sb; ! ioctl(0, TIOCGETP, (char *)&sb); defflags = sb.sg_flags; tabflag = defflags & TBDELAY; --- 234,238 ---- struct sgttyb sb; ! (void) ioctl(0, TIOCGETP, (char *)&sb); defflags = sb.sg_flags; tabflag = defflags & TBDELAY; *************** *** 187,198 **** deferase = sb.sg_erase; defkill = sb.sg_kill; ! ioctl(0, TIOCLGET, (char *)&deflflags); ! ioctl(0, TIOCGETC, (char *)&deftc); notc.t_startc = deftc.t_startc; notc.t_stopc = deftc.t_stopc; ! ioctl(0, TIOCGLTC, (char *)&defltc); ! signal(SIGINT, SIG_IGN); ! signal(SIGHUP, exit); ! signal(SIGQUIT, exit); child = fork(); if (child == -1) { --- 240,251 ---- deferase = sb.sg_erase; defkill = sb.sg_kill; ! (void) ioctl(0, TIOCLGET, (char *)&deflflags); ! (void) ioctl(0, TIOCGETC, (char *)&deftc); notc.t_startc = deftc.t_startc; notc.t_stopc = deftc.t_stopc; ! (void) ioctl(0, TIOCGLTC, (char *)&defltc); ! (void) signal(SIGINT, SIG_IGN); ! setsignal(SIGHUP, exit); ! setsignal(SIGQUIT, exit); child = fork(); if (child == -1) { *************** *** 202,207 **** if (child == 0) { mode(1); ! sigsetmask(oldmask); ! if (reader() == 0) { prf("Connection closed."); exit(0); --- 255,259 ---- if (child == 0) { mode(1); ! if (reader(oldmask) == 0) { prf("Connection closed."); exit(0); *************** *** 211,217 **** exit(3); } ! signal(SIGURG, writeroob); ! sigsetmask(oldmask); ! signal(SIGCHLD, catchild); writer(); prf("Closed connection."); --- 263,277 ---- exit(3); } ! ! /* ! * We may still own the socket, and may have a pending SIGURG ! * (or might receive one soon) that we really want to send to ! * the reader. Set a trap that simply copies such signals to ! * the child. ! */ ! (void) signal(SIGURG, copytochild); ! (void) signal(SIGUSR1, writeroob); ! (void) sigsetmask(oldmask); ! (void) signal(SIGCHLD, catchild); writer(); prf("Closed connection."); *************** *** 219,229 **** } done(status) int status; { mode(0); ! if (child > 0 && kill(child, SIGKILL) >= 0) ! wait((int *)0); exit(status); } --- 279,308 ---- } + /* + * Trap a signal, unless it is being ignored. + */ + setsignal(sig, act) + int sig, (*act)(); + { + int omask = sigblock(sigmask(sig)); + + if (signal(sig, act) == SIG_IGN) + (void) signal(sig, SIG_IGN); + (void) sigsetmask(omask); + } + done(status) int status; { + int w; mode(0); ! if (child > 0) { ! /* make sure catchild does not snap it up */ ! (void) signal(SIGCHLD, SIG_DFL); ! if (kill(child, SIGKILL) >= 0) ! while ((w = wait((union wait *)0)) > 0 && w != child) ! /*void*/; ! } exit(status); } *************** *** 230,233 **** --- 309,321 ---- /* + * Copy SIGURGs to the child process. + */ + copytochild() + { + + (void) kill(child, SIGURG); + } + + /* * This is called when the reader process gets the out-of-band (urgent) * request to turn on the window-changing protocol. *************** *** 238,242 **** if (dosigwinch == 0) { sendwindow(); ! signal(SIGWINCH, sigwinch); } dosigwinch = 1; --- 326,330 ---- if (dosigwinch == 0) { sendwindow(); ! (void) signal(SIGWINCH, sigwinch); } dosigwinch = 1; *************** *** 249,253 **** again: ! pid = wait3(&status, WNOHANG|WUNTRACED, 0); if (pid == 0) return; --- 337,341 ---- again: ! pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0); if (pid == 0) return; *************** *** 256,260 **** */ if (pid < 0 || pid == child && !WIFSTOPPED(status)) ! done(status.w_termsig | status.w_retcode); goto again; } --- 344,348 ---- */ if (pid < 0 || pid == child && !WIFSTOPPED(status)) ! done((int)(status.w_termsig | status.w_retcode)); goto again; } *************** *** 290,294 **** if (bol) { bol = 0; ! if (c == cmdchar) { bol = 0; local = 1; --- 378,382 ---- if (bol) { bol = 0; ! if (!isswitch && c == cmdchar) { bol = 0; local = 1; *************** *** 308,312 **** } if (c != cmdchar) ! write(rem, &cmdchar, 1); } if (write(rem, &c, 1) == 0) { --- 396,400 ---- } if (c != cmdchar) ! (void) write(rem, &cmdchar, 1); } if (write(rem, &c, 1) == 0) { *************** *** 338,342 **** *p++ = '\r'; *p++ = '\n'; ! write(1, buf, p - buf); } --- 426,430 ---- *p++ = '\r'; *p++ = '\n'; ! (void) write(1, buf, p - buf); } *************** *** 345,351 **** { mode(0); ! signal(SIGCHLD, SIG_IGN); ! kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); ! signal(SIGCHLD, catchild); mode(1); sigwinch(); /* check for size changes */ --- 433,439 ---- { mode(0); ! (void) signal(SIGCHLD, SIG_IGN); ! (void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); ! (void) signal(SIGCHLD, catchild); mode(1); sigwinch(); /* check for size changes */ *************** *** 352,373 **** } - #ifdef sun sigwinch() { - struct ttysize ws; - - if (dosigwinch && ioctl(0, TIOCGSIZE, &ws) == 0 && - bcmp(&ws, &winsize, sizeof (ws))) { - winsize = ws; - sendwindow(); - } - } - - #else sun - sigwinch() - { struct winsize ws; ! if (dosigwinch && ioctl(0, TIOCGWINSZ, &ws) == 0 && bcmp(&ws, &winsize, sizeof (ws))) { winsize = ws; --- 440,448 ---- } sigwinch() { struct winsize ws; ! if (dosigwinch && get_window_size(0, &ws) == 0 && bcmp(&ws, &winsize, sizeof (ws))) { winsize = ws; *************** *** 375,379 **** } } - #endif /* --- 450,453 ---- *************** *** 389,398 **** obuf[2] = 's'; obuf[3] = 's'; - #ifdef sun - wp->ws_row = htons(winsize.ts_lines); - wp->ws_col = htons(winsize.ts_cols); - wp->ws_xpixel = 0; - wp->ws_ypixel = 0; - #else sun wp->ws_row = htons(winsize.ws_row); wp->ws_col = htons(winsize.ws_col); --- 463,466 ---- *************** *** 399,403 **** wp->ws_xpixel = htons(winsize.ws_xpixel); wp->ws_ypixel = htons(winsize.ws_ypixel); - #endif sun (void) write(rem, obuf, sizeof(obuf)); } --- 467,470 ---- *************** *** 409,413 **** #define WRITING 2 ! char rcvbuf[8 * 1024]; int rcvcnt; int rcvstate; --- 476,480 ---- #define WRITING 2 ! char rcvbuf[32 * 1024]; int rcvcnt; int rcvstate; *************** *** 452,477 **** * Let server know about window size changes */ ! kill(ppid, SIGURG); } if (!eight && (mark & TIOCPKT_NOSTOP)) { ! ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~CBREAK; sb.sg_flags |= RAW; ! ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = -1; notc.t_startc = -1; ! ioctl(0, TIOCSETC, (char *)¬c); } if (!eight && (mark & TIOCPKT_DOSTOP)) { ! ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~RAW; sb.sg_flags |= CBREAK; ! ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = deftc.t_stopc; notc.t_startc = deftc.t_startc; ! ioctl(0, TIOCSETC, (char *)¬c); } if (mark & TIOCPKT_FLUSHWRITE) { ! ioctl(1, TIOCFLUSH, (char *)&out); for (;;) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) { --- 519,544 ---- * Let server know about window size changes */ ! (void) kill(ppid, SIGUSR1); } if (!eight && (mark & TIOCPKT_NOSTOP)) { ! (void) ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~CBREAK; sb.sg_flags |= RAW; ! (void) ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = -1; notc.t_startc = -1; ! (void) ioctl(0, TIOCSETC, (char *)¬c); } if (!eight && (mark & TIOCPKT_DOSTOP)) { ! (void) ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~RAW; sb.sg_flags |= CBREAK; ! (void) ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = deftc.t_stopc; notc.t_startc = deftc.t_startc; ! (void) ioctl(0, TIOCSETC, (char *)¬c); } if (mark & TIOCPKT_FLUSHWRITE) { ! (void) ioctl(1, TIOCFLUSH, (char *)&out); for (;;) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) { *************** *** 495,499 **** --- 562,571 ---- longjmp(rcvtop, 1); } + /* + * oob does not do FLUSHREAD (alas!) + */ + + /* * If we filled the receive buffer while a read was pending, * longjmp to the top to restart appropriately. Don't abort *************** *** 507,511 **** * reader: read from remote: line -> 1 */ ! reader() { #if !defined(BSD) || BSD < 43 --- 579,584 ---- * reader: read from remote: line -> 1 */ ! reader(oldmask) ! int oldmask; { #if !defined(BSD) || BSD < 43 *************** *** 517,524 **** char *bufp = rcvbuf; ! signal(SIGTTOU, SIG_IGN); ! fcntl(rem, F_SETOWN, pid); ppid = getppid(); (void) setjmp(rcvtop); for (;;) { while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { --- 590,599 ---- char *bufp = rcvbuf; ! (void) signal(SIGTTOU, SIG_IGN); ! (void) signal(SIGURG, oob); ppid = getppid(); + (void) fcntl(rem, F_SETOWN, pid); (void) setjmp(rcvtop); + (void) sigsetmask(oldmask); for (;;) { while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { *************** *** 554,559 **** int lflags; ! ioctl(0, TIOCGETP, (char *)&sb); ! ioctl(0, TIOCLGET, (char *)&lflags); switch (f) { --- 629,634 ---- int lflags; ! (void) ioctl(0, TIOCGETP, (char *)&sb); ! (void) ioctl(0, TIOCLGET, (char *)&lflags); switch (f) { *************** *** 584,591 **** return; } ! ioctl(0, TIOCSLTC, (char *)ltc); ! ioctl(0, TIOCSETC, (char *)tc); ! ioctl(0, TIOCSETN, (char *)&sb); ! ioctl(0, TIOCLSET, (char *)&lflags); } --- 659,666 ---- return; } ! (void) ioctl(0, TIOCSLTC, (char *)ltc); ! (void) ioctl(0, TIOCSETC, (char *)tc); ! (void) ioctl(0, TIOCSETN, (char *)&sb); ! (void) ioctl(0, TIOCLSET, (char *)&lflags); } *************** *** 594,597 **** --- 669,673 ---- char *f; { + fprintf(stderr, f, a1, a2, a3, a4, a5); fprintf(stderr, CRLF); *************** *** 600,604 **** lostpeer() { ! signal(SIGPIPE, SIG_IGN); prf("\007Connection closed."); done(1); --- 676,681 ---- lostpeer() { ! ! (void) signal(SIGPIPE, SIG_IGN); prf("\007Connection closed."); done(1); -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu