summaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-08-16 15:47:08 -0400
committerJakob Kaivo <jkk@ung.org>2020-08-16 15:47:08 -0400
commit700fbd205a1a428677876d322606b9a354221892 (patch)
treec1a521f3a2ea0346f293a543a9ed4ef6c1242b77 /src/stdlib
parentd36c832edee04db91e0c0ab635980c63844ca07c (diff)
add skeleton of things from C11
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/aligned_alloc.c12
-rw-r--r--src/stdlib/at_quick_exit.c54
-rw-r--r--src/stdlib/quick_exit.c45
3 files changed, 111 insertions, 0 deletions
diff --git a/src/stdlib/aligned_alloc.c b/src/stdlib/aligned_alloc.c
new file mode 100644
index 00000000..9b721a13
--- /dev/null
+++ b/src/stdlib/aligned_alloc.c
@@ -0,0 +1,12 @@
+#include <stdli.h>
+
+void *aligned_alloc(size_t alignment, size_t size)
+{
+ /* all allocations are page aligned */
+ (void)alignment;
+ return malloc(size);
+}
+
+/*
+STDC(201112)
+*/
diff --git a/src/stdlib/at_quick_exit.c b/src/stdlib/at_quick_exit.c
new file mode 100644
index 00000000..01127d4e
--- /dev/null
+++ b/src/stdlib/at_quick_exit.c
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+#include "_stdlib.h"
+
+/** register a function to run at quick exit **/
+int at_quick_exit(void (*func)(void))
+{
+ __C_MIN(201112L);
+ if (__stdlib.nat_quick_exit >= ATEXIT_MAX) {
+ return 1;
+ }
+
+ if (__stdlib.at_quick_exit == NULL) {
+ __stdlib.at_quick_exit = calloc(1,
+ sizeof(*__stdlib.at_quick_exit));
+ if (__stdlib.at_quick_exit == NULL) {
+ errno = ENOMEM;
+ return 1;
+ }
+ __stdlib.at_quick_exit->fn = func;
+ __stdlib.nat_quick_exit = 1;
+ return 0;
+ }
+
+ __stdlib.at_quick_exit->next = calloc(1,
+ sizeof(*__stdlib.at_quick_exit->next));
+ if (__stdlib.at_quick_exit->next == NULL) {
+ errno = ENOMEM;
+ return 1;
+ }
+ __stdlib.at_quick_exit->next->fn = func;
+ __stdlib.at_quick_exit->next->prev = __stdlib.at_quick_exit;
+ __stdlib.at_quick_exit = __stdlib.at_quick_exit->next;
+ __stdlib.nat_quick_exit++;
+
+ return 0;
+}
+
+/***
+The fn(at_quick_exit) registers the function arg(func) to be called when the
+program exits via fn(quick_exit). The function must take no parameters.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: the number of registrations allowed (at least 32) */
+/* LOCALE: - */
+
+/* RETURN(0): success */
+/* RETURN(NZ): failure */
+/*
+STDC(201112)
+*/
diff --git a/src/stdlib/quick_exit.c b/src/stdlib/quick_exit.c
new file mode 100644
index 00000000..25937325
--- /dev/null
+++ b/src/stdlib/quick_exit.c
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <stddef.h>
+#include "_stdlib.h"
+
+/** cause normal quick program termination **/
+_Noreturn void quick_exit(int status)
+{
+ /* execute all at_quick_exit() registered functions in reverse order */
+ while (__stdlib.at_quick_exit) {
+ __stdlib.at_quick_exit->fn();
+ __stdlib.at_quick_exit = __stdlib.at_quick_exit->prev;
+ }
+
+ fflush(NULL);
+ // fclose(all the things);
+ // remove(all the tmpfile()s);
+ /* TODO */
+ /* __syscall(exit, status); */
+ _Exit(status);
+}
+
+/***
+The fn(quick_exit) function causes the program to terminate normally, returning
+the value arg(status) to the host environment.
+
+First, all functions registered by fn(at_quick_exit) are called in the reverse
+order in which they were registered.
+
+Then, all open streams with unwritten buffered data are flushed. All open
+streams are closed. All temporary files created by fn(tmpfile) are removed.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: calls to fn(longjmp) in a registered handler */
+/* UNDEFINED: calling fn(quick_exit) twice */
+/* UNDEFINED: calling fn(quick_exit) and fn(exit) twice */
+/* UNDEFINED: signals during fn(quick_exit) */
+/* IMPLEMENTATION: the successful termination value returned to the host environment when arg(status) is 0 of macro(EXIT_SUCESS) */
+/* IMPLEMENTATION: the unsuccessful termination value returned to the host environment when arg(status) is macro(EXIT_FAILURE) */
+/* LOCALE: - */
+
+/*
+STDC(201112)
+*/