From: iain.lea@anl433.erlm.siemens.de (Iain Lea) Subject: Re: rlogin problems: Sun<->Linux Date: 28 Apr 1993 07:07:38 GMT
John Paul Morrison (jmorriso@rflab.ee.ubc.ca) wrote:
:
: I'm having really annoying rlogin problems between SunOS 4.1.3 and Linux 99pl9
: the rlogind in Linux takes forever to respond to the Sun. From SunOS I can
: sit typing: rlogin linux.host & until I have around 15 rlogin attempts
: in the background, and eventually one of the *latest* rlogin attempts gets
: through
The following context diff has been working well on SLS 1.00 with a 0.99p[678].
Iain
--cut here--
o Kernel modifications:
- /usr/src/linux/net/tcp/sock.c at line 1826 in get_sock() added:
if (s->dead && (s->state == TCP_CLOSE))
continue;
o TCP/IP net-src:
- /usr/src/net-src/rlogind/rlogind.c
Just remove all the "ifndef linux" bits from rlogind.c so the OOB
handling code is re-inserted.
- /usr/src/net-src/rlogin/rlogin.c
--PATCH BEGIN--
*** rlogin.c.original Sat Mar 13 12:06:19 1993
--- rlogin.c Tue Mar 16 15:44:05 1993
***************
*** 82,89 ****
--- 82,100 ----
char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
extern char *krb_realmofhost();
#endif
+ /*
+ * rlogin has problems with urgent data when logging into suns which
+ * results in the connection being closed with an IO error. SUN_KLUDGE
+ * is a work around - the actual bug is probably in tcp.c in the kernel, but
+ * I haven't managed to find it yet.
+ * Andrew.Tridgell@anu.edu.au (12th March 1993)
+ */
+ #ifdef linux
+ #define SUN_KLUDGE
+ #endif
+
#ifndef TIOCPKT_WINDOW
#define TIOCPKT_WINDOW 0x80
#endif
***************
*** 556,563 ****
--- 567,577 ----
bcmp(&ws, &winsize, sizeof(ws))) {
winsize = ws;
sendwindow();
}
+ #ifdef SUN_KLUDGE
+ signal(SIGWINCH,sigwinch);
+ #endif
}
/*
* Send the window size to the server via the magic escape
***************
*** 596,605 ****
jmp_buf rcvtop;
int ppid, rcvcnt, rcvstate;
char rcvbuf[8 * 1024];
void
! oob()
{
struct sgttyb sb;
int atmark, n, out, rcvd;
char waste[BUFSIZ], mark;
--- 610,629 ----
jmp_buf rcvtop;
int ppid, rcvcnt, rcvstate;
char rcvbuf[8 * 1024];
+ void oob()
+ {
+ void oob_real();
+ oob_real();
+ #ifdef SUN_KLUDGE
+ signal(SIGURG,oob);
+ #endif
+ }
+
+
void
! oob_real()
{
struct sgttyb sb;
int atmark, n, out, rcvd;
char waste[BUFSIZ], mark;
***************
*** 636,644 ****
--- 660,670 ----
if (!eight && (mark & TIOCPKT_NOSTOP)) {
(void)ioctl(0, TIOCGETP, (char *)&sb);
sb.sg_flags &= ~CBREAK;
sb.sg_flags |= RAW;
+ #ifndef SUN_KLUDGE
(void)ioctl(0, TIOCSETN, (char *)&sb);
+ #endif
notc.t_stopc = -1;
notc.t_startc = -1;
(void)ioctl(0, TIOCSETC, (char *)¬c);
}
***************
*** 728,735 ****
--- 754,778 ----
else
#endif
#endif
rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
+
+ /*
+ * If we get a EIO from a read then it may mean that we have unread ungent data
+ * waiting that is getting in the way. We probably have got more then one lot of
+ * urgent data but we only got one SIGURG due to a problem in the kernel tcp.
+ * We can try and fix this by sending ourself a SIGURG and pretending the error
+ * never occurred. This might be a problem if we really _should_ be getting
+ * a EIO for some unrelated reason. (AJT 3/93)
+ */
+ #ifdef SUN_KLUDGE
+ if (rcvcnt < 0 && errno == EIO)
+ {
+ errno = 0;
+ kill(getpid(),SIGURG);
+ continue;
+ }
+ #endif
if (rcvcnt == 0)
return (0);
if (rcvcnt < 0) {
if (errno == EINTR)
***************
*** 793,800 ****
--- 836,846 ----
void
copytochild()
{
(void)kill(child, SIGURG);
+ #ifdef SUN_KLUDGE
+ signal(SIGCHLD,copytochild);
+ #endif
}
msg(str)
char *str;