Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: watch(1) - periodically execute a command and display its output
To:
Job Snijders <job@openbsd.org>
Cc:
tech@openbsd.org
Date:
Mon, 19 May 2025 19:01:44 -0600

Download raw body.

Thread
+               FD_ZERO(&readfds);
+               FD_SET(fileno(stdin), &readfds);
+
+               nfds = select(1, &readfds, NULL, NULL, (paused) ? NULL : &to);
+               if (nfds < 0) {

This select() use doesn't have the fd_set overflow problem.  But anyways,
it should use poll()

In this loop, the sig_atomic_t variable(s) would be inspected, to depart
cleanly from curses/terminfo configuration of the tty.  The loop doesn't
look very good, for example it has ways of terminating the process without
doing the curses/terminfo cleanup.

+                               perror("select");

I also have a bad feeling about the NULL timeout for select()

+               nfds = select(1, &readfds, NULL, NULL, (paused) ? NULL : &to);

But a rewrite for poll() will probably resolve that.  libevent can also be
used, but I think it will introduce more complexity than needed.

+                       case EINTR:
+                               /*
+                                * ncurses has changed the window size with
+                                * SIGWINCH. Call doupdate() to use the
+                                * updated window size.
+                                */
+                               doupdate();
+                               goto redraw;

I get a bad feeling about this and SIGSTOP related system calls.