xnoe-os/src/common/common.c
2024-04-14 00:50:21 +01:00

211 lines
4.8 KiB
C

#include "common.h"
#define syscall_hdlr_0(a, b, c) \
a b() { \
asm volatile("mov $" c ", %%eax; int $0x80" : : :); \
}
#define syscall_hdlr_1(a, b, c, d, e) \
a b(d e) { \
asm volatile("mov $" c ", %%eax; mov %0, %%ebx; int $0x80" : : "m" (e) : "ebx"); \
}
#define syscall_hdlr_2(a, b, c, d, e, f, g) \
a b(d e, f g) { \
asm volatile("mov $" c ", %%eax; mov %0, %%ebx; mov %1, %%ecx; int $0x80" : : "m" (e), "m" (g) : "ebx", "ecx"); \
}
#define syscall_hdlr_3(a, b, c, d, e, f, g, h, i) \
a b(d e, f g, h i) { \
asm volatile("mov $" c ", %%eax; mov %0, %%ebx; mov %1, %%ecx; mov %2, %%edx; int $0x80" : : "m" (e), "m" (g), "m" (i) : "ebx", "ecx", "edx"); \
}
#include "syscalls.h"
char** environ = 0;
uint32_t strcmpc(char* a, char* b, char c) {
for (int i=0; a[i] && b[i]; i++) {
if (a[i] == c)
return i;
}
return 0;
}
void __setup(uint32_t argc, char** argv, char** envp) {
environ = envp;
}
char* getenv(char* key) {
for (int i=0; environ[i]; i++) {
uint32_t pos;
if (pos = strcmpc(environ[i], key, '=')) {
return key+pos+1;
}
}
return 0;
}
void setenv(char* key, char* value) {
uint32_t environ_count = 0;
for (int i=0; environ[i]; i++)
environ_count += 1;
char** new_environ = (char**)malloc((environ_count+2)*sizeof(char*));
for (int i=0; i<environ_count; i++)
new_environ[i] = environ[i];
uint32_t key_size = strlen(key);
uint32_t value_size = strlen(value);
char* new_entry = (char*)malloc(key_size + value_size + 2);
memcpy(new_entry, key, key_size);
new_entry[key_size] = '=';
memcpy(new_entry+key_size+1, value, value_size);
new_entry[key_size+1+value_size] = 0;
new_environ[environ_count] = new_entry;
new_environ[environ_count+1] = 0;
environ = new_environ;
}
uint32_t strlen(char* s) {
uint32_t i=0;
while (s[i]) i++;
return i;
}
bool strcmp(char* a, char* b) {
for (int i=0; a[i] && b[i]; i++)
if (a[i] != b[i])
return false;
return true;
}
void print(char* string) {
char* c = string;
int i=0;
while (*(c++))
i++;
write(i, 0, (uint8_t*)string);
}
int int_to_decimal(unsigned int number, char* string_buffer) {
for (int i=0; i<11; i++)
string_buffer[i] = 0;
int index = 9;
unsigned int acc = number;
if (acc == 0)
string_buffer[index--] = '0';
while (acc != 0) {
string_buffer[index--] = 0x30+(acc%10);
acc /= 10;
}
return (index+1);
}
char dec_to_hex[16] = "0123456789abcdef";
int int_to_hex(unsigned int number, char* string_buffer) {
for (int i=0; i<8; i++)
string_buffer[i] = '0';
string_buffer[8] = 0;
int index = 7;
unsigned int acc = number;
if (acc == 0)
string_buffer[index--] = '0';
while (acc != 0) {
string_buffer[index--] = dec_to_hex[acc%0x10];
acc /= 0x10;
}
return (index+1);
}
bool isnum(char c) {
return c >= 0x30 && c <= 0x39;
}
void printf(const char* string, ...) {
va_list ptr;
va_start(ptr, string);
int index = 0;
char current;
while (current=string[index++]) {
if (current == '%') {
uint32_t width = 0;
bool lp = false;
if (string[index] == '.') {
lp = true;
index++;
} else {
while (isnum(string[index])) {
width *= 10;
width += string[index] - 0x30;
index++;
}
}
int type = string[index++];
int offset;
switch (type) {
case 'd': {
char decimal_buffer[11];
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
print(decimal_buffer + offset);
break;
}
case 'x': {
char hex_buffer[8];
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
print(hex_buffer);
break;
}
case 's': {
if (width) {
char s[width+1];
s[width] = 0;
memcpy(s, va_arg(ptr, const char*), width);
print(s);
} else if (lp) {
int width = va_arg(ptr, int);
char s[width+1];
s[width] = 0;
memcpy(s, va_arg(ptr, const char*), width);
print(s);
} else {
print(va_arg(ptr, const char*));
}
break;
}
case 'c': {
int promoted = va_arg(ptr, int);
char charred = promoted;
write(1, 0, &charred);
break;
}
}
continue;
}
write(1, 0, &current);
}
va_end(ptr);
}
void memset(void* ptr, char c, uint32_t count) {
for (int i=0; i<count; i++) {
((char*)ptr)[i] = c;
}
}
void memcpy(void* dst, void* src, uint32_t count) {
for (int i=0; i<count; i++)
((char*)dst)[i] = ((char*)src)[i];
}
uint32_t exec(uint32_t fh) {
char* zero = 0;
return execve(fh, &zero, environ);
}
uint32_t execv(uint32_t fh, char** argv) {
char* zero = 0;
return execve(fh, argv, environ);
}