dmenu

Kris's build of dmenu
git clone git clone https://git.krisyotam.com/krisyotam/dmenu.git
Log | Files | Refs | README | LICENSE

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 }