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