hedrick@geneva.rutgers.edu (Charles Hedrick) (11/19/89)
>About a third of the time I suspend emacs and then go back in, the >Meta keys don't work (I can still use ESC) and ^S and ^Q are trapped. >If I suspend emacs again, a stty command tells me that decctlq is on. >And when I go back into emacs, everything is OK again. This is a bug in the BSD socket code. The problem is that rlogin relies on "urgent data" to change the terminal mode on the remote host. If urgent data happens to arrive while the kernel is processing previous data, it can be lost. What happens is that there is a loop over data that has already arrived, giving it to the process that is reading it. If urgent data happens to arrive while you are in that loop, the loop will continue past it. At that point the data is regarded as out of date, and will not be ignored by the ioctl that asks for urgent data. This normally shows up only when you rlogin to a machine that is very much faster than your local one. It's pretty clear why that should be. The problem depends upon a second packet arriving while the first one is still being processed, and that's obviously more likely when the machine doing the processing is relatively slow. We first saw it with Sun 3/50's logged into Pyramids. The following fix is from our SunOS 4.0.1 source. I'm fairly sure you could use the same fix in 4.0.3 and 4.0.3c. I believe the fix has to be in the local machine, i.e. your Sun 3/80. This diff is for uipc_socket.c. It has been reported to Berkeley, Sun, and Pyramid, but long enough ago that I'm pretty sure that if they were going to accept it, they would have done so already. So you should probably report it to Sun yourself. *** /tmp/geta635 Sat Nov 18 17:36:30 1989 --- /tmp/getb635 Sat Nov 18 17:36:31 1989 *************** *** 436,441 **** --- 436,444 ---- struct mbuf *nextrecord; int moff; + /* RU 29 - need procp for test of SIGURG. see below */ + register struct proc *p = u.u_procp; + if (rightsp) *rightsp = 0; if (aname) *************** *** 568,575 **** } } moff = 0; ! tomark = so->so_oobmark; while (m && uio->uio_resid > 0 && error == 0) { if (m->m_type != MT_DATA && m->m_type != MT_HEADER) panic("receive 3"); len = uio->uio_resid; --- 571,594 ---- } } moff = 0; ! /* ! * RU 29 - move calculation of tomark into loop, so we exit ! * if push happens to arrive while we are in the loop with ! * priority lowered. Also, arrange to exit if we get SIGURG, ! * so that we don't read over the urgent data, making it ! * invalid. ! */ ! if (flags & MSG_PEEK) ! tomark = so->so_oobmark; ! if ((((p)->p_sig &~ (p)->p_sigmask) & sigmask(SIGURG)) && ! ((p)->p_flag&STRC || ! ((sigmask(SIGURG) & (p)->p_sigignore) == 0))) ! error = EINTR; ! else while (m && uio->uio_resid > 0 && error == 0) { + /* RU 29 - move tomark inside loop */ + if ((flags & MSG_PEEK) == 0) + tomark = so->so_oobmark; if (m->m_type != MT_DATA && m->m_type != MT_HEADER) panic("receive 3"); len = uio->uio_resid; *************** *** 616,621 **** --- 635,645 ---- if (tomark == 0) break; } + /* RU 29 - exit if now have a SIGURG */ + if ((((p)->p_sig &~ (p)->p_sigmask) & sigmask(SIGURG)) && + ((p)->p_flag&STRC || + ((sigmask(SIGURG) & (p)->p_sigignore) == 0))) + break; } if ((flags & MSG_PEEK) == 0) { if (m == 0)