#ifndef _API_H #define _API_H #define main _the_entry_point #define UNUSED __attribute__((unused)) #define NORETURN __attribute__((noreturn)) #ifdef __CPLUSPLUS extern "C" { #endif #define UNAME_FIELD_SIZE 12 typedef 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 system int sys_uname(utsname* ob); /// read len bytes from buf from fd int sys_read(int fd,void* buf,int len); /// write len bytes from buf to fd int 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_IO static const char* NULLSTRING="(null)"; static char output_line[BUF_LEN]; static int output_pos=0; #ifdef USE_BUFFERED_IO void 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(); } } #else void flush() {} #endif char 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>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 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 point void 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;i20) return; if(bg==9||bg==8||bg<0||bg>20) return; printf("%c[%d;%dm",27,fg+30,bg+90); }