lli

A small emulated asm like lang
Log | Files | Refs

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 }