On Tue, Dec 12, 2023 at 08:30:02PM -0500, Thomas Dickey wrote: > On Wed, Dec 13, 2023 at 01:33:59AM +0100, наб wrote: > > On Tue, Dec 12, 2023 at 05:55:38PM -0500, Thomas Dickey wrote: > > > On Tue, Dec 12, 2023 at 11:09:13PM +0100, наб wrote: > > > > urlview 1c-1 whose xterm was killed but which didn't die consumes 100% > > > > CPU. > > > > The event loop is for(;;) switch(getch()) ... and ignores -1 > > > If it's going to ignore the error return (while at the same time > > > manipulating the time delays with mousemask), then this is expected > > > (mis)behavior. > > Sure. > > > > Still, it doesn't set errno to EINTR, > ...and the manual page does not say it would do that. > > It lists three possible causes for ERR being returned, > and on the third it mentions that errno will be set: > returns ERR if the window pointer is null, or if its timeout > expires without having any data, or if the execution was interrupted by > a signal (errno will be set to EINTR). > > It could be reformatted like this without changing its meaning: > returns ERR > * if the window pointer is null, or > * if its timeout expires without having any data, or > * if the execution was interrupted by a signal (errno will be set to > EINTR). That, to me, wasn't clear from the page itself. "any data (errno unchanged)" would make it so.
> > and instant empty reads you get from a hung-up teletype > > definitely aren't exceeding the timeout. > > https://git.sr.ht/~nabijaczleweli/urlview-ng/tree/1c/item/urlview.c#L441 > > mouseinterval(0) tells it to not wait for mouse events, Well, mouseinterval(3curses) says Use mouseinterval(0) to disable click resolution. which is different from "not wait for mouse events". > That looks like someone's attempting to make the wheel mouse work at > infinite velocity The mouse wheel is checked-for with BUTTON[45]_PRESSED, so click resolution doesn't factor in here at all. I picked mouseinterval(0) because the default 166 value is completely unusable. Clearly it doesn't actually disable click resolution either. htop uses mouseinterval(0) as well. Regardless of the mouseinterval argument I can click-hold-release for however long I want, so long as I don't move the cursor too much and it registers. With the default value it just sleeps after I release. In addition to my usual X teletype (st(1)), this also happens with xterm(1) under both X configs I have, so with it being under the dickey umbrella as well, that clearly indicates that something's wrong to me. This is also the case under gpm, on a 2002 Celeron laptop. (And under X on that one as well.) > I'd have used a 5msec delay (or 1msec for "modern" computers :-) So is this a UI design choice or is it a VT-compat choice? What's the point of this function, why does it not just correctly associate clicks with clicks? Or, rather, why do you need mouseinterval(0) to correctly associate clicks with clicks, without "clearly broken" levels of delay? Why do you suggest any delay at all? Why 5ms or 1ms? When is this (supposedly) needed? What does computer recency have to do with it, and why is that notion dispelled on the oldest piece of shit I have? Why is none of this documented? > -- and might be the reason for ignoring errors -- Mouse support is new, errors are ignored in 0.7 from 1997, so no. > and might be the reason for the 100% CPU. This all also happens with mouse and keypad disabled altogether, so this is all moot. > If ncurses is actually reading from a closed file descriptor, the manpage > for read(2) suggests that errno may be set to EBADF ..? It isn't, and I never said it did. It reads from a valid fd, which corresponds to a hanged-up tty. This is a consistent thoroughline. > -- but since you say > errno is _not_ being set, then there's nothing to alert ncurses to the > problem -- the timeout expired. There is no time-out: > (You may get more insight using strace). The straces you got both indicate that ncurses' first (only) read returns empty, and any time-out isn't even attempted. You can tell because they both say read(0, "", 1) = 0 exclusively, and neither of them have a poll. Indeed, the only time the mouse timeout is attempted is /after/ a mouse button down/up is read. There is another 1s poll timeout, which happens after reading an ESC. Again, neither of those are attempted. Similarly, they all end up in fifo_push() with 340 n = (int) read(sp->_ifd, &c2, (size_t) 1); ... 347 if ((n == -1) || (n == 0)) { 348 TR(TRACE_IEVENT, ("read(%d,&ch,1)=%d, errno=%d", sp->_ifd, n, errno)); 349 ch = ERR; 350 } from (in the no-timeout case) _nc_wgetch() 596 } else { 597 if (head == -1) 598 fifo_push(sp EVENTLIST_2nd(evl)); 599 ch = fifo_pull(sp); 600 } 601 602 if (ch == ERR) { ... 620 returnCode(ERR); again, no sleeps or timeouts or delays or intervals in this. Consulting with the illumos-gate curses (usr/src/lib/libcurses/screen/tgetch.c), it looks like it does the same thing, and also doesn't document it, so presumably switch(errno = 0, getch()) { case ERR: if(errno == EINTR) continue; else if(errno) err(1, "getch()"); else done = true; break; } is fine.
signature.asc
Description: PGP signature