Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Dec 2008 01:27:52 +0900
From:      Norikatsu Shigemura <nork@FreeBSD.org>
To:        Ed Schouten <ed@FreeBSD.org>
Cc:        freebsd-current@FreeBSD.org, Norikatsu Shigemura <nork@FreeBSD.org>
Subject:   Change select(2) to kevent(2) on script(1)...
Message-ID:  <20081221012752.cdc5cbfc.nork@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
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
@@ -49,6 +49,7 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/event.h>
 #include <sys/time.h>
 
 #include <err.h>
@@ -85,11 +86,12 @@
 	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;
@@ -160,23 +162,29 @@
 		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;
@@ -190,7 +198,7 @@
 				}
 			}
 		}
-		if (n > 0 && FD_ISSET(master, &rfd)) {
+		if (n > 0 && kev[0].ident == master) {
 			cc = read(master, obuf, sizeof (obuf));
 			if (cc <= 0)
 				break;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081221012752.cdc5cbfc.nork>