276 lines
7.6 KiB
C
276 lines
7.6 KiB
C
#include "all.h"
|
|
|
|
global pthread_key_t linux_thread_context_key;
|
|
global void (*_ctrl_c_handler_fn_ptr)() = NULL;
|
|
// ThreadContext
|
|
void osInit() {
|
|
pthread_key_create(&linux_thread_context_key, NULL);
|
|
}
|
|
|
|
void _osGenericSignalHandler(i32 signal) {
|
|
if (signal == SIGINT && _ctrl_c_handler_fn_ptr != NULL) {
|
|
_ctrl_c_handler_fn_ptr();
|
|
}
|
|
}
|
|
|
|
void osSetCtrlCCallback(void (*handler)()) {
|
|
_ctrl_c_handler_fn_ptr = handler;
|
|
signal(SIGINT, _osGenericSignalHandler);
|
|
}
|
|
|
|
void* osThreadContextGet() {
|
|
return pthread_getspecific(linux_thread_context_key);
|
|
}
|
|
|
|
void osThreadContextSet(void* ctx) {
|
|
pthread_setspecific(linux_thread_context_key, ctx);
|
|
}
|
|
|
|
bool osThreadJoin(Thread handle, u64 endt_us) {
|
|
/*
|
|
if(MemoryIsZeroStruct(&handle)) { return 0; }
|
|
OS_LNX_Entity *entity = (OS_LNX_Entity *)handle.u64[0];
|
|
int join_result = pthread_join(entity->thread.handle, 0);
|
|
B32 result = (join_result == 0);
|
|
os_lnx_entity_release(entity);
|
|
return result;
|
|
*/
|
|
i32 join_result = pthread_join(handle.thread, NULL);
|
|
bool result = join_result == 0;
|
|
return result;
|
|
}
|
|
|
|
// Memory
|
|
fn void* osMemoryReserve(u64 size) {
|
|
void* result = mmap(((void*)0), size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
if(result == MAP_FAILED) {
|
|
result = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
fn void osMemoryCommit(void* memory, u64 size) {
|
|
i32 result = mprotect(memory, size, PROT_READ | PROT_WRITE);
|
|
assert(result == 0 && "osMemoryCommit() failed");
|
|
}
|
|
|
|
fn void osMemoryDecommit(void* memory, u64 size) {
|
|
mprotect(memory, size, PROT_NONE);
|
|
}
|
|
|
|
fn void osMemoryRelease(void* memory, u64 size) {
|
|
munmap(memory, size);
|
|
}
|
|
|
|
// TUI
|
|
TermIOs osStartTUI(bool blocking) {
|
|
// set up the TUI incantations
|
|
printf("\033[?1049h"); // go to alternate buffer
|
|
TermIOs terminal_attributes, old_terminal_attributes;
|
|
tcgetattr(STDOUT_FILENO, &terminal_attributes);
|
|
old_terminal_attributes = terminal_attributes;
|
|
terminal_attributes.c_lflag &= ~(ICANON | ECHO); // dont echo keypresses, dont wait for carriage return
|
|
tcsetattr(STDOUT_FILENO, TCSANOW, &terminal_attributes);
|
|
if (!blocking) {
|
|
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking input mode
|
|
}
|
|
fflush(stdout);
|
|
return old_terminal_attributes;
|
|
}
|
|
|
|
fn void osEndTUI(TermIOs old_terminal_attributes) {
|
|
tcsetattr(STDOUT_FILENO, TCSANOW, &old_terminal_attributes);
|
|
|
|
// cleanup terminal TUI incantations
|
|
printf("\033[?1049l");
|
|
fflush(stdout);
|
|
}
|
|
|
|
fn Dim2 osGetTerminalDimensions() {
|
|
Dim2 result = {0};
|
|
struct winsize ws;
|
|
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) {
|
|
//perror("ioctl TIOCGWINSZ failed");
|
|
//exit(1);
|
|
return result;
|
|
}
|
|
result.width = ws.ws_col;
|
|
result.height = ws.ws_row;
|
|
return result;
|
|
}
|
|
|
|
void osBlitToTerminal(ptr writeable_output_ansi_string, u64 count) {
|
|
int flags = fcntl(STDOUT_FILENO, F_GETFL);
|
|
fcntl(STDOUT_FILENO, F_SETFL, flags & ~O_NONBLOCK);
|
|
|
|
u64 total = 0;
|
|
while (total < count) {
|
|
i64 written_bytes = write(STDOUT_FILENO, writeable_output_ansi_string + total, count - total);
|
|
/* TODO handle this error
|
|
if (written_bytes < 0) {
|
|
if (errno == EINTR) continue; // Interrupted, retry
|
|
return -1; // Real error
|
|
}
|
|
*/
|
|
total += written_bytes;
|
|
}
|
|
fcntl(STDOUT_FILENO, F_SETFL, flags);
|
|
}
|
|
|
|
bool osInitNetwork() { return true; }
|
|
|
|
void osReadConsoleInput(u8* buffer, u32 len) {
|
|
MemoryZero(buffer, len); // reset the input so it's not contaminated by last keystroke
|
|
read(STDIN_FILENO, buffer, len);
|
|
}
|
|
|
|
#define LOCALHOST_127 16777343
|
|
i32 osLanIPAddress() { // returns as HOST byte-order
|
|
i32 result = 0;
|
|
struct ifaddrs *ifaddr, *ifa;
|
|
if (getifaddrs(&ifaddr) != -1) {
|
|
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
|
if (ifa->ifa_addr == NULL) continue;
|
|
|
|
int family = ifa->ifa_addr->sa_family;
|
|
|
|
if (family == AF_INET) {
|
|
struct sockaddr_in addr = *(struct sockaddr_in*)ifa->ifa_addr;
|
|
if (addr.sin_addr.s_addr != LOCALHOST_127) {
|
|
freeifaddrs(ifaddr);
|
|
//printf("%s %d %d", inet_ntoa(addr.sin_addr), addr.sin_addr.s_addr, ntohl(addr.sin_addr.s_addr));
|
|
return ntohl(addr.sin_addr.s_addr);
|
|
}
|
|
/*
|
|
char host[NI_MAXHOST];
|
|
int s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
|
|
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
|
|
|
|
if (s == 0) {
|
|
printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, host);
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
freeifaddrs(ifaddr);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Files
|
|
fn bool osFileExists(String filename) {
|
|
bool result = access((str)filename.bytes, F_OK) == 0;
|
|
return result;
|
|
}
|
|
|
|
fn String osFileRead(Arena* arena, ptr filepath) {
|
|
struct stat st;
|
|
stat(filepath, &st);
|
|
String result = { st.st_size, st.st_size, 0 };
|
|
result.bytes = arenaAlloc(arena, st.st_size);
|
|
|
|
size_t handle = open(filepath, O_RDWR, S_IRUSR | S_IRGRP | S_IROTH);
|
|
read(handle, result.bytes, st.st_size);
|
|
close(handle);
|
|
|
|
return result;
|
|
}
|
|
|
|
fn bool osFileCreate(String filename) {
|
|
/*
|
|
M_Scratch scratch = scratch_get();
|
|
string nt = str_copy(&scratch.arena, filename);
|
|
bool result = true;
|
|
size_t handle = open((const char*) nt.str, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
|
|
if (handle == -1) {
|
|
result = false;
|
|
}
|
|
scratch_return(&scratch);
|
|
close(handle);
|
|
return true;
|
|
*/
|
|
bool result = true;
|
|
i32 handle = open((str)filename.bytes, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
if (handle == -1) {
|
|
result = false;
|
|
}
|
|
if (close(handle) == -1) {
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
fn bool osFileCreateWrite(String filename, String data) {
|
|
/*
|
|
M_Scratch scratch = scratch_get();
|
|
string nt = str_copy(&scratch.arena, filename);
|
|
b32 result = true;
|
|
size_t handle =
|
|
open((const char*) nt.str, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH);
|
|
if (handle == -1) result = false;
|
|
write(handle, data.str, data.size);
|
|
close(handle);
|
|
scratch_return(&scratch);
|
|
return result;
|
|
*/
|
|
bool result = true;
|
|
i32 handle = open(
|
|
(str)filename.bytes,
|
|
O_RDWR | O_CREAT | O_TRUNC,
|
|
S_IRUSR | S_IRGRP | S_IROTH
|
|
);
|
|
if (handle == -1) result = false;
|
|
write(handle, data.bytes, data.length);
|
|
close(handle);
|
|
return result;
|
|
}
|
|
|
|
fn bool osFileWrite(String filename, String data) {
|
|
/*
|
|
M_Scratch scratch = scratch_get();
|
|
string nt = str_copy(&scratch.arena, filename);
|
|
b32 result = true;
|
|
size_t handle =
|
|
open((const char*) nt.str, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH);
|
|
if (handle == -1) result = false;
|
|
write(handle, data.str, data.size);
|
|
close(handle);
|
|
*/
|
|
bool result = true;
|
|
i32 handle = open((str) filename.bytes, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH);
|
|
if (handle == -1) result = false;
|
|
write(handle, data.bytes, data.length);
|
|
close(handle);
|
|
return result;
|
|
}
|
|
|
|
fn Resulti64 osFileOpenForWriting(String filename) {
|
|
i32 handle = open((str)filename.bytes, O_WRONLY | O_APPEND, S_IRUSR | S_IRGRP | S_IROTH);
|
|
Resulti64 result = {
|
|
.success = handle != -1,
|
|
.value = (i64)handle,
|
|
};
|
|
return result;
|
|
}
|
|
|
|
fn Resulti64 osFileClose(Resulti64 handle) {
|
|
i32 close_result = close((size_t)handle.value);
|
|
Resulti64 result = {
|
|
.success = close_result != -1,
|
|
.value = (i64)close_result,
|
|
};
|
|
return result;
|
|
}
|
|
|
|
fn bool osFileWriteOpenFile(Resulti64 handle, String data) {
|
|
assert(handle.success == true);
|
|
i32 wrote_this_round = 0;
|
|
for (u32 bytes_written = 0; bytes_written < data.length; bytes_written += wrote_this_round) {
|
|
wrote_this_round = write((size_t)handle.value, data.bytes + bytes_written, data.length - bytes_written);
|
|
if (wrote_this_round == -1) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|