Hi,

I rewrote my proposal with select(). Now readstdin() will return if it
cannot read data from stdin during more than 1 u_sec. It will set the
static flag 'eof' to 1 if it has read the end of file character. This
way while eof is 0, you know you should call readstdin() again.

Attached is a patch that you can also pull from
https://bitbucket.org/chmduquesne/dmenu
diff -r a79e4a9cb167 dmenu.c
--- a/dmenu.c	Sat Nov 20 09:25:08 2010 +0000
+++ b/dmenu.c	Mon Nov 29 01:14:46 2010 +0100
@@ -10,6 +10,8 @@
 #ifdef XINERAMA
 #include <X11/extensions/Xinerama.h>
 #endif
+#include <sys/time.h>
+#include <sys/types.h>
 #include "draw.h"
 
 #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
@@ -44,6 +46,7 @@
 static int lines = 0;
 static int monitor = -1;
 static int promptw;
+static int eof = 0;
 static size_t cursor = 0;
 static const char *font = NULL;
 static const char *prompt = NULL;
@@ -59,6 +62,7 @@
 static Item *items = NULL;
 static Item *matches, *sel;
 static Item *prev, *curr, *next;
+static Item **end = &items;
 static Window root, win;
 
 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -432,26 +436,44 @@
 
 void
 readstdin(void) {
+	fd_set rfds;
+	struct timeval tv;
+	int canread;
 	char buf[sizeof text], *p;
-	Item *item, **end;
+	Item *item;
 
-	for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
-		if((p = strchr(buf, '\n')))
-			*p = '\0';
-		if(!(item = malloc(sizeof *item)))
-			eprintf("cannot malloc %u bytes\n", sizeof *item);
-		if(!(item->text = strdup(buf)))
-			eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
-		item->next = item->left = item->right = NULL;
-		inputw = MAX(inputw, textw(dc, item->text));
-	}
+	do {
+		tv.tv_sec = 0;
+		tv.tv_usec = 1;
+		FD_ZERO(&rfds);
+		FD_SET(0, &rfds);
+		canread = select(1, &rfds, NULL, NULL, &tv);
+		if(canread == -1)
+			perror("select()");
+		if(canread) {
+			eof = (fgets(buf, sizeof buf, stdin) == NULL);
+			if(!eof) {
+				if((p = strchr(buf, '\n')))
+					*p = '\0';
+				if(!(item = malloc(sizeof *item)))
+					eprintf("cannot malloc %u bytes\n", sizeof *item);
+				if(!(item->text = strdup(buf)))
+					eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
+				item->next = item->left = item->right = NULL;
+				inputw = MAX(inputw, textw(dc, item->text));
+
+				*end = item;
+				end = &item->next;
+			}
+		}
+	} while(canread && !eof);
 }
 
 void
 run(void) {
 	XEvent ev;
 
-	while(!XNextEvent(dc->dpy, &ev))
+	while(!XNextEvent(dc->dpy, &ev)) {
 		switch(ev.type) {
 		case Expose:
 			if(ev.xexpose.count == 0)
@@ -469,6 +491,9 @@
 				XRaiseWindow(dc->dpy, win);
 			break;
 		}
+		if (!eof)
+			readstdin();
+	}
 }
 
 void

Reply via email to