Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/rlogin PR/54435: Adjust for new kernel behavior of s...



details:   https://anonhg.NetBSD.org/src/rev/9b045ca8ff40
branches:  trunk
changeset: 932263:9b045ca8ff40
user:      christos <christos%NetBSD.org@localhost>
date:      Sun May 03 16:32:16 2020 +0000

description:
PR/54435: Adjust for new kernel behavior of soreceive(9) clearing MSG_OOB
when receiving the oob message. This made SIOCATMARK return always 0 since
the oob message was cleared. Instead, use recvmsg(2) to determine if
the message was oob or not. This works with both the old and new kernel
and it is not racy.

diffstat:

 usr.bin/rlogin/rlogin.c |  38 ++++++++++++++++++++++++--------------
 1 files changed, 24 insertions(+), 14 deletions(-)

diffs (82 lines):

diff -r 403dd200813f -r 9b045ca8ff40 usr.bin/rlogin/rlogin.c
--- a/usr.bin/rlogin/rlogin.c   Sun May 03 16:11:06 2020 +0000
+++ b/usr.bin/rlogin/rlogin.c   Sun May 03 16:32:16 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rlogin.c,v 1.46 2020/05/03 16:11:06 christos Exp $     */
+/*     $NetBSD: rlogin.c,v 1.47 2020/05/03 16:32:16 christos Exp $     */
 
 /*
  * Copyright (c) 1983, 1990, 1993
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)rlogin.c   8.4 (Berkeley) 4/29/95";
 #else
-__RCSID("$NetBSD: rlogin.c,v 1.46 2020/05/03 16:11:06 christos Exp $");
+__RCSID("$NetBSD: rlogin.c,v 1.47 2020/05/03 16:32:16 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -577,16 +577,34 @@
 static ssize_t rcvcnt, rcvstate;
 static char rcvbuf[8 * 1024];
 
+static int
+recvx(int fd, void *buf, size_t len, int flags, int *msgflags)
+{
+       struct msghdr msg;
+       struct iovec iov;
+       int error;
+
+       memset(&msg, 0, sizeof(msg));
+       msg.msg_iov = &iov;
+       iov.iov_base = buf;
+       iov.iov_len = len;
+       error = recvmsg(fd, &msg, flags);
+       if (error)
+               return error;
+       *msgflags = msg.msg_flags;
+       return 0;
+}
+
 static void
 oob(int signo)
 {
        struct termios tty;
-       int atmark;
+       int atmark = 0;
        ssize_t n, rcvd;
        char waste[BUFSIZ], mark;
 
        rcvd = 0;
-       while (recv(rem, &mark, 1, MSG_OOB) == -1) {
+       while (recvx(rem, &mark, 1, MSG_OOB, &atmark) == -1) {
                switch (errno) {
                case EWOULDBLOCK:
                        /*
@@ -610,6 +628,7 @@
                        return;
                }
        }
+       atmark &= MSG_OOB;
        if (mark & TIOCPKT_WINDOW) {
                /* Let server know about window size changes */
                (void)kill(ppid, SIGUSR1);
@@ -626,17 +645,8 @@
        }
        if (mark & TIOCPKT_FLUSHWRITE) {
                (void)tcflush(1, TCIOFLUSH);
-               for (;;) {
-                       if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
-                               warn("ioctl SIOCATMARK (ignored)");
-                               break;
-                       }
-                       if (atmark)
-                               break;
+               if (!atmark)
                        n = read(rem, waste, sizeof (waste));
-                       if (n <= 0)
-                               break;
-               }
                /*
                 * Don't want any pending data to be output, so clear the recv
                 * buffer.  If we were hanging on a write when interrupted,



Home | Main Index | Thread Index | Old Index