Article View: net.emacs
Article #2134Re: GNU Emacs hanging...
From: Chris Torek
Date: Fri, 17 Oct 1986 04:53
Date: Fri, 17 Oct 1986 04:53
707 lines
17934 bytes
17934 bytes
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 <sys/file.h>
#include <sys/socket.h>
+ #include <sys/time.h>
+ #include <sys/resource.h>
#include <sys/wait.h>
***************
*** 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
Technical Details
Message-ID:
<3908@umcp-cs.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!umcp-cs!chrisReferences:
<2536@utai.UUCP> <1456@jade.BERKELEY.EDU>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!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