add lab answers
This commit is contained in:
22
labcodes_answer/lab8_result/user/badarg.c
Normal file
22
labcodes_answer/lab8_result/user/badarg.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int pid, exit_code;
|
||||
if ((pid = fork()) == 0) {
|
||||
cprintf("fork ok.\n");
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
yield();
|
||||
}
|
||||
exit(0xbeaf);
|
||||
}
|
||||
assert(pid > 0);
|
||||
assert(waitpid(-1, NULL) != 0);
|
||||
assert(waitpid(pid, (void *)0xC0000000) != 0);
|
||||
assert(waitpid(pid, &exit_code) == 0 && exit_code == 0xbeaf);
|
||||
cprintf("badarg pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
11
labcodes_answer/lab8_result/user/badsegment.c
Normal file
11
labcodes_answer/lab8_result/user/badsegment.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
/* try to load the kernel's TSS selector into the DS register */
|
||||
|
||||
int
|
||||
main(void) {
|
||||
asm volatile("movw $0x28,%ax; movw %ax,%ds");
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
11
labcodes_answer/lab8_result/user/divzero.c
Normal file
11
labcodes_answer/lab8_result/user/divzero.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int zero;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("value is %d.\n", 1 / zero);
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
34
labcodes_answer/lab8_result/user/exit.c
Normal file
34
labcodes_answer/lab8_result/user/exit.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int magic = -0x10384;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int pid, code;
|
||||
cprintf("I am the parent. Forking the child...\n");
|
||||
if ((pid = fork()) == 0) {
|
||||
cprintf("I am the child.\n");
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
exit(magic);
|
||||
}
|
||||
else {
|
||||
cprintf("I am parent, fork a child pid %d\n",pid);
|
||||
}
|
||||
assert(pid > 0);
|
||||
cprintf("I am the parent, waiting now..\n");
|
||||
|
||||
assert(waitpid(pid, &code) == 0 && code == magic);
|
||||
assert(waitpid(pid, &code) != 0 && wait() != 0);
|
||||
cprintf("waitpid %d ok.\n", pid);
|
||||
|
||||
cprintf("exit pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
9
labcodes_answer/lab8_result/user/faultread.c
Normal file
9
labcodes_answer/lab8_result/user/faultread.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("I read %8x from 0.\n", *(unsigned int *)0);
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
9
labcodes_answer/lab8_result/user/faultreadkernel.c
Normal file
9
labcodes_answer/lab8_result/user/faultreadkernel.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("I read %08x from 0xfac00000!\n", *(unsigned *)0xfac00000);
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
34
labcodes_answer/lab8_result/user/forktest.c
Normal file
34
labcodes_answer/lab8_result/user/forktest.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
const int max_child = 32;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int n, pid;
|
||||
for (n = 0; n < max_child; n ++) {
|
||||
if ((pid = fork()) == 0) {
|
||||
cprintf("I am child %d\n", n);
|
||||
exit(0);
|
||||
}
|
||||
assert(pid > 0);
|
||||
}
|
||||
|
||||
if (n > max_child) {
|
||||
panic("fork claimed to work %d times!\n", n);
|
||||
}
|
||||
|
||||
for (; n > 0; n --) {
|
||||
if (wait() != 0) {
|
||||
panic("wait stopped early\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (wait() == 0) {
|
||||
panic("wait got too many\n");
|
||||
}
|
||||
|
||||
cprintf("forktest pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
39
labcodes_answer/lab8_result/user/forktree.c
Normal file
39
labcodes_answer/lab8_result/user/forktree.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DEPTH 4
|
||||
#define SLEEP_TIME 400
|
||||
void forktree(const char *cur);
|
||||
|
||||
void
|
||||
forkchild(const char *cur, char branch) {
|
||||
char nxt[DEPTH + 1];
|
||||
|
||||
if (strlen(cur) >= DEPTH)
|
||||
return;
|
||||
|
||||
snprintf(nxt, DEPTH + 1, "%s%c", cur, branch);
|
||||
if (fork() == 0) {
|
||||
forktree(nxt);
|
||||
yield();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
forktree(const char *cur) {
|
||||
cprintf("%04x: I am '%s'\n", getpid(), cur);
|
||||
|
||||
forkchild(cur, '0');
|
||||
forkchild(cur, '1');
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("forktree process will sleep %d ticks\n",SLEEP_TIME);
|
||||
sleep(SLEEP_TIME);
|
||||
forktree("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
11
labcodes_answer/lab8_result/user/hello.c
Normal file
11
labcodes_answer/lab8_result/user/hello.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("Hello world!!.\n");
|
||||
cprintf("I am process %d.\n", getpid());
|
||||
cprintf("hello pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
46
labcodes_answer/lab8_result/user/libs/dir.c
Normal file
46
labcodes_answer/lab8_result/user/libs/dir.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <defs.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <stat.h>
|
||||
#include <dirent.h>
|
||||
#include <file.h>
|
||||
#include <dir.h>
|
||||
#include <error.h>
|
||||
#include <unistd.h>
|
||||
|
||||
DIR dir, *dirp=&dir;
|
||||
DIR *
|
||||
opendir(const char *path) {
|
||||
|
||||
if ((dirp->fd = open(path, O_RDONLY)) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
struct stat __stat, *stat = &__stat;
|
||||
if (fstat(dirp->fd, stat) != 0 || !S_ISDIR(stat->st_mode)) {
|
||||
goto failed;
|
||||
}
|
||||
dirp->dirent.offset = 0;
|
||||
return dirp;
|
||||
|
||||
failed:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dirent *
|
||||
readdir(DIR *dirp) {
|
||||
if (sys_getdirentry(dirp->fd, &(dirp->dirent)) == 0) {
|
||||
return &(dirp->dirent);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
closedir(DIR *dirp) {
|
||||
close(dirp->fd);
|
||||
}
|
||||
|
||||
int
|
||||
getcwd(char *buffer, size_t len) {
|
||||
return sys_getcwd(buffer, len);
|
||||
}
|
||||
|
||||
19
labcodes_answer/lab8_result/user/libs/dir.h
Normal file
19
labcodes_answer/lab8_result/user/libs/dir.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __USER_LIBS_DIR_H__
|
||||
#define __USER_LIBS_DIR_H__
|
||||
|
||||
#include <defs.h>
|
||||
#include <dirent.h>
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
struct dirent dirent;
|
||||
} DIR;
|
||||
|
||||
DIR *opendir(const char *path);
|
||||
struct dirent *readdir(DIR *dirp);
|
||||
void closedir(DIR *dirp);
|
||||
int chdir(const char *path);
|
||||
int getcwd(char *buffer, size_t len);
|
||||
|
||||
#endif /* !__USER_LIBS_DIR_H__ */
|
||||
|
||||
68
labcodes_answer/lab8_result/user/libs/file.c
Normal file
68
labcodes_answer/lab8_result/user/libs/file.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <defs.h>
|
||||
#include <string.h>
|
||||
#include <syscall.h>
|
||||
#include <stdio.h>
|
||||
#include <stat.h>
|
||||
#include <error.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
open(const char *path, uint32_t open_flags) {
|
||||
return sys_open(path, open_flags);
|
||||
}
|
||||
|
||||
int
|
||||
close(int fd) {
|
||||
return sys_close(fd);
|
||||
}
|
||||
|
||||
int
|
||||
read(int fd, void *base, size_t len) {
|
||||
return sys_read(fd, base, len);
|
||||
}
|
||||
|
||||
int
|
||||
write(int fd, void *base, size_t len) {
|
||||
return sys_write(fd, base, len);
|
||||
}
|
||||
|
||||
int
|
||||
seek(int fd, off_t pos, int whence) {
|
||||
return sys_seek(fd, pos, whence);
|
||||
}
|
||||
|
||||
int
|
||||
fstat(int fd, struct stat *stat) {
|
||||
return sys_fstat(fd, stat);
|
||||
}
|
||||
|
||||
int
|
||||
fsync(int fd) {
|
||||
return sys_fsync(fd);
|
||||
}
|
||||
|
||||
int
|
||||
dup2(int fd1, int fd2) {
|
||||
return sys_dup(fd1, fd2);
|
||||
}
|
||||
|
||||
static char
|
||||
transmode(struct stat *stat) {
|
||||
uint32_t mode = stat->st_mode;
|
||||
if (S_ISREG(mode)) return 'r';
|
||||
if (S_ISDIR(mode)) return 'd';
|
||||
if (S_ISLNK(mode)) return 'l';
|
||||
if (S_ISCHR(mode)) return 'c';
|
||||
if (S_ISBLK(mode)) return 'b';
|
||||
return '-';
|
||||
}
|
||||
|
||||
void
|
||||
print_stat(const char *name, int fd, struct stat *stat) {
|
||||
cprintf("[%03d] %s\n", fd, name);
|
||||
cprintf(" mode : %c\n", transmode(stat));
|
||||
cprintf(" links : %lu\n", stat->st_nlinks);
|
||||
cprintf(" blocks : %lu\n", stat->st_blocks);
|
||||
cprintf(" size : %lu\n", stat->st_size);
|
||||
}
|
||||
|
||||
23
labcodes_answer/lab8_result/user/libs/file.h
Normal file
23
labcodes_answer/lab8_result/user/libs/file.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef __USER_LIBS_FILE_H__
|
||||
#define __USER_LIBS_FILE_H__
|
||||
|
||||
#include <defs.h>
|
||||
|
||||
struct stat;
|
||||
|
||||
int open(const char *path, uint32_t open_flags);
|
||||
int close(int fd);
|
||||
int read(int fd, void *base, size_t len);
|
||||
int write(int fd, void *base, size_t len);
|
||||
int seek(int fd, off_t pos, int whence);
|
||||
int fstat(int fd, struct stat *stat);
|
||||
int fsync(int fd);
|
||||
int dup(int fd);
|
||||
int dup2(int fd1, int fd2);
|
||||
int pipe(int *fd_store);
|
||||
int mkfifo(const char *name, uint32_t open_flags);
|
||||
|
||||
void print_stat(const char *name, int fd, struct stat *stat);
|
||||
|
||||
#endif /* !__USER_LIBS_FILE_H__ */
|
||||
|
||||
24
labcodes_answer/lab8_result/user/libs/initcode.S
Normal file
24
labcodes_answer/lab8_result/user/libs/initcode.S
Normal file
@@ -0,0 +1,24 @@
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
# set ebp for backtrace
|
||||
movl $0x0, %ebp
|
||||
|
||||
# load argc and argv
|
||||
movl (%esp), %ebx
|
||||
lea 0x4(%esp), %ecx
|
||||
|
||||
|
||||
# move down the esp register
|
||||
# since it may cause page fault in backtrace
|
||||
subl $0x20, %esp
|
||||
|
||||
# save argc and argv on stack
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
|
||||
# call user-program function
|
||||
call umain
|
||||
1: jmp 1b
|
||||
|
||||
|
||||
42
labcodes_answer/lab8_result/user/libs/lock.h
Normal file
42
labcodes_answer/lab8_result/user/libs/lock.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef __USER_LIBS_LOCK_H__
|
||||
#define __USER_LIBS_LOCK_H__
|
||||
|
||||
#include <defs.h>
|
||||
#include <atomic.h>
|
||||
#include <ulib.h>
|
||||
|
||||
#define INIT_LOCK {0}
|
||||
|
||||
typedef volatile bool lock_t;
|
||||
|
||||
static inline void
|
||||
lock_init(lock_t *l) {
|
||||
*l = 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
try_lock(lock_t *l) {
|
||||
return test_and_set_bit(0, l);
|
||||
}
|
||||
|
||||
static inline void
|
||||
lock(lock_t *l) {
|
||||
if (try_lock(l)) {
|
||||
int step = 0;
|
||||
do {
|
||||
yield();
|
||||
if (++ step == 100) {
|
||||
step = 0;
|
||||
sleep(10);
|
||||
}
|
||||
} while (try_lock(l));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
unlock(lock_t *l) {
|
||||
test_and_clear_bit(0, l);
|
||||
}
|
||||
|
||||
#endif /* !__USER_LIBS_LOCK_H__ */
|
||||
|
||||
28
labcodes_answer/lab8_result/user/libs/panic.c
Normal file
28
labcodes_answer/lab8_result/user/libs/panic.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <defs.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
#include <error.h>
|
||||
|
||||
void
|
||||
__panic(const char *file, int line, const char *fmt, ...) {
|
||||
// print the 'message'
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
cprintf("user panic at %s:%d:\n ", file, line);
|
||||
vcprintf(fmt, ap);
|
||||
cprintf("\n");
|
||||
va_end(ap);
|
||||
exit(-E_PANIC);
|
||||
}
|
||||
|
||||
void
|
||||
__warn(const char *file, int line, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
cprintf("user warning at %s:%d:\n ", file, line);
|
||||
vcprintf(fmt, ap);
|
||||
cprintf("\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
89
labcodes_answer/lab8_result/user/libs/stdio.c
Normal file
89
labcodes_answer/lab8_result/user/libs/stdio.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <defs.h>
|
||||
#include <stdio.h>
|
||||
#include <syscall.h>
|
||||
#include <file.h>
|
||||
#include <ulib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* *
|
||||
* cputch - writes a single character @c to stdout, and it will
|
||||
* increace the value of counter pointed by @cnt.
|
||||
* */
|
||||
static void
|
||||
cputch(int c, int *cnt) {
|
||||
sys_putc(c);
|
||||
(*cnt) ++;
|
||||
}
|
||||
|
||||
/* *
|
||||
* vcprintf - format a string and writes it to stdout
|
||||
*
|
||||
* The return value is the number of characters which would be
|
||||
* written to stdout.
|
||||
*
|
||||
* Call this function if you are already dealing with a va_list.
|
||||
* Or you probably want cprintf() instead.
|
||||
* */
|
||||
int
|
||||
vcprintf(const char *fmt, va_list ap) {
|
||||
int cnt = 0;
|
||||
vprintfmt((void*)cputch, NO_FD, &cnt, fmt, ap);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* *
|
||||
* cprintf - formats a string and writes it to stdout
|
||||
*
|
||||
* The return value is the number of characters which would be
|
||||
* written to stdout.
|
||||
* */
|
||||
int
|
||||
cprintf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
int cnt = vcprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* *
|
||||
* cputs- writes the string pointed by @str to stdout and
|
||||
* appends a newline character.
|
||||
* */
|
||||
int
|
||||
cputs(const char *str) {
|
||||
int cnt = 0;
|
||||
char c;
|
||||
while ((c = *str ++) != '\0') {
|
||||
cputch(c, &cnt);
|
||||
}
|
||||
cputch('\n', &cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fputch(char c, int *cnt, int fd) {
|
||||
write(fd, &c, sizeof(char));
|
||||
(*cnt) ++;
|
||||
}
|
||||
|
||||
int
|
||||
vfprintf(int fd, const char *fmt, va_list ap) {
|
||||
int cnt = 0;
|
||||
vprintfmt((void*)fputch, fd, &cnt, fmt, ap);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int
|
||||
fprintf(int fd, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
int cnt = vfprintf(fd, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
145
labcodes_answer/lab8_result/user/libs/syscall.c
Normal file
145
labcodes_answer/lab8_result/user/libs/syscall.c
Normal file
@@ -0,0 +1,145 @@
|
||||
#include <defs.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <syscall.h>
|
||||
#include <stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
|
||||
#define MAX_ARGS 5
|
||||
|
||||
static inline int
|
||||
syscall(int num, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, num);
|
||||
uint32_t a[MAX_ARGS];
|
||||
int i, ret;
|
||||
for (i = 0; i < MAX_ARGS; i ++) {
|
||||
a[i] = va_arg(ap, uint32_t);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
asm volatile (
|
||||
"int %1;"
|
||||
: "=a" (ret)
|
||||
: "i" (T_SYSCALL),
|
||||
"a" (num),
|
||||
"d" (a[0]),
|
||||
"c" (a[1]),
|
||||
"b" (a[2]),
|
||||
"D" (a[3]),
|
||||
"S" (a[4])
|
||||
: "cc", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
sys_exit(int error_code) {
|
||||
return syscall(SYS_exit, error_code);
|
||||
}
|
||||
|
||||
int
|
||||
sys_fork(void) {
|
||||
return syscall(SYS_fork);
|
||||
}
|
||||
|
||||
int
|
||||
sys_wait(int pid, int *store) {
|
||||
return syscall(SYS_wait, pid, store);
|
||||
}
|
||||
|
||||
int
|
||||
sys_yield(void) {
|
||||
return syscall(SYS_yield);
|
||||
}
|
||||
|
||||
int
|
||||
sys_kill(int pid) {
|
||||
return syscall(SYS_kill, pid);
|
||||
}
|
||||
|
||||
int
|
||||
sys_getpid(void) {
|
||||
return syscall(SYS_getpid);
|
||||
}
|
||||
|
||||
int
|
||||
sys_putc(int c) {
|
||||
return syscall(SYS_putc, c);
|
||||
}
|
||||
|
||||
int
|
||||
sys_pgdir(void) {
|
||||
return syscall(SYS_pgdir);
|
||||
}
|
||||
|
||||
void
|
||||
sys_lab6_set_priority(uint32_t priority)
|
||||
{
|
||||
syscall(SYS_lab6_set_priority, priority);
|
||||
}
|
||||
|
||||
int
|
||||
sys_sleep(unsigned int time) {
|
||||
return syscall(SYS_sleep, time);
|
||||
}
|
||||
|
||||
size_t
|
||||
sys_gettime(void) {
|
||||
return syscall(SYS_gettime);
|
||||
}
|
||||
|
||||
int
|
||||
sys_exec(const char *name, int argc, const char **argv) {
|
||||
return syscall(SYS_exec, name, argc, argv);
|
||||
}
|
||||
|
||||
int
|
||||
sys_open(const char *path, uint32_t open_flags) {
|
||||
return syscall(SYS_open, path, open_flags);
|
||||
}
|
||||
|
||||
int
|
||||
sys_close(int fd) {
|
||||
return syscall(SYS_close, fd);
|
||||
}
|
||||
|
||||
int
|
||||
sys_read(int fd, void *base, size_t len) {
|
||||
return syscall(SYS_read, fd, base, len);
|
||||
}
|
||||
|
||||
int
|
||||
sys_write(int fd, void *base, size_t len) {
|
||||
return syscall(SYS_write, fd, base, len);
|
||||
}
|
||||
|
||||
int
|
||||
sys_seek(int fd, off_t pos, int whence) {
|
||||
return syscall(SYS_seek, fd, pos, whence);
|
||||
}
|
||||
|
||||
int
|
||||
sys_fstat(int fd, struct stat *stat) {
|
||||
return syscall(SYS_fstat, fd, stat);
|
||||
}
|
||||
|
||||
int
|
||||
sys_fsync(int fd) {
|
||||
return syscall(SYS_fsync, fd);
|
||||
}
|
||||
|
||||
int
|
||||
sys_getcwd(char *buffer, size_t len) {
|
||||
return syscall(SYS_getcwd, buffer, len);
|
||||
}
|
||||
|
||||
int
|
||||
sys_getdirentry(int fd, struct dirent *dirent) {
|
||||
return syscall(SYS_getdirentry, fd, dirent);
|
||||
}
|
||||
|
||||
int
|
||||
sys_dup(int fd1, int fd2) {
|
||||
return syscall(SYS_dup, fd1, fd2);
|
||||
}
|
||||
33
labcodes_answer/lab8_result/user/libs/syscall.h
Normal file
33
labcodes_answer/lab8_result/user/libs/syscall.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef __USER_LIBS_SYSCALL_H__
|
||||
#define __USER_LIBS_SYSCALL_H__
|
||||
|
||||
int sys_exit(int error_code);
|
||||
int sys_fork(void);
|
||||
int sys_wait(int pid, int *store);
|
||||
int sys_exec(const char *name, int argc, const char **argv);
|
||||
int sys_yield(void);
|
||||
int sys_kill(int pid);
|
||||
int sys_getpid(void);
|
||||
int sys_putc(int c);
|
||||
int sys_pgdir(void);
|
||||
int sys_sleep(unsigned int time);
|
||||
size_t sys_gettime(void);
|
||||
|
||||
struct stat;
|
||||
struct dirent;
|
||||
|
||||
int sys_open(const char *path, uint32_t open_flags);
|
||||
int sys_close(int fd);
|
||||
int sys_read(int fd, void *base, size_t len);
|
||||
int sys_write(int fd, void *base, size_t len);
|
||||
int sys_seek(int fd, off_t pos, int whence);
|
||||
int sys_fstat(int fd, struct stat *stat);
|
||||
int sys_fsync(int fd);
|
||||
int sys_getcwd(char *buffer, size_t len);
|
||||
int sys_getdirentry(int fd, struct dirent *dirent);
|
||||
int sys_dup(int fd1, int fd2);
|
||||
void sys_lab6_set_priority(uint32_t priority); //only for lab6
|
||||
|
||||
|
||||
#endif /* !__USER_LIBS_SYSCALL_H__ */
|
||||
|
||||
87
labcodes_answer/lab8_result/user/libs/ulib.c
Normal file
87
labcodes_answer/lab8_result/user/libs/ulib.c
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <defs.h>
|
||||
#include <syscall.h>
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
#include <stat.h>
|
||||
#include <string.h>
|
||||
#include <lock.h>
|
||||
|
||||
static lock_t fork_lock = INIT_LOCK;
|
||||
|
||||
void
|
||||
lock_fork(void) {
|
||||
lock(&fork_lock);
|
||||
}
|
||||
|
||||
void
|
||||
unlock_fork(void) {
|
||||
unlock(&fork_lock);
|
||||
}
|
||||
|
||||
void
|
||||
exit(int error_code) {
|
||||
sys_exit(error_code);
|
||||
cprintf("BUG: exit failed.\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
int
|
||||
fork(void) {
|
||||
return sys_fork();
|
||||
}
|
||||
|
||||
int
|
||||
wait(void) {
|
||||
return sys_wait(0, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
waitpid(int pid, int *store) {
|
||||
return sys_wait(pid, store);
|
||||
}
|
||||
|
||||
void
|
||||
yield(void) {
|
||||
sys_yield();
|
||||
}
|
||||
|
||||
int
|
||||
kill(int pid) {
|
||||
return sys_kill(pid);
|
||||
}
|
||||
|
||||
int
|
||||
getpid(void) {
|
||||
return sys_getpid();
|
||||
}
|
||||
|
||||
//print_pgdir - print the PDT&PT
|
||||
void
|
||||
print_pgdir(void) {
|
||||
sys_pgdir();
|
||||
}
|
||||
|
||||
void
|
||||
lab6_set_priority(uint32_t priority)
|
||||
{
|
||||
sys_lab6_set_priority(priority);
|
||||
}
|
||||
|
||||
int
|
||||
sleep(unsigned int time) {
|
||||
return sys_sleep(time);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gettime_msec(void) {
|
||||
return (unsigned int)sys_gettime();
|
||||
}
|
||||
|
||||
int
|
||||
__exec(const char *name, const char **argv) {
|
||||
int argc = 0;
|
||||
while (argv[argc] != NULL) {
|
||||
argc ++;
|
||||
}
|
||||
return sys_exec(name, argc, argv);
|
||||
}
|
||||
49
labcodes_answer/lab8_result/user/libs/ulib.h
Normal file
49
labcodes_answer/lab8_result/user/libs/ulib.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef __USER_LIBS_ULIB_H__
|
||||
#define __USER_LIBS_ULIB_H__
|
||||
|
||||
#include <defs.h>
|
||||
|
||||
void __warn(const char *file, int line, const char *fmt, ...);
|
||||
void __noreturn __panic(const char *file, int line, const char *fmt, ...);
|
||||
|
||||
#define warn(...) \
|
||||
__warn(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
#define panic(...) \
|
||||
__panic(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
#define assert(x) \
|
||||
do { \
|
||||
if (!(x)) { \
|
||||
panic("assertion failed: %s", #x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// static_assert(x) will generate a compile-time error if 'x' is false.
|
||||
#define static_assert(x) \
|
||||
switch (x) { case 0: case (x): ; }
|
||||
|
||||
int fprintf(int fd, const char *fmt, ...);
|
||||
|
||||
void __noreturn exit(int error_code);
|
||||
int fork(void);
|
||||
int wait(void);
|
||||
int waitpid(int pid, int *store);
|
||||
void yield(void);
|
||||
int kill(int pid);
|
||||
int getpid(void);
|
||||
void print_pgdir(void);
|
||||
int sleep(unsigned int time);
|
||||
unsigned int gettime_msec(void);
|
||||
int __exec(const char *name, const char **argv);
|
||||
|
||||
#define __exec0(name, path, ...) \
|
||||
({ const char *argv[] = {path, ##__VA_ARGS__, NULL}; __exec(name, argv); })
|
||||
|
||||
#define exec(path, ...) __exec0(NULL, path, ##__VA_ARGS__)
|
||||
#define nexec(name, path, ...) __exec0(name, path, ##__VA_ARGS__)
|
||||
|
||||
void lab6_set_priority(uint32_t priority); //only for lab6
|
||||
|
||||
#endif /* !__USER_LIBS_ULIB_H__ */
|
||||
|
||||
34
labcodes_answer/lab8_result/user/libs/umain.c
Normal file
34
labcodes_answer/lab8_result/user/libs/umain.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <ulib.h>
|
||||
#include <unistd.h>
|
||||
#include <file.h>
|
||||
#include <stat.h>
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
static int
|
||||
initfd(int fd2, const char *path, uint32_t open_flags) {
|
||||
int fd1, ret;
|
||||
if ((fd1 = open(path, open_flags)) < 0) {
|
||||
return fd1;
|
||||
}
|
||||
if (fd1 != fd2) {
|
||||
close(fd2);
|
||||
ret = dup2(fd1, fd2);
|
||||
close(fd1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
umain(int argc, char *argv[]) {
|
||||
int fd;
|
||||
if ((fd = initfd(0, "stdin:", O_RDONLY)) < 0) {
|
||||
warn("open <stdin> failed: %e.\n", fd);
|
||||
}
|
||||
if ((fd = initfd(1, "stdout:", O_WRONLY)) < 0) {
|
||||
warn("open <stdout> failed: %e.\n", fd);
|
||||
}
|
||||
int ret = main(argc, argv);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
118
labcodes_answer/lab8_result/user/ls.c
Executable file
118
labcodes_answer/lab8_result/user/ls.c
Executable file
@@ -0,0 +1,118 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dir.h>
|
||||
#include <file.h>
|
||||
#include <stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define printf(...) fprintf(1, __VA_ARGS__)
|
||||
#define BUFSIZE 4096
|
||||
|
||||
static char
|
||||
getmode(uint32_t st_mode) {
|
||||
char mode = '?';
|
||||
if (S_ISREG(st_mode)) mode = '-';
|
||||
if (S_ISDIR(st_mode)) mode = 'd';
|
||||
if (S_ISLNK(st_mode)) mode = 'l';
|
||||
if (S_ISCHR(st_mode)) mode = 'c';
|
||||
if (S_ISBLK(st_mode)) mode = 'b';
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int
|
||||
getstat(const char *name, struct stat *stat) {
|
||||
int fd, ret;
|
||||
if ((fd = open(name, O_RDONLY)) < 0) {
|
||||
return fd;
|
||||
}
|
||||
ret = fstat(fd, stat);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lsstat(struct stat *stat, const char *filename) {
|
||||
printf(" [%c]", getmode(stat->st_mode));
|
||||
printf(" %3d(h)", stat->st_nlinks);
|
||||
printf(" %8d(b)", stat->st_blocks);
|
||||
printf(" %8d(s)", stat->st_size);
|
||||
printf(" %s\n", filename);
|
||||
}
|
||||
|
||||
int
|
||||
lsdir(const char *path) {
|
||||
struct stat __stat, *stat = &__stat;
|
||||
int ret;
|
||||
DIR *dirp = opendir(".");
|
||||
|
||||
if (dirp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
struct dirent *direntp;
|
||||
while ((direntp = readdir(dirp)) != NULL) {
|
||||
if ((ret = getstat(direntp->name, stat)) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
lsstat(stat, direntp->name);
|
||||
}
|
||||
printf("lsdir: step 4\n");
|
||||
closedir(dirp);
|
||||
return 0;
|
||||
failed:
|
||||
closedir(dirp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ls(const char *path) {
|
||||
struct stat __stat, *stat = &__stat;
|
||||
int ret, type;
|
||||
if ((ret = getstat(path, stat)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *filetype[] = {
|
||||
" [ file ]",
|
||||
" [directory]",
|
||||
" [ symlink ]",
|
||||
" [character]",
|
||||
" [ block ]",
|
||||
" [ ????? ]",
|
||||
};
|
||||
switch (getmode(stat->st_mode)) {
|
||||
case '0': type = 0; break;
|
||||
case 'd': type = 1; break;
|
||||
case 'l': type = 2; break;
|
||||
case 'c': type = 3; break;
|
||||
case 'b': type = 4; break;
|
||||
default: type = 5; break;
|
||||
}
|
||||
|
||||
printf(" @ is %s", filetype[type]);
|
||||
printf(" %d(hlinks)", stat->st_nlinks);
|
||||
printf(" %d(blocks)", stat->st_blocks);
|
||||
printf(" %d(bytes) : @'%s'\n", stat->st_size, path);
|
||||
if (S_ISDIR(stat->st_mode)) {
|
||||
return lsdir(path);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
if (argc == 1) {
|
||||
return ls(".");
|
||||
}
|
||||
else {
|
||||
int i, ret;
|
||||
for (i = 1; i < argc; i ++) {
|
||||
if ((ret = ls(argv[i])) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
84
labcodes_answer/lab8_result/user/matrix.c
Normal file
84
labcodes_answer/lab8_result/user/matrix.c
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MATSIZE 10
|
||||
|
||||
static int mata[MATSIZE][MATSIZE];
|
||||
static int matb[MATSIZE][MATSIZE];
|
||||
static int matc[MATSIZE][MATSIZE];
|
||||
|
||||
void
|
||||
work(unsigned int times) {
|
||||
int i, j, k, size = MATSIZE;
|
||||
for (i = 0; i < size; i ++) {
|
||||
for (j = 0; j < size; j ++) {
|
||||
mata[i][j] = matb[i][j] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
yield();
|
||||
|
||||
cprintf("pid %d is running (%d times)!.\n", getpid(), times);
|
||||
|
||||
while (times -- > 0) {
|
||||
for (i = 0; i < size; i ++) {
|
||||
for (j = 0; j < size; j ++) {
|
||||
matc[i][j] = 0;
|
||||
for (k = 0; k < size; k ++) {
|
||||
matc[i][j] += mata[i][k] * matb[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < size; i ++) {
|
||||
for (j = 0; j < size; j ++) {
|
||||
mata[i][j] = matb[i][j] = matc[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
cprintf("pid %d done!.\n", getpid());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
const int total = 21;
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int pids[total];
|
||||
memset(pids, 0, sizeof(pids));
|
||||
|
||||
int i;
|
||||
for (i = 0; i < total; i ++) {
|
||||
if ((pids[i] = fork()) == 0) {
|
||||
srand(i * i);
|
||||
int times = (((unsigned int)rand()) % total);
|
||||
times = (times * times + 10) * 100;
|
||||
work(times);
|
||||
}
|
||||
if (pids[i] < 0) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
cprintf("fork ok.\n");
|
||||
|
||||
for (i = 0; i < total; i ++) {
|
||||
if (wait() != 0) {
|
||||
cprintf("wait failed.\n");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
cprintf("matrix pass.\n");
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
for (i = 0; i < total; i ++) {
|
||||
if (pids[i] > 0) {
|
||||
kill(pids[i]);
|
||||
}
|
||||
}
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
11
labcodes_answer/lab8_result/user/pgdir.c
Normal file
11
labcodes_answer/lab8_result/user/pgdir.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("I am %d, print pgdir.\n", getpid());
|
||||
print_pgdir();
|
||||
cprintf("pgdir pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
80
labcodes_answer/lab8_result/user/priority.c
Normal file
80
labcodes_answer/lab8_result/user/priority.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TOTAL 5
|
||||
/* to get enough accuracy, MAX_TIME (the running time of each process) should >1000 mseconds. */
|
||||
#define MAX_TIME 2000
|
||||
#define SLEEP_TIME 400
|
||||
unsigned int acc[TOTAL];
|
||||
int status[TOTAL];
|
||||
int pids[TOTAL];
|
||||
|
||||
static void
|
||||
spin_delay(void)
|
||||
{
|
||||
int i;
|
||||
volatile int j;
|
||||
for (i = 0; i != 200; ++ i)
|
||||
{
|
||||
j = !j;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int i,time;
|
||||
cprintf("priority process will sleep %d ticks\n",SLEEP_TIME);
|
||||
sleep(SLEEP_TIME);
|
||||
memset(pids, 0, sizeof(pids));
|
||||
lab6_set_priority(TOTAL + 1);
|
||||
|
||||
for (i = 0; i < TOTAL; i ++) {
|
||||
acc[i]=0;
|
||||
if ((pids[i] = fork()) == 0) {
|
||||
lab6_set_priority(i + 1);
|
||||
acc[i] = 0;
|
||||
while (1) {
|
||||
spin_delay();
|
||||
++ acc[i];
|
||||
if(acc[i]%4000==0) {
|
||||
if((time=gettime_msec())>MAX_TIME) {
|
||||
cprintf("child pid %d, acc %d, time %d\n",getpid(),acc[i],time);
|
||||
exit(acc[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (pids[i] < 0) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
cprintf("main: fork ok,now need to wait pids.\n");
|
||||
|
||||
for (i = 0; i < TOTAL; i ++) {
|
||||
status[i]=0;
|
||||
waitpid(pids[i],&status[i]);
|
||||
cprintf("main: pid %d, acc %d, time %d\n",pids[i],status[i],gettime_msec());
|
||||
}
|
||||
cprintf("main: wait pids over\n");
|
||||
cprintf("stride sched correct result:");
|
||||
for (i = 0; i < TOTAL; i ++)
|
||||
{
|
||||
cprintf(" %d", (status[i] * 2 / status[0] + 1) / 2);
|
||||
}
|
||||
cprintf("\n");
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
for (i = 0; i < TOTAL; i ++) {
|
||||
if (pids[i] > 0) {
|
||||
kill(pids[i]);
|
||||
}
|
||||
}
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
254
labcodes_answer/lab8_result/user/sh.c
Executable file
254
labcodes_answer/lab8_result/user/sh.c
Executable file
@@ -0,0 +1,254 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dir.h>
|
||||
#include <file.h>
|
||||
#include <error.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define printf(...) fprintf(1, __VA_ARGS__)
|
||||
#define putc(c) printf("%c", c)
|
||||
|
||||
#define BUFSIZE 4096
|
||||
#define WHITESPACE " \t\r\n"
|
||||
#define SYMBOLS "<|>&;"
|
||||
|
||||
char shcwd[BUFSIZE];
|
||||
|
||||
int
|
||||
gettoken(char **p1, char **p2) {
|
||||
char *s;
|
||||
if ((s = *p1) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
while (strchr(WHITESPACE, *s) != NULL) {
|
||||
*s ++ = '\0';
|
||||
}
|
||||
if (*s == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*p2 = s;
|
||||
int token = 'w';
|
||||
if (strchr(SYMBOLS, *s) != NULL) {
|
||||
token = *s, *s ++ = '\0';
|
||||
}
|
||||
else {
|
||||
bool flag = 0;
|
||||
while (*s != '\0' && (flag || strchr(WHITESPACE SYMBOLS, *s) == NULL)) {
|
||||
if (*s == '"') {
|
||||
*s = ' ', flag = !flag;
|
||||
}
|
||||
s ++;
|
||||
}
|
||||
}
|
||||
*p1 = (*s != '\0' ? s : NULL);
|
||||
return token;
|
||||
}
|
||||
|
||||
char *
|
||||
readline(const char *prompt) {
|
||||
static char buffer[BUFSIZE];
|
||||
if (prompt != NULL) {
|
||||
printf("%s", prompt);
|
||||
}
|
||||
int ret, i = 0;
|
||||
while (1) {
|
||||
char c;
|
||||
if ((ret = read(0, &c, sizeof(char))) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
if (i > 0) {
|
||||
buffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (c == 3) {
|
||||
return NULL;
|
||||
}
|
||||
else if (c >= ' ' && i < BUFSIZE - 1) {
|
||||
putc(c);
|
||||
buffer[i ++] = c;
|
||||
}
|
||||
else if (c == '\b' && i > 0) {
|
||||
putc(c);
|
||||
i --;
|
||||
}
|
||||
else if (c == '\n' || c == '\r') {
|
||||
putc(c);
|
||||
buffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void) {
|
||||
printf("usage: sh [command-file]\n");
|
||||
}
|
||||
|
||||
int
|
||||
reopen(int fd2, const char *filename, uint32_t open_flags) {
|
||||
int ret, fd1;
|
||||
close(fd2);
|
||||
if ((ret = open(filename, open_flags)) >= 0 && ret != fd2) {
|
||||
close(fd2);
|
||||
fd1 = ret, ret = dup2(fd1, fd2);
|
||||
close(fd1);
|
||||
}
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
int
|
||||
testfile(const char *name) {
|
||||
int ret;
|
||||
if ((ret = open(name, O_RDONLY)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
close(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
runcmd(char *cmd) {
|
||||
static char argv0[BUFSIZE];
|
||||
const char *argv[EXEC_MAX_ARG_NUM + 1];
|
||||
char *t;
|
||||
int argc, token, ret, p[2];
|
||||
again:
|
||||
argc = 0;
|
||||
while (1) {
|
||||
switch (token = gettoken(&cmd, &t)) {
|
||||
case 'w':
|
||||
if (argc == EXEC_MAX_ARG_NUM) {
|
||||
printf("sh error: too many arguments\n");
|
||||
return -1;
|
||||
}
|
||||
argv[argc ++] = t;
|
||||
break;
|
||||
case '<':
|
||||
if (gettoken(&cmd, &t) != 'w') {
|
||||
printf("sh error: syntax error: < not followed by word\n");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = reopen(0, t, O_RDONLY)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (gettoken(&cmd, &t) != 'w') {
|
||||
printf("sh error: syntax error: > not followed by word\n");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = reopen(1, t, O_RDWR | O_TRUNC | O_CREAT)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
// if ((ret = pipe(p)) != 0) {
|
||||
// return ret;
|
||||
// }
|
||||
if ((ret = fork()) == 0) {
|
||||
close(0);
|
||||
if ((ret = dup2(p[0], 0)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
close(p[0]), close(p[1]);
|
||||
goto again;
|
||||
}
|
||||
else {
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
close(1);
|
||||
if ((ret = dup2(p[1], 1)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
close(p[0]), close(p[1]);
|
||||
goto runit;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
goto runit;
|
||||
case ';':
|
||||
if ((ret = fork()) == 0) {
|
||||
goto runit;
|
||||
}
|
||||
else {
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
waitpid(ret, NULL);
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("sh error: bad return %d from gettoken\n", token);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
runit:
|
||||
if (argc == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[0], "cd") == 0) {
|
||||
if (argc != 2) {
|
||||
return -1;
|
||||
}
|
||||
strcpy(shcwd, argv[1]);
|
||||
return 0;
|
||||
}
|
||||
if ((ret = testfile(argv[0])) != 0) {
|
||||
if (ret != -E_NOENT) {
|
||||
return ret;
|
||||
}
|
||||
snprintf(argv0, sizeof(argv0), "/%s", argv[0]);
|
||||
argv[0] = argv0;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
return __exec(NULL, argv);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
printf("user sh is running!!!");
|
||||
int ret, interactive = 1;
|
||||
if (argc == 2) {
|
||||
if ((ret = reopen(0, argv[1], O_RDONLY)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
interactive = 0;
|
||||
}
|
||||
else if (argc > 2) {
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
//shcwd = malloc(BUFSIZE);
|
||||
assert(shcwd != NULL);
|
||||
|
||||
char *buffer;
|
||||
while ((buffer = readline((interactive) ? "$ " : NULL)) != NULL) {
|
||||
shcwd[0] = '\0';
|
||||
int pid;
|
||||
if ((pid = fork()) == 0) {
|
||||
ret = runcmd(buffer);
|
||||
exit(ret);
|
||||
}
|
||||
assert(pid >= 0);
|
||||
if (waitpid(pid, &ret) == 0) {
|
||||
if (ret == 0 && shcwd[0] != '\0') {
|
||||
ret = 0;
|
||||
}
|
||||
if (ret != 0) {
|
||||
printf("error: %d - %e\n", ret, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
28
labcodes_answer/lab8_result/user/sleep.c
Normal file
28
labcodes_answer/lab8_result/user/sleep.c
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
void
|
||||
sleepy(int pid) {
|
||||
int i, time = 100;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
sleep(time);
|
||||
cprintf("sleep %d x %d slices.\n", i + 1, time);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
unsigned int time = gettime_msec();
|
||||
int pid1, exit_code;
|
||||
|
||||
if ((pid1 = fork()) == 0) {
|
||||
sleepy(pid1);
|
||||
}
|
||||
|
||||
assert(waitpid(pid1, &exit_code) == 0 && exit_code == 0);
|
||||
cprintf("use %04d msecs.\n", gettime_msec() - time);
|
||||
cprintf("sleep pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
18
labcodes_answer/lab8_result/user/sleepkill.c
Normal file
18
labcodes_answer/lab8_result/user/sleepkill.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int pid;
|
||||
if ((pid = fork()) == 0) {
|
||||
sleep(~0);
|
||||
exit(0xdead);
|
||||
}
|
||||
assert(pid > 0);
|
||||
|
||||
sleep(100);
|
||||
assert(kill(pid) == 0);
|
||||
cprintf("sleepkill pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
9
labcodes_answer/lab8_result/user/softint.c
Normal file
9
labcodes_answer/lab8_result/user/softint.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
asm volatile("int $14");
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
32
labcodes_answer/lab8_result/user/spin.c
Normal file
32
labcodes_answer/lab8_result/user/spin.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int pid, ret, i ,j;
|
||||
cprintf("I am the parent. Forking the child...\n");
|
||||
pid = fork();
|
||||
if (pid== 0) {
|
||||
cprintf("I am the child. spinning ...\n");
|
||||
while (1);
|
||||
}else if (pid<0) {
|
||||
panic("fork child error\n");
|
||||
}
|
||||
cprintf("I am the parent. Running the child...\n");
|
||||
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
|
||||
cprintf("I am the parent. Killing the child...\n");
|
||||
|
||||
assert((ret = kill(pid)) == 0);
|
||||
cprintf("kill returns %d\n", ret);
|
||||
|
||||
assert((ret = waitpid(pid, NULL)) == 0);
|
||||
cprintf("wait returns %d\n", ret);
|
||||
|
||||
cprintf("spin may pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
33
labcodes_answer/lab8_result/user/testbss.c
Normal file
33
labcodes_answer/lab8_result/user/testbss.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <ulib.h>
|
||||
|
||||
#define ARRAYSIZE (1024*1024)
|
||||
|
||||
uint32_t bigarray[ARRAYSIZE];
|
||||
|
||||
int
|
||||
main(void) {
|
||||
cprintf("Making sure bss works right...\n");
|
||||
int i;
|
||||
for (i = 0; i < ARRAYSIZE; i ++) {
|
||||
if (bigarray[i] != 0) {
|
||||
panic("bigarray[%d] isn't cleared!\n", i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAYSIZE; i ++) {
|
||||
bigarray[i] = i;
|
||||
}
|
||||
for (i = 0; i < ARRAYSIZE; i ++) {
|
||||
if (bigarray[i] != i) {
|
||||
panic("bigarray[%d] didn't hold its value!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
cprintf("Yes, good. Now doing a wild write off the end...\n");
|
||||
cprintf("testbss may pass.\n");
|
||||
|
||||
bigarray[ARRAYSIZE + 1024] = 0;
|
||||
asm volatile ("int $0x14");
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
59
labcodes_answer/lab8_result/user/waitkill.c
Normal file
59
labcodes_answer/lab8_result/user/waitkill.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
do_yield(void) {
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
yield();
|
||||
}
|
||||
|
||||
int parent, pid1, pid2;
|
||||
|
||||
void
|
||||
loop(void) {
|
||||
cprintf("child 1.\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
void
|
||||
work(void) {
|
||||
cprintf("child 2.\n");
|
||||
do_yield();
|
||||
if (kill(parent) == 0) {
|
||||
cprintf("kill parent ok.\n");
|
||||
do_yield();
|
||||
if (kill(pid1) == 0) {
|
||||
cprintf("kill child1 ok.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
parent = getpid();
|
||||
if ((pid1 = fork()) == 0) {
|
||||
loop();
|
||||
}
|
||||
|
||||
assert(pid1 > 0);
|
||||
|
||||
if ((pid2 = fork()) == 0) {
|
||||
work();
|
||||
}
|
||||
if (pid2 > 0) {
|
||||
cprintf("wait child 1.\n");
|
||||
waitpid(pid1, NULL);
|
||||
panic("waitpid %d returns\n", pid1);
|
||||
}
|
||||
else {
|
||||
kill(pid1);
|
||||
}
|
||||
panic("FAIL: T.T\n");
|
||||
}
|
||||
|
||||
16
labcodes_answer/lab8_result/user/yield.c
Normal file
16
labcodes_answer/lab8_result/user/yield.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <ulib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int i;
|
||||
cprintf("Hello, I am process %d.\n", getpid());
|
||||
for (i = 0; i < 5; i ++) {
|
||||
yield();
|
||||
cprintf("Back in process %d, iteration %d.\n", getpid(), i);
|
||||
}
|
||||
cprintf("All done in process %d.\n", getpid());
|
||||
cprintf("yield pass.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user