title: 近況報告 author: Takahiro Shimizu profile: lang: Japanese # 今週の進捗 - xv6をcloneして読み始めました - [Xv6, a simple Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2017/xv6.html) - 教科書もありました - [xv6 a simple, Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2017/xv6/book-rev10.pdf) - 木金で読み会をやる予定です # systemcall - `user.h` `usys.S`でそれぞれ定義されていました ```c // system calls int fork(void); int exit(void) __attribute__((noreturn)); int wait(void); int pipe(int*); int write(int, void*, int); int read(int, void*, int); int close(int); int kill(int); int exec(char*, char**); int open(char*, int); int mknod(char*, short, short); int unlink(char*); int fstat(int fd, struct stat*); int link(char*, char*); int mkdir(char*); int chdir(char*); int dup(int); int getpid(void); char* sbrk(int); int sleep(int); int uptime(void); ``` # printf - printfは `%d, %x, %p, %s.` のみをサポートしています - コンパイラ構成論で書いたような素朴な実装でした - print時の進数は `printint` の引数で分けているようです ```c void printf(int fd, char *fmt, ...) { char *s; int c, i, state; uint *ap; state = 0; ap = (uint*)(void*)&fmt + 1; for(i = 0; fmt[i]; i++){ c = fmt[i] & 0xff; if(state == 0){ if(c == '%'){ state = '%'; } else { putc(fd, c); } } else if(state == '%'){ if(c == 'd'){ printint(fd, *ap, 10, 1); ap++; } else if(c == 'x' || c == 'p'){ printint(fd, *ap, 16, 0); ap++; } else if(c == 's'){ s = (char*)*ap; ap++; if(s == 0) s = "(null)"; while(*s != 0){ putc(fd, *s); s++; } } else if(c == 'c'){ putc(fd, *ap); ap++; } else if(c == '%'){ putc(fd, c); } else { // Unknown % sequence. Print it to draw attention. putc(fd, '%'); putc(fd, c); } state = 0; } } } ``` # sysemcallを呼ぶ前 - まだ処理が追いきれていません。 ``` static void printint(int fd, int xx, int base, int sgn) { static char digits[] = "0123456789ABCDEF"; char buf[16]; int i, neg; uint x; neg = 0; if(sgn && xx < 0){ neg = 1; x = -xx; } else { x = xx; } i = 0; do{ buf[i++] = digits[x % base]; }while((x /= base) != 0); if(neg) buf[i++] = '-'; while(--i >= 0) putc(fd, buf[i]); } ``` # putc - 素朴にwriteを読んでいる ``` static void putc(int fd, char c) { write(fd, &c, 1); } ``` # sh - main関数 - まずforkが入る - cd以外はparseしてrunする世界観のようです ```C int main(void) { static char buf[100]; int fd; // Ensure that three file descriptors are open. while((fd = open("console", O_RDWR)) >= 0){ if(fd >= 3){ close(fd); break; } } // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Chdir must be called by the parent, not the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) printf(2, "cannot cd %s\n", buf+3); continue; } if(fork1() == 0) runcmd(parsecmd(buf)); wait(); } exit(); } ```