rendered paste body#ifndef _API_H#define _API_H#define main _the_entry_point#define UNUSED __attribute__((unused))#define NORETURN __attribute__((noreturn))#ifdef __CPLUSPLUSextern "C" {#endif#define UNAME_FIELD_SIZE 12typedef unsigned char u8;typedef unsigned short u16;typedef unsigned int u32;typedef unsigned long long u64;typedef long long s64;typedef int s32;typedef u32 size_t;typedef int pid_t;typedef struct { pid_t pid; u32 data[7];} Message;typedef struct { char sysname[UNAME_FIELD_SIZE]; char nodename[UNAME_FIELD_SIZE]; char release[UNAME_FIELD_SIZE]; char version[UNAME_FIELD_SIZE]; char machine[UNAME_FIELD_SIZE];} utsname;typedef enum { SEEK_SET=0,SEEK_CUR=1,SEEK_END=2 } SEEK_WHENCE ;typedef enum { P_READ=0,P_WRITE=1 } POLL_OPS;extern int errno;#define WNOHANG 1/// return information about the systemint sys_uname(utsname* ob);/// read len bytes from buf from fdint sys_read(int fd,void* buf,int len);/// write len bytes from buf to fdint sys_write(int fd,const void* buf,int len);/// exits the current process.NORETURN void sys_exit(int code);/// pause execution for a number of ticks. (not seconds)void sys_sleep(int time);/// change the offset in file fd.int sys_lseek(int fd,int offset,SEEK_WHENCE whence);/// start a new process which is a copy of this one.int sys_fork(void);/// wait for a child to finish execution, and return it's status code.int sys_wait(int*status);/// get the process id of the calling process.int sys_getpid(void);/// opens a file with the specified mode.int sys_open(const char*filename,char mode);/// executes the file fd.int sys_exec(int fd);int sys_execve(int fd,char** argv);/// return true if fd will block on read or write.int sys_poll(int fd,POLL_OPS operation);/// closes the open file fd.int sys_close(int fd);void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd, u32 offset);int sys_munmap(void *addr, size_t length);int sys_waitpid(int pid,int*status,int options);int sys_setring(int priv);int sys_pipe(int *fds);int sys_dup(int oldfd,int newfd);int sys_recvmsg(Message *m);int sys_sendmsg(Message *m);#ifdef __CPLUSPLUS};#endif#endif#include "lib.h"// these are functions to be called in usermode, utilising the system calls.#include "api.h"#define BUF_LEN 256#define USE_BUFFERED_IOstatic const char* NULLSTRING="(null)";static char output_line[BUF_LEN];static int output_pos=0;#ifdef USE_BUFFERED_IOvoid flush() { sys_write(1,output_line,output_pos); output_pos=0;}static void append_char(char c) { output_line[output_pos++]=c; if(output_pos>=BUF_LEN || c=='\n') { flush(); }}#elsevoid flush() {}#endifchar getch() { char in[2]; sys_read(0,in,1); return in[0];}void putch(char c) {#ifdef USE_BUFFERED_IO append_char(c);#else sys_write(1,&c,1); return;#endif}int strlen(const char*str) { int len=0; while(*str++) len++; return len;}int atoi(const char*str) { int ret=0; for(const char* it=str;*it;++it) { if(*it >= '0' && *it <= '9') { ret*=10; ret+=(*it)-'0'; } else break; } return ret;}int strncmp(const char* s1,const char* s2,const int len) { for(int i=0;i<len;++i) { char c = s1[i]-s2[i]; if(c!=0) return c; if(s1[i]==0 || s2[i]==0) break; } return 0;}void* memset(void* s,int c,int n) { char*it = (char*)(s); char* end=it+n; while(it!=end) *it++ = c; return s;}int print(const char*str) { const char *it=str; if(!it) it=NULLSTRING; while(*it) putch(*it++); return 0;}static void puthexnibble(char c) { char val = c&0xf; if(val<10) putch('0'+val); else putch('A'+val-10);}static void puthex(int val,int width) {switch(width) { case 0: case 8: puthexnibble(val>>28); case 7: puthexnibble(val>>24); case 6: puthexnibble(val>>20); case 5: puthexnibble(val>>16); case 4: puthexnibble(val>>12); case 3: puthexnibble(val>>8); case 2: puthexnibble(val>>4); case 1: puthexnibble(val); break; }}/* reverse: reverse string s in place */static void reverse(char s[]){ int c, i, j; for (i = 0, j = strlen(s)-1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; }}void itoa(int n, char s[]){ int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s);}static void putdec(int x) { char output[14]; itoa(x,output); print(output);}int printf(const char*fmt,...) {int *args=(int*)&fmt;args++;const char* curr=fmt;while(*curr) { if(*curr=='%') { int width=0; ++curr; if(*curr > '0' && *curr <= '9') { width=*curr-'0'; ++curr; } switch(*curr) { case 's': print((char*)*args++); break; case 'X': print("0x"); case 'x': puthex((int)*args++,width); break; case 'd': putdec((int)*args++); break; case 'c': if((char)*args) putch((char)*args); else print("\\0"); ++args; break; default: break; } ++curr; } else { putch(*curr); ++curr; }}return 0;}#define ESC 27// clear the screen via the terminal.void cls() { printf("%c[2J",ESC);// char code[4] = {ESC,'[','2','J' };// sys_write(1,code,sizeof(code));}// move the cursor to the specified pointvoid cursor_to(int x,int y) { printf("%c[%d;%dH",ESC,x,y); flush();}char getchar(int fd) { char c; if(sys_read(fd,&c,1)) return c; return 0;}void putchar(int fd,char c) { sys_write(fd,&c,1);}int fgets(int fd,char* buf,int len) {// int line_len=0; for(int i=0;i<len;++i) { char c = getchar(fd); switch(c) { case 0: // null byte, probably a keyboard key we've not mapped yet. --i; continue; case 8: // backspace. i-=2; if(i==-2) { ++i; } else putchar(1,c); continue; case '\n': putchar(1,c); c=0; default: buf[i]=c; if(c) { putchar(1,c); } break; } if(c==0) { return i; } } return -1;}void abort() { sys_exit(1); }void *memcpy(void *_dest, const void *_src, int n) { const u8* s=(u8*)(_src); u8* d=(u8*)(_dest); for(int i=0;i<n;++i) d[i]=s[i]; return _dest;}void colour(int fg,int bg) { if(fg==9||fg==8||fg<0||fg>20) return; if(bg==9||bg==8||bg<0||bg>20) return; printf("%c[%d;%dm",27,fg+30,bg+90);}