Process last data of failed child process

This commit is contained in:
Gerhard Rieger 2023-06-15 12:53:32 +02:00
parent 4bab097ffc
commit a0e17a813a
4 changed files with 17 additions and 2 deletions

View file

@ -13,6 +13,14 @@ Features:
The number of warnings has been reduced, e.g.removing a non existing The number of warnings has been reduced, e.g.removing a non existing
file does in most cases no longer log a warning. file does in most cases no longer log a warning.
Corrections:
When a sub process (EXEC, SYSTEM) terminated with exit code other than
0, its last sent data might have been lost depending on timing of read/
write and SIGCHLD in Socat.
Now the SIGCHLD handler does not simply terminate Socat in this case,
but remembers the failure and allows further processing.
Thanks to Luke Jones for reporting this issue.
Coding: Coding:
Introduced groups_t instead of uint32_t, for more flexibility Introduced groups_t instead of uint32_t, for more flexibility

View file

@ -399,6 +399,9 @@ int main(int argc, const char *argv[]) {
Atexit(socat_unlock); Atexit(socat_unlock);
result = socat(arg1[0], arg1[1]); result = socat(arg1[0], arg1[1]);
if (result == EXIT_SUCCESS && engine_result != EXIT_SUCCESS) {
result = engine_result; /* a signal handler reports failure */
}
Notice1("exiting with status %d", result); Notice1("exiting with status %d", result);
Exit(result); Exit(result);
return 0; /* not reached, just for gcc -Wall */ return 0; /* not reached, just for gcc -Wall */

1
xio.h
View file

@ -461,6 +461,7 @@ extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */
#define diedunknown3 (diedunknown[2]) #define diedunknown3 (diedunknown[2])
#define diedunknown4 (diedunknown[3]) #define diedunknown4 (diedunknown[3])
extern int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */ extern int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */
extern int engine_result; /* here signal handler overrides OK */
extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)); extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
extern int xiosetchilddied(void); extern int xiosetchilddied(void);

View file

@ -13,6 +13,7 @@
pid_t diedunknown[NUMUNKNOWN]; /* children that died before they were registered */ pid_t diedunknown[NUMUNKNOWN]; /* children that died before they were registered */
int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */ int statunknown[NUMUNKNOWN]; /* exit state of unknown dead child */
size_t nextunknown; size_t nextunknown;
int engine_result = EXIT_SUCCESS;
/* register for a xio filedescriptor a callback (handler). /* register for a xio filedescriptor a callback (handler).
@ -138,8 +139,9 @@ void childdied(int signum) {
Info2("waitpid(): child %d exited with status %d", Info2("waitpid(): child %d exited with status %d",
pid, WEXITSTATUS(status)); pid, WEXITSTATUS(status));
} else { } else {
Error2("waitpid(): child %d exited with status %d", Warn2("waitpid(): child %d exited with status %d",
pid, WEXITSTATUS(status)); pid, WEXITSTATUS(status));
engine_result = 1;
} }
} }
} else if (WIFSIGNALED(status)) { } else if (WIFSIGNALED(status)) {
@ -147,8 +149,9 @@ void childdied(int signum) {
Info2("waitpid(): child %d exited on signal %d", Info2("waitpid(): child %d exited on signal %d",
pid, WTERMSIG(status)); pid, WTERMSIG(status));
} else { } else {
Error2("waitpid(): child %d exited on signal %d", Warn2("waitpid(): child %d exited on signal %d",
pid, WTERMSIG(status)); pid, WTERMSIG(status));
engine_result = 1;
} }
} else if (WIFSTOPPED(status)) { } else if (WIFSTOPPED(status)) {
Info2("waitpid(): child %d stopped on signal %d", Info2("waitpid(): child %d stopped on signal %d",