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:
parent
be9026442e
commit
743aedcd49
@ -12,11 +12,11 @@ extern "C"
|
|||||||
/* Aborts the program. */
|
/* Aborts the program. */
|
||||||
noreturn void abort();
|
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);
|
noreturn void exit(int status);
|
||||||
|
|
||||||
/* Not implemented. */
|
/* Registers a handler function to be run at normal program termination. */
|
||||||
int atexit(void (*)(void));
|
int atexit(void (*handler)(void));
|
||||||
|
|
||||||
/* Not implemented.*/
|
/* Not implemented.*/
|
||||||
int atoi(const char*);
|
int atoi(const char*);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef _UNISTD_H
|
#ifndef _UNISTD_H
|
||||||
#define _UNISTD_H
|
#define _UNISTD_H
|
||||||
|
|
||||||
|
#include <bits/macros.h>
|
||||||
#include <bits/seek.h>
|
#include <bits/seek.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -20,6 +21,9 @@ extern "C"
|
|||||||
/* Not implemented. */
|
/* Not implemented. */
|
||||||
pid_t fork(void);
|
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. */
|
/* Calls the kernel for a specific service, determined by number. */
|
||||||
long syscall(long number, ...);
|
long syscall(long number, ...);
|
||||||
|
|
||||||
|
25
libs/libc/src/atexit.cpp
Normal file
25
libs/libc/src/atexit.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void terminate_libc()
|
||||||
|
{
|
||||||
|
fclose(stdout);
|
||||||
|
fclose(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void initialize_libc()
|
extern "C" void initialize_libc()
|
||||||
{
|
{
|
||||||
if (lseek(0, 0, SEEK_CUR) < 0)
|
if (lseek(0, 0, SEEK_CUR) < 0)
|
||||||
@ -24,4 +30,5 @@ extern "C" void initialize_libc()
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
else { stderr = fdopen(1, "rw"); }
|
else { stderr = fdopen(1, "rw"); }
|
||||||
|
atexit(terminate_libc);
|
||||||
}
|
}
|
@ -7,18 +7,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
noreturn void abort()
|
noreturn void abort()
|
||||||
{
|
{
|
||||||
exit(-1);
|
_exit(-1);
|
||||||
}
|
|
||||||
|
|
||||||
noreturn void exit(int status)
|
|
||||||
{
|
|
||||||
syscall(SYS_exit, status);
|
|
||||||
__builtin_unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
int atexit(void (*)(void))
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED("atexit");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int atoi(const char*)
|
int atoi(const char*)
|
||||||
|
@ -95,4 +95,10 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return syscall(SYS_seek, fd, offset, whence);
|
return syscall(SYS_seek, fd, offset, whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noreturn void _exit(int status)
|
||||||
|
{
|
||||||
|
syscall(SYS_exit, status);
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user