nonblockingstdin.c (1463B)
1 #include <fcntl.h> 2 #include <unistd.h> 3 #include <sys/select.h> 4 5 static void 6 readstdin(void) 7 { 8 static size_t max = 0; 9 static struct item **end = &items; 10 11 char buf[sizeof text], *p, *maxstr; 12 struct item *item; 13 14 #if PASSWORD_PATCH 15 if (passwd) { 16 inputw = lines = 0; 17 return; 18 } 19 #endif // PASSWORD_PATCH 20 21 /* read each line from stdin and add it to the item list */ 22 while (fgets(buf, sizeof buf, stdin)) { 23 if (!(item = malloc(sizeof *item))) 24 die("cannot malloc %u bytes:", sizeof *item); 25 if ((p = strchr(buf, '\n'))) 26 *p = '\0'; 27 if (!(item->text = strdup(buf))) 28 die("cannot strdup %u bytes:", strlen(buf)+1); 29 if (strlen(item->text) > max) { 30 max = strlen(maxstr = item->text); 31 #if PANGO_PATCH 32 inputw = maxstr ? TEXTWM(maxstr) : 0; 33 #else 34 inputw = maxstr ? TEXTW(maxstr) : 0; 35 #endif // PANGO_PATCH 36 } 37 *end = item; 38 end = &item->next; 39 item->next = NULL; 40 item->out = 0; 41 } 42 match(); 43 drawmenu(); 44 } 45 46 static void 47 run(void) 48 { 49 fd_set fds; 50 int flags, xfd = XConnectionNumber(dpy); 51 52 if ((flags = fcntl(0, F_GETFL)) == -1) 53 die("cannot get stdin control flags:"); 54 if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1) 55 die("cannot set stdin control flags:"); 56 for (;;) { 57 FD_ZERO(&fds); 58 FD_SET(xfd, &fds); 59 if (!feof(stdin)) 60 FD_SET(0, &fds); 61 if (select(xfd + 1, &fds, NULL, NULL, NULL) == -1) 62 die("cannot multiplex input:"); 63 if (FD_ISSET(xfd, &fds)) 64 readevent(); 65 if (FD_ISSET(0, &fds)) 66 readstdin(); 67 } 68 }