Luna/libs/libc/src/init.cpp

67 lines
1.6 KiB
C++

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void terminate_libc()
{
fclose(stdout);
fclose(stderr);
fclose(stdin);
}
static void initialize_random()
{
unsigned int seed = 3735928559U;
int fd = open("/dev/random", O_RDONLY | O_CLOEXEC); // If we somehow fail to close this file, close it on exec.
FILE* fp = fdopen(fd, "r");
if (!fp)
{
errno = 0;
goto failed_to_read_dev_random;
}
fread(&seed, sizeof(seed), 1, fp);
if (ferror(fp))
{
errno = 0;
fclose(fp);
goto failed_to_read_dev_random;
}
fclose(fp);
failed_to_read_dev_random:
srand(seed); // If we failed, this will be seeded with a known value. Else, it will be seeded with a random value
// from the kernel.
return;
}
static void check_for_file(int fd, FILE** target_stream, const char* path, const char* mode)
{
if (lseek(fd, 0, SEEK_CUR) < 0)
{
if (errno == EBADF) *target_stream = fopen(path, mode);
else
exit(-127);
if (!*target_stream) exit(-127);
errno = 0;
}
else { *target_stream = fdopen(fd, mode); }
}
extern char* program_invocation_name;
extern "C" void initialize_libc(int, char** argv)
{
check_for_file(STDIN_FILENO, &stdin, "/dev/kbd", "r");
check_for_file(STDOUT_FILENO, &stdout, "/dev/console", "a");
check_for_file(STDERR_FILENO, &stderr, "/dev/console", "a");
if (argv) program_invocation_name = argv[0];
initialize_random();
atexit(terminate_libc);
}