https://gitlab.synchro.net/main/sbbs/-/commit/800c8b09317e30a0868a4d10
Added Files:
src/sftp/sftp_outcome.c
Modified Files:
src/sbbs3/main.cpp sftp.cpp src/sftp/sftp.c sftp.h sftp_client.c sftp_server.c src/syncterm/sftp_browser.c sftp_queue.c ssh.c
Log Message:
sftp: replace last_error TLS hack with sftp{c,s}_outcome
The pthread_key_t TLS for sftpc_get_err was removed for portability in 2710c20e54, but that exposed a real race the TLS had been masking: the
three SyncTERM user threads (browser, uploader, downloader) sharing one sftpc_state_t can clobber each other's last_error between op return
and sftpc_get_err call.
Reshape the API so per-op state lives in caller-supplied storage and
shared scalar state on the connection goes away. New
struct sftp{c,s}_outcome carries:
- err code (sftp_err_code_t -- flat enum of specific lib failure
modes; SFTP_ERR_OK on success), valid when op returns false
- result code (SSH_FX_* from server reply, client-side only),
valid when op returns true
- estr text accumulator with file:line prefixes per record, plus
server-supplied SSH_FXP_STATUS messages as `Reply: "..."` lines
Bool contract:
true - op completed; act on result. err/estr are diagnostic only.
false - op didn't complete; result undefined. Switch on err for
retry decisions; show estr to the user.
Stack-allocated via SFTPC_OUTCOME_DECL(name, textsz) /
SFTPS_OUTCOME_DECL macros. Pass NULL for "don't care", or sz=0 for
"codes but no text". A single internal outcome_record_impl backs both
public record entry points so formatting/accumulation lives in one
place. sftpc_outcome_reply formats server-supplied SSH_FXP_STATUS
text as `Reply: "msg" (lang)` lines, distinguishable from
file:line-prefixed lib-internal records.
Server side gets sftps_outcome too (no result field -- server supplies
the SSH_FX_* code rather than receiving it). Threading covers
sftps_recv, sftps_send_packet/error/handle/data/name/attrs/extended_reply
and the static dispatch helpers. sbbs3/main.cpp's sftps_recv sites
get real outcomes that log via lprintf on failure; sbbs3/sftp.cpp's
~100 sftps_send_* sites pass nullptr for now (existing lprintf
plumbing in the lib already logs the immediate context).
SyncTERM consumers (ssh.c, sftp_browser.c, sftp_queue.c) take real
outcomes. The queue worker uses sftp_err_is_transient() to choose
between SFTP_JOB_QUEUED (retryable) and SFTP_JOB_FAILED for op-level
failures. ssh.c's SSH_FX_EOF handling correctly lives on the
post-true branch.
set_thread_err / get_thread_err / sftpc_get_err / state->last_error
all gone.
Co-Authored-By: Claude Opus 4.7 (1M context) <
[email protected]>
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)