diff -r c596c060aedb dmenu.c --- a/dmenu.c Sun Jan 08 13:13:00 2012 +0100 +++ b/dmenu.c Wed Jan 11 11:53:07 2012 +0100 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -466,20 +467,59 @@ void readstdin(void) { char buf[sizeof text], *p, *maxstr = NULL; - size_t i, max = 0, size = 0; + size_t i = 0, max = 0, size = 0; - /* read each line from stdin and add it to the item list */ - for(i = 0; fgets(buf, sizeof buf, stdin); i++) { - if(i+1 >= size / sizeof *items) - if(!(items = realloc(items, (size += BUFSIZ)))) - eprintf("cannot realloc %u bytes:", size); - if((p = strchr(buf, '\n'))) - *p = '\0'; - if(!(items[i].text = strdup(buf))) - eprintf("cannot strdup %u bytes:", strlen(buf)+1); - if(strlen(items[i].text) > max) + fd_set set; + struct timeval timeout; + int ret, xfd; + XEvent ev; + KeySym ksym = NoSymbol; + + xfd = ConnectionNumber(dc->dpy); + + while (!feof(stdin)) { + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + FD_ZERO(&set); + FD_SET(STDIN_FILENO, &set); + FD_SET(xfd, &set); + + if ((ret = select(xfd + 1, &set, NULL, NULL, &timeout)) < 0) { + if (errno == EINTR) + continue; + eprintf("select(): %s", strerror(errno)); + } + + /* exit dmenu on XK_Escape or Ctrl-C */ + if (FD_ISSET(xfd, &set)) { + while (XPending(dc->dpy)) { + XNextEvent(dc->dpy, &ev); + + if (ev.type != KeyPress) + continue; + + ksym = XLookupKeysym(&ev.xkey, 0); + if (ksym == XK_Escape || (ev.xkey.state & ControlMask && ksym == XK_c)) + exit(EXIT_FAILURE); + } + } + + /* read a line from stdin and add it to the item list */ + else if (FD_ISSET(STDIN_FILENO, &set) && fgets(buf, sizeof buf, stdin)) { + if(i+1 >= size / sizeof *items) + if(!(items = realloc(items, (size += BUFSIZ)))) + eprintf("cannot realloc %u bytes:", size); + if((p = strchr(buf, '\n'))) + *p = '\0'; + if(!(items[i].text = strdup(buf))) + eprintf("cannot strdup %u bytes:", strlen(buf)+1); + if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); + i++; + } } + if(items) items[i].text = NULL; inputw = maxstr ? textw(dc, maxstr) : 0;