Change select(2) to kevent(2) on script(1)...

From: Norikatsu Shigemura <nork_at_FreeBSD.org>
Date: Sun, 21 Dec 2008 01:27:52 +0900
Hi Ed!

	I inspired by your 'kqueue()-support to pseudo-terminal master
	devices' (svn commit: r185942).  So I'm trying to use kevent(2)
	on script(1). (SEE ALSO following patch)

	But it doesn't work.  Because 'master' file descriptor (from
	openpty(3)) doesn't return last 0 byte data readable when shell
	exit.  In this case of select(2), 'master' file descriptor
	gets 0 byte data and exit script(1).

	Do you have any idea?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--- usr.bin/script/script.c.orig	2004-02-16 02:30:13.000000000 +0900
+++ usr.bin/script/script.c	2008-12-21 00:59:59.929804968 +0900
_at__at_ -49,6 +49,7 _at__at_
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/event.h>
 #include <sys/time.h>
 
 #include <err.h>
_at__at_ -85,11 +86,12 _at__at_
 	struct termios rtt, stt;
 	struct winsize win;
 	int aflg, kflg, ch, n;
-	struct timeval tv, *tvp;
+	struct timespec ts, *tsp;
 	time_t tvec, start;
 	char obuf[BUFSIZ];
 	char ibuf[BUFSIZ];
-	fd_set rfd;
+	int kq;
+	struct kevent kev[2];
 	int flushtime = 30;
 
 	aflg = kflg = 0;
_at__at_ -160,23 +162,29 _at__at_
 		doshell(argv);
 
 	if (flushtime > 0)
-		tvp = &tv;
+		tsp = &ts;
 	else
-		tvp = NULL;
+		tsp = NULL;
 
 	start = time(0);
-	FD_ZERO(&rfd);
+
+	if ((kq = kqueue()) < 0)
+		err(1, "kqueue");
+
+	EV_SET(&kev[0], master,       EVFILT_READ, EV_ADD, 0, 0, NULL);
+	EV_SET(&kev[1], STDIN_FILENO, EVFILT_READ, EV_ADD, 0, 0, NULL);
+	if (kevent(kq, kev, 2, NULL, 0, NULL) < 0)
+		err(1, "kevent");
+
 	for (;;) {
-		FD_SET(master, &rfd);
-		FD_SET(STDIN_FILENO, &rfd);
 		if (flushtime > 0) {
-			tv.tv_sec = flushtime;
-			tv.tv_usec = 0;
+			ts.tv_sec = flushtime;
+			ts.tv_nsec = 0;
 		}
-		n = select(master + 1, &rfd, 0, 0, tvp);
+		n = kevent(kq, NULL, 0, kev, 1, tsp);
 		if (n < 0 && errno != EINTR)
 			break;
-		if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) {
+		if (n > 0 && kev[0].ident == STDIN_FILENO) {
 			cc = read(STDIN_FILENO, ibuf, BUFSIZ);
 			if (cc < 0)
 				break;
_at__at_ -190,7 +198,7 _at__at_
 				}
 			}
 		}
-		if (n > 0 && FD_ISSET(master, &rfd)) {
+		if (n > 0 && kev[0].ident == master) {
 			cc = read(master, obuf, sizeof (obuf));
 			if (cc <= 0)
 				break;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Received on Sat Dec 20 2008 - 15:27:54 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:39 UTC