https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1032276
If the quakespasm server is run noninteractively with stdin redirected from /dev/null (for example as a systemd service), it spams the system log with "Console input too long!".
This appears to be because it ignores EOF and errors from read(), and instead assumes that exactly one character was read, repeatedly appending an uninitialized character from the stack to the console buffer until the buffer is full.
Patch to follow.
Patch attached, seems to work well.
I seem to have missed this one: sorry for the late reply.
I never ran qs that way. So: con_eof is static means it won't ever process
any more input after hitting con_eof, but the way qs is ran console input
is not wanted anyway?
Simon McVittie doesn't seem to be responding. Steven, Eric: Can you guys
review?
"So: con_eof is static means it won't ever process
any more input after hitting con_eof, but the way qs is ran console input
is not wanted anyway?" - pretty much.
If stdin is not a terminal (for example /dev/null or a regular file), after you have reached EOF it will continue to poll as readable (POLLIN from poll() or readfds in select()) forever, but read() will return 0 (meaning EOF), so quakespasm will constantly try to read from it.
(Previously, quakespasm was also mishandling a read of 0 bytes (EOF) as though it was a read of 1 byte, which meant it would append 1 uninitialized byte to the buffer until it ran out of buffer; that's clearly not the intended behaviour.)
If stdin is a terminal, after you press Ctrl+D it will report "end of file" with a 0-byte read, but I think there might be some special behaviour of terminals where the same terminal can have more than one "end of file"? But if the user has signalled end of file, it seems reasonable for quakespasm to stop reading anyway. If you do want to special-case terminals so that a 0 byte read is just ignored, then isatty() would tell you whether this is a terminal or not.
I see. How about never running the read loop if stdin isn't a tty, e.g. like the following (bits from q3 source):
If stdin is a socket or the read end of a pipe/fifo (or even a regular file for that matter), wouldn't you want to read everything from it until EOF is reached, and then stop?
Do we change stdin to a socket or a pipe/fifo when running quakespasm as a server, either normally or in a case you described like a systemd server?
It's not really up to the server author what stdin is: it's the user who runs the server that decides.
Patch applied with a minor edit. Further merged the isatty and dumb terminal detection bits.
Thanks.
Patch applied with a minor edit. Further merged the isatty and dumb terminal detection bits.
Thanks.