unix_core.c (2141B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdint.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <string.h> 7 8 /* table of memory 9 * | function | size | loc | 10 * +----------+------+-----+ 11 * | stdin | 1 | 0 | 12 * | stdout | 1 | 1 | 13 * | stderr | 1 | 2 | 14 * | syscall | 1 | 3 | 15 * | arg1 | 4 | 4 | 16 * | arg2 | 4 | 8 | 17 * | arg3 | 4 | 12 | 18 * | arg4 | 4 | 16 | 19 * | result | 4 | 20 | 20 * | fd | 4 | 24 | 21 * | read | 1 | 28 | 22 * | write | 1 | 29 | 23 */ 24 25 enum syscalls { 26 NOP = 0, // no args 27 OPEN = 1, // path, 0 | 1 | 2 (read | write | append) -> id 28 CLOSE = 2, // id 29 EXIT = 3, // status 30 FORK = 4, // no args -> pid 31 }; 32 33 static void 34 dosyscall(uint8_t num, int args[4], char *mem) { 35 int fd, pid; 36 switch (num) { 37 case NOP: return; 38 case OPEN: 39 if (args[1] == 0) 40 fd = open(&mem[args[0]], O_RDONLY); 41 else if (args[1] == 1) 42 fd = open(&mem[args[0]], O_RDWR | O_TRUNC | O_CREAT, 0666); 43 else if (args[1] == 2) 44 fd = open(&mem[args[0]], O_RDWR | O_APPEND | O_CREAT, 0666); 45 if (fd == -1) 46 perror("failed to open file"); 47 memcpy(&mem[20], &fd, sizeof(int)); 48 break; 49 case CLOSE: 50 close(args[0]); 51 break; 52 case EXIT: 53 exit(args[0]); 54 break; 55 case FORK: 56 pid = fork(); 57 memcpy(&mem[20], &pid, sizeof(int)); 58 break; 59 } 60 } 61 62 int 63 getsize() { 64 return 30; 65 } 66 67 void 68 onwrite(char *addr) { 69 if (*(addr + 1)) { 70 putc(*(addr + 1), stdout); 71 *(addr + 1) = 0; 72 } 73 if (*(addr + 2)) { 74 putc(*(addr + 2), stderr); 75 *(addr + 2) = 0; 76 } 77 if (*(addr + 3)) { 78 int args[] = { 79 *(int *)(addr + 4), 80 *(int *)(addr + 8), 81 *(int *)(addr + 12), 82 *(int *)(addr + 16), 83 }; 84 dosyscall(*(uint8_t *)(addr + 3), args, addr); 85 *(addr + 3) = 0; 86 *(int *)(addr + 4) = 0; 87 *(int *)(addr + 8) = 0; 88 *(int *)(addr + 12) = 0; 89 *(int *)(addr + 16) = 0; 90 } 91 if (*(addr + 29)) { 92 char c = *(addr + 29); 93 write(*(int *)&addr[24], &c, 1); 94 *(addr + 29) = 0; 95 } 96 } 97 98 void 99 onread(char *addr, char *ptr) { 100 if (ptr == addr) { 101 *ptr = getc(stdin); 102 } 103 if (ptr == (addr + 28)) { 104 read(*(int *)&addr[24], (addr + 28), 1); 105 *(addr + 28) = 0; 106 } 107 }