-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix syscon fatal exit on ^Z #160
Conversation
Then again the least intrusive change would be to leave the signal handlers alone and just check for |
EINTR checks don't look correct. Non-blocking read() or write() should never with EINTR. How can I reproduce this? |
Note to self: it's enough to add a check for reading, writing is ok. |
Here's a repro from WSL. The issue was originally reported on a real Linux machine with the musl libc.
|
Yes, but that causes read() to fail with EIO, not EINTR. Why are you re-adding EINTR checks? They were deliberately removed in commit 9c2446a because "interrupted" non-blocking calls don't make sense. What is dummy signal handler for? Isn't checking for EIO and ignoring it enough? (I don't think pausing network-interactive application such as Q2PRO is correct behavior here.) |
It's to get a consistent errno regardless off
It's not as much pausing, but having the controlling terminal return to the shell from the q2proded process. An example of this "controlling terminal" behavior on FreeBSD:
I fully agree, but that's what the tty read returns on Linux. WSL even reproduces this braindead behavior. |
Can you explain? What kind of inconsistency? If the process is ignoring TSIGTTOU, then behavior should be identical according to the blog post you linked.
I meant that as a response to your suggestion to raise SIGSTOP in the handler. What exactly is the goal of this PR? To fix fatal error on read() when using ^Z, or implement some specific behavior regarding to handling control of the terminal? If the latter, keep in mind that once Q2PRO initializes TTY support, the terminal is no longer usable by other programs anyway (it switches to non-blocking mode which many programs don't handle). Correct way to run Q2PRO within the same login session as other programs is to use a terminal multiplexer such as screen(1) or tmux(1). |
The former. Fix braindead
Agreed, it's the kosher way. But it's a matter of robustness. |
But EINTR never happens when the process is ignoring SIGTTIN/SIGTTOU. See here and here. It's pointless to check for EINTR. The following patch, however, works for me on Linux and FreeBSD:
Can you fix the PR to contain only this change? |
0e8ef6d
to
19242ca
Compare
Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or its process group is orphaned. [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet#160 (comment)
19242ca
to
e42f16a
Compare
Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet#160 (comment)
Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet#160 (comment)
e42f16a
to
799662c
Compare
Works on my end as well! Rebased against the master branch. |
Applied, thanks. |
* Reduce TCP port probing console spam. * Convert to stdbool.h. Mostly straightforward 's/qboolean/bool' except the following. Bitfields are changed to unsigned int. Structure members, function signatures that are part of game ABI are changed to int. Savegame code has been extended with new F_BOOL type that is written/read as int so that old savegames continue to work. * Get rid of ssize_t. This is a wrong return type for functions that return negative value on error and byte count on success. Functions that take a memory buffer are never passed buffers exceeding INT_MAX bytes in size, therefore they can return a plain int. Functions that return file sizes or positions can return values exceeding INT_MAX, therefore they must return int64_t. * Get rid of qerror_t. Using separate type for error values only adds clutter. Replace with int. * Replace Q_Errno() with a macro. Macro is shorter and clearer than inline function. * Get rid of off_t. This is a tricky type with unspecified size and no standard way to print it. Replace with int64_t. * Fix error codes after certain functions failure. All these functions don't set errno on failure: fgets(), fread(), fwrite(), gzseek(). Also return more appropriate error code after gzdopen() failure. * Get rid of Q_PrintError(). * Fix invalid use of size_t. For storing file sizes and positions int64_t must be used. Use of size_t in structures should be avoided if the value stored fits into unsigned int to reduce structure size. * Simplify FS_*WriteFile(). * Use _FILE_OFFSET_BITS=64. Prefer Mingw-w64 fseeko()/ftello() emulation over _fseeki64()/_ftelli64(). * Use consistent limits for PAK/PKZ sizes and offsets. These should never exceed INT_MAX for compatibility reasons. Previously limits were inconsistent between LP64 and non-LP64 systems. * Get rid of FS_FilterFile(). It was broken due to the use of gzdopen() on file descriptor left in unclean state after high-level seek. Handle FS_FLAG_GZIP internally in FS_FOpenFile() and remove all external checks for gzip header from client and MVD code. * cleanup warnings In particular `_STRINGIFY' is defined in mingw-w64 internal headers. The underscore-prefixed names are reserved. v2: - Align macro definition - Use q_unused attribute Reported by: @skullernet * make debug info readable on LCD's I can't see the blue text ingame. * use monotonic time on Unix gettimeofday(2) is subject to arbitrary skews. v2: - Use integer width suffix for LP64. - The time.h header is already implicitly included. Reported by: @skullernet * fix build with libjpeg * fix some unchecked strncpy(3) usages Found with GCC 8 v2: Use Q_strlcpy, fix typo Reported by: @skullernet * Replace more strncpy() calls with Q_strlcpy() in game code. * Remove unused defines. * Skip getting file position when using FS_MODE_WRITE. Stream is always positioned at the beginning of the file in this case. * Don't define _FILE_OFFSET_BITS for Win32. Just use 64-suffixed functions directly. * Bring qboolean type back for game ABI compat. Technically, whether enumerated type is compatible with int is implementation defined. Therefore it can't be blindly replaced with int in game headers. * Fix edict_t structure private member type. Defined as qboolean in quake2-3.21 source, yet the value stored is float. * Clamp ‘gl_picmip’ cvar to sane range. * Remove useless declaration. * Don't use 0 where NULL is expected. * remove calls to x86/fpu.c I was able to reproduce breaking opentdm. cf. skullernet#157 * Simplify Q_vscnprintf(). * Reduce size of spawn/save field arrays. * Fix unused function warnings. * Use SSE math by default for x86 builds. This is required now since code that manipulated FPU control word was removed for good. * Link with -lrt on Linux. Fix commit 135fb77 by linking with -lrt to accomodate glibc versions before 2.17. * Fix updating configstring to prefix of original string. * Clean up degrees/radians conversions. * Use VectorLength macro in more places. * Add proper suffix to floating point constants. * Fix fire_grenade(). Scale parameter for VectorMA macro must not have side effects. * Use float variants of sqrt() and fabs(). * Avoid unneeded double precision math. * Drop connection when client outgoing reliable message overflows. Prevents netchan fatal error and server connection "getting stuck" as noticed by tojestzart in skullernet#159. * prevent tty_fatal_error on reads Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet#160 (comment) * Fix Clang warning. * Fix usage of _GNU_SOURCE. * Add -std=gnu99 option. Fixes compilation with GCC 4.3 on Debian 5. * Don't define _FILE_OFFSET_BITS. Defining this by default turned out to be the bad idea. Just use an OS with native 64-bit off_t, or define this manually if needed. * Fix time/date formatting code. Don't crash if localtime() returns NULL. Buffer content is undefined if strfime() fails and returns 0. * appease harmless compiler warnings - sine warning from newer Clang - LRESULT size mismatch from 64-bit Windows The code passes a subset of `-Wextra' on GCC 8.8.1. * reduce `developer 2' logspam I keep getting the animation debug log dozens of times each second. * move frame delays from developer=3 to 2 These only happen on connection/map change or maxfps change. * Port to MT19337 PRNG. Get rid of evil rand_byte(). Code still using rand() remains semi-broken until the following commit. * Replace remaining calls to rand() with Q_rand(). Note that return type of Q_rand() is unsigned. Add appropriate casts in cases where signed result is required. * Reduce more animation debug spam. * fix and simplify client main loop There's a case with cl_async=0 and cl_maxfps=0 such that physics run thousand times a second. This breaks down movement due to possibly `cl_maxpackets', `rate', or network bandwidth. This happens anytime the client isn't hosting the game. There's the same case with cl_async=1 but it's unreachable due to `QVF_VIDEOSYNC' not getting set anywhere. Having removed the bug and dead code, we can see that the `CL_Frame()' main loop can process several cases through the same logic if it's set up right in `CL_UpdateFrameTimes()'. - Reduce branching in the main loop. - Unify some cases that depended on stubbed code elsewhere and remove the stubs. There are more stubs that may complicate code paths elsewhere in the files that had the `VID_*' stuff stubbed. - Remove the duplicate enum elements. - Add some #define constants - `cl_maxfps 120' is really 125 Hz by virtue of rounding done in `fps_to_msec'. Adjust the value. Note that on Windows, SYNC_SLEEP_60 is inaccurate, resulting in 50 Hz rather than 60. It shouldn't be too tragic. While we could use `timeBeginPeriod()', let's leave it at that. * warn on cl_maxfps/r_maxfps rounding Due to millisecond-precision timekeeping, {cl,r}_maxfps only has few distinct actual values. Different values will round off to one of these. I don't think it's practical to expect users to know that implicit rounding behavior. It's also not practical to rework the timekeeping code from the ground up. Potentially emit the message on direct maxfps change and on startup. v2: - Prevent logspam on focus change. v3: - Prevent logspam on `developer=2'. - Remove effectively dead debug code. - In half-initialized state we may have "msec" equal to zero inside `warn_on_fps_rounding()' that needs guarding against. Happens when set during `autoexec.cfg' invocation. The same will happen when using cl_maxfps=0 for max Hz. Thanks to @skullernet for extensive review. * factor out more common parts In addition, cl_maxfps=0 w/ cl_async=1 now stands for maximum allowed Hz. * Fix invalid use of sizeof. * Avoid modulo bias when generating random numbers. Add Q_rand_uniform() function that generates random numbers modulo N, using the trick from OpenBSD implementation of arc4random_uniform(). * Avoid some float divisions. * Ensure that seek target fits into INT_MAX for FS_ZIP. Seeking is allowed when reading from uncompressed FS_ZIP entry. Ensure that file end position fits into INT_MAX, just like with FS_PAK. * Check fclose() return value when writing files. * Simplify and fix portal bits packing. Remove oversize array warning. Flag portal bits that don't fit into array as open. Remove dependency on MAX_MAP_AREAS constant. * Simplify and fix cmodel code. Properly set plane signbits in CM_InitBoxHull(). Unused currently, but this will change in the next commit. * Remove unused code and stale comments. * Use plane signbits to lookup trace offsets. * unix/tty: rename for clarity Rename `tty_io' to `tty_input' 'cause that's what it is. * allow logging data from a dumb tty on Unix Continue emitting to stdout if EOF is hit on stdin. This helps running the dedicated server from nohup(1), systemd and the like. Please note that setting `sys_console=1' on the command-line is obligatory in the event that a tty isn't attached. Launching without a tty will default to `sys_console=0' in which case nothing is read or emitted. % ./q2proded +set sys_console 1 +exec server.cfg v2: [backed out] v3: - Disable polling stdin if EOF is hit (suggested by @skullernet). - Restore original terminal settings on EOF (@skullernet) Thanks to @fishxz for additional testing. Issue: skullernet#168 * Use separate lists for ‘ignoretext’ and ‘ignorenick’. Make ignore list management cleaner. Avoid escaping special characters in nickname. Properly complete ‘unignorenick’ arguments. Permit passing literal ‘all’ string to ‘unignoretext’ and ‘unignorenick’. Also match ‘[]’ prefix before nickname. Fixes skullernet#166. * Update documentation. * Further simplify CM_SetPortalStates(). * Reduce size of bsp_lumps[] array. * Fix pointer arithmetic in BSP_ClusterVis(). * Fix loop counter type. * Remove redundant #if. * Misc changes to ‘status’ command. Increase max displayed version string length. Print help when invalid mode is specified. Document settings mode that was missing from doc/server. * Simplify network address comparsion functions. * Use macros for vector comparsions in msg code. * Make Com_FormatLocalTime() a public function. Also properly NUL-terminate result if strftime() fails. * Add support for client console timestamps. Fixes skullernet#139. * Fix Con_Dump_f(). Don't use FS_FPrintf() because console lines are not necessarily NUL-terminated. Normalize high-bit and replace special characters before writing. * Fix handling CVAR_NOSET values at startup. If CVAR_NOSET value got reset during Sys_Init(), second call to Com_AddEarlyCommands() will change it back to what was specified on command line. Don't allow that and silently ignore the change. Bug reported by sthalik (see skullernet#170). * Simplify CVAR_LATCH handling. There is no reason to keep latched string if server is not running. * Remove unused prototype. * Use VectorEmpty where appropriate, etc. * Remove dead pmove code. * Add mdfour test. * Simplify and fix mdfour implementation. Existing code was partially broken: it produced invalid result on zero size message, or whenever mdfour_update() was called multiple times to process message in chunks. * Simplify Com_BlockChecksum(). No need for endianness conversions. * Add/update some comments. * Sort commands by name. * Simplify Cmd_AddCommand(). * Use List_Remove() where appropriate. * Fix use-after-free in UI_LoadScript(). * Allow built-in menus to be overridden. Protection against override didn't work correctly anyway. * Highlight low RTT entries in server browser. Fixes skullernet#98. * Fix gi.sound() on unlinked entities. Apparently, game can legally call gi.sound() on unlinked entities such as ‘target_blaster’. Because PF_StartSound() uses entity link information for PHS, this doesn't work correctly. Revert to simple two point PHS that original Q2 employs. Change MVD_ParseSound() accordingly. Fixes skullernet#92. * Simplify SV_Multicast() and MVD_ParseMulticast(). * Merge SV_EdictIsVisible() into the only caller. * Remove trivial CM_Leaf*() macros. * Fix MSG_TRESHOLD definition. * Unify PF_PositionedSound() with PF_StartSound(). Make gi.positioned_sound() with NULL origin equivalent to gi.sound(). Error out if NULL entity is passed to gi.positioned_sound(). Make gi.sound() on SVF_NOCLIENT entities run through SV_Multicast(). In particular, this should fix sounds on invisible entities when recording MVDs. Change MVD_ParseSound() accordingly. * Don't test Prompt_AddMatch() return value. * Require C99 semantics for ‘bool’. * Misc server operator command code cleanup. Don't announce filtercmd kick reason to everyone, only print to the client. * Add cvarban and userinfoban support. * Make PF_FindIndex() error message more informative. * Use CLIENT_ACTIVE macro. * Fix CL_ClampSpeed(). Clamping to pmp.maxspeed (which is 300) is wrong, because PM_AirMove() ignores Z component of wishvel[] vector. Clamp to default (maximum) running speed, which is 400. Thanks to akorepanov for reporting this issue. * Simplify PM_AddCurrents(). * Fix indentation. * Fix CL_ClampPitch(). Properly handle angle wraparound before clamping. Fixes skullernet#173 (a long standing Q2 bug). Thanks to fishxz for test case and testing the patch. * Fix PM_ClampAngles(). Properly clamp pitch to [-89, 89] degrees. Second part of existing check is wrong because SHORT2ANGLE() returns angle in range [-180, 180). * Don't leak private cvars through userinfo. * Rewrite server message compression for uniformity. Make SV_ClientAddMessage() the only place where compression is performed. Rewrite how configstrings are compressed: instead of using Z_SYNC_FLUSH after each configstring, compress everything in one chunk, using deflateBound() to estimate how much to compress. Also compress baselines using this method. * Allow ‘log’ action for ‘addfiltercmd’. * Update documentation. * Clean up compressed UDP download code. Also don't print zlib error message on inflate() failure, print returned error code instead. Error message is not set for all error codes. * Use MSG_ReadWord() where appropriate. * Strip quotes when passing through raw command args. Strip surrounding quotes so that e.g. ‘stuffall "some long text"’ command does what users expect (sends ‘some long text’ string without quotes). * Misc fixes to cmd code. * Misc changes to cvarban/stuffcmd commands. Prevent adding the same cvarban/stuffcmd multiple times. Allow deleting stuffcmds by string match. Add raw stuffcmd string. * Add lrcon support. * Extend PF_setmodel() NULL check. * Make ‘sv_registered’ variable static. * Avoid using macro name starting with underscore. * Make ‘stuffall’ command ignore zombie clients. * Make frame.num_entities signed int. No reason to have it and associated variables unsigned. Loops using unsigned counter can be slower. * Drop unneeded memset(). * Revert "Allow built-in menus to be overridden." This reverts commit 261f9ae. Fixes skullernet#174. * Allow cursor to move one character past end of buffer. Also properly NUL terminate after memmove() when inserting a character. * Support line editing in TTY. * Support line editing in Windows console. * Fix last column edge case, revert to old cursor behavior. Revert part of commit 70350bc and implement a better fix for last column edge case in system console. * Misc system console fixes/cleanup. * Add hack for partial line output. * Hide console input after fatal error. * Allow scrolling console with keyboard. * Lazily resize input line. * Parse more ANSI escape codes. * Document line editing key bindings. * Sanitize edict_size against INT_MAX. * s/Game DLL/Game library. * Minor simplification. * Only refresh line if console width changes. * Fix scrolling info lists while refreshing servers. * Remove unused variable. * Make BFG particles INSTANT_PARTICLE. See skullernet#176. * Limit CL_TrapParticles() to 100 FPS. * Play power screen/shield hit sound only once. Fixes skullernet#175. * Allow SV_StartSound() with attenuation = 4. Some maps hard code this value, even though it causes overflow when converting to byte. Since commit 0044c01 this crashes the server. Don't crash and clamp to maximum representable value instead. Fixes skullernet#180. * Remove unused typedef. * Fix invalid use of size_t. * Log estimated client timescale. * Allow kicking clients with too high time skew. * Make timescale check period configurable.
Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet/q2pro#160 (comment)
Fix crash on USE_SYSCON=1 and q2proded detached from its controlling terminal, as per `./q2proded &'. As per the Linux manual for read(2): EIO This will happen for example when the process is in a background process group, tries to read from its controlling terminal, and either it is ignoring or blocking SIGTTIN, or [...] Thanks to @skullernet for explaining the finer aspects of SIGTTIN/SIGTTOU, and preventing this patch from becoming too crufty. cf. https://www.freebsd.org/cgi/man.cgi?query=read&sektion=2&manpath=CentOS+7.1 cf. skullernet/q2pro#160 (comment)
Master skuller sync to aqtion-alpha
I'm unsure what's the right behavior here. Maybe we should raise
SIGSTOP
in the handler? The current behavior of a fatal exit is hardly sensible however.