https://gitlab.synchro.net/main/sbbs/-/commit/d98f0eaeb863ee3093720750
Modified Files:
src/xpdev/genwrap.c
Log Message:
xp_popen(), xp_pipe_open(): the child inherits only its standard handles
On Windows, both ran their command with plain handle inheritance, which
gives the child every inheritable handle open anywhere in the process at
that moment, including each file another thread has fopen()ed. The child
then holds those files open until it exits, so the owning thread's
remove() after fclose() fails with a sharing violation.
Symptom: the FTP server packing a QWK packet at the same moment another
server thread ran a command (most likely the web server's "lsar", via system.popen() in filecontents_lib.js, for an archive view):
!ERROR 13 (Permission denied) (WinError 32) in pack_qwk.cpp line 660
(sbbs_t::pack_qwk) removing ".../PERSONAL.NDX"
Name the standard handles in a PROC_THREAD_ATTRIBUTE_HANDLE_LIST so that nothing else is inherited. Where that isn't available (pre-Vista headers, Borland) or is refused, the command runs with plain inheritance as before.
xp_system() is unchanged: services.cpp relies on it to pass a native
service its socket.
Introduced with xp_popen() in 5de72e0995 (2026-09-20) and with
xp_pipe_open() in 17981f079f (2026-09-20).
Co-Authored-By: Claude Fable 5.2 <
noreply@anthropic.com>
---
þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net