libc: Implement atexit() and _exit()

exit() now calls registered handlers before calling _exit().

And initialize_libc() can now register a handler to close stdout and stderr on program termination!! :)
This commit is contained in:
apio 2022-10-12 20:41:55 +02:00
parent be9026442e
commit 743aedcd49
6 changed files with 46 additions and 15 deletions

View File

@ -12,11 +12,11 @@ extern "C"
/* Aborts the program. */
noreturn void abort();
/* Exits the program with the specified status code. */
/* Normally exits the program with the specified status code. */
noreturn void exit(int status);
/* Not implemented. */
int atexit(void (*)(void));
/* Registers a handler function to be run at normal program termination. */
int atexit(void (*handler)(void));
/* Not implemented.*/
int atoi(const char*);

View File

@ -1,6 +1,7 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#include <bits/macros.h>
#include <bits/seek.h>
#include <sys/types.h>
@ -20,6 +21,9 @@ extern "C"
/* Not implemented. */
pid_t fork(void);
/* Terminates the program with the status code status. */
noreturn void _exit(int status);
/* Calls the kernel for a specific service, determined by number. */
long syscall(long number, ...);

25
libs/libc/src/atexit.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <stdlib.h>
#include <unistd.h>
#define ATEXIT_MAX_FUNCS 32
typedef void (*atexit_func_t)(void);
atexit_func_t atexit_functions[ATEXIT_MAX_FUNCS];
int atexit_function_count = 0;
extern "C"
{
int atexit(atexit_func_t handler)
{
if (atexit_function_count >= ATEXIT_MAX_FUNCS) return -1;
atexit_functions[atexit_function_count++] = handler;
return 0;
}
noreturn void exit(int status)
{
for (int i = 0; i < atexit_function_count; i++) { atexit_functions[i](); }
_exit(status);
}
}

View File

@ -4,6 +4,12 @@
#include <stdlib.h>
#include <unistd.h>
static void terminate_libc()
{
fclose(stdout);
fclose(stderr);
}
extern "C" void initialize_libc()
{
if (lseek(0, 0, SEEK_CUR) < 0)
@ -24,4 +30,5 @@ extern "C" void initialize_libc()
errno = 0;
}
else { stderr = fdopen(1, "rw"); }
atexit(terminate_libc);
}

View File

@ -7,18 +7,7 @@ extern "C"
{
noreturn void abort()
{
exit(-1);
}
noreturn void exit(int status)
{
syscall(SYS_exit, status);
__builtin_unreachable();
}
int atexit(void (*)(void))
{
NOT_IMPLEMENTED("atexit");
_exit(-1);
}
int atoi(const char*)

View File

@ -95,4 +95,10 @@ extern "C"
{
return syscall(SYS_seek, fd, offset, whence);
}
noreturn void _exit(int status)
{
syscall(SYS_exit, status);
__builtin_unreachable();
}
}