210 lines
4.8 KiB
C
210 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, ¤t);
|
|
}
|
|
|
|
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) {
|
|
uint8_t* zero = 0;
|
|
return execve(fh, &zero, (uint8_t**)environ);
|
|
}
|
|
|
|
uint32_t execv(uint32_t fh, char** argv) {
|
|
return execve(fh, (uint8_t**)argv, (uint8_t**)environ);
|
|
} |