aboutsummaryrefslogtreecommitdiff
path: root/lib/xwrap.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2016-03-13 20:23:41 -0500
committerRob Landley <rob@landley.net>2016-03-13 20:23:41 -0500
commiteb24df9749994d175a2de3b7fc0535abe46a7576 (patch)
tree73960237e28c3e222cbe054858641d7b4ece8a92 /lib/xwrap.c
parent51d71f5c5b7040b50a38d9360561cee626eb2c2e (diff)
downloadtoybox-eb24df9749994d175a2de3b7fc0535abe46a7576.tar.gz
Split out _xexit() from xexit() and give sigatexit() multiple callbacks.
Diffstat (limited to 'lib/xwrap.c')
-rw-r--r--lib/xwrap.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 78103555..0b1ab8e9 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -28,13 +28,32 @@ void xstrncat(char *dest, char *src, size_t size)
strcpy(dest+len, src);
}
+// We replaced exit(), _exit(), and atexit() with xexit(), _xexit(), and
+// sigatexit(). This gives _xexit() the option to siglongjmp(toys.rebound, 1)
+// instead of exiting, lets xexit() report stdout flush failures to stderr
+// and change the exit code to indicate error, lets our toys.exit function
+// change happen for signal exit paths and lets us remove the functions
+// after we've called them.
+
+void _xexit(void)
+{
+ if (toys.rebound) siglongjmp(*toys.rebound, 1);
+
+ _exit(toys.exitval);
+}
+
void xexit(void)
{
- if (toys.rebound) longjmp(*toys.rebound, 1);
+ // Call toys.xexit functions in reverse order added.
+ while (toys.xexit) {
+ // This is typecasting xexit->arg to a function pointer,then calling it.
+ ((void (*)(void))(toys.xexit->arg))();
+
+ free(llist_pop(&toys.xexit));
+ }
if (fflush(NULL) || ferror(stdout))
if (!toys.exitval) perror_msg("write");
-
- exit(toys.exitval);
+ _xexit();
}
// Die unless we can allocate memory.