diff options
author | Mole Shang <[email protected]> | 2024-01-17 11:33:39 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-01-17 11:33:39 +0800 |
commit | daa90a639a35e9f99747c92bb28946ac414615bd (patch) | |
tree | cc119f4e037015b2fdff2b4ed8d989b8db66e3b0 | |
parent | c424f997808269559f7968c812860fd1f1974a13 (diff) | |
download | xv6-labs-util.tar.gz xv6-labs-util.tar.bz2 xv6-labs-util.zip |
lab util: finishutil
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | user/find.c | 84 | ||||
-rw-r--r-- | user/pingpong.c | 44 | ||||
-rw-r--r-- | user/primes.c | 74 | ||||
-rw-r--r-- | user/sh.c | 3 | ||||
-rw-r--r-- | user/sleep.c | 22 | ||||
-rw-r--r-- | user/xargs.c | 60 |
7 files changed, 292 insertions, 0 deletions
@@ -188,6 +188,11 @@ UPROGS=\ $U/_grind\ $U/_wc\ $U/_zombie\ + $U/_sleep\ + $U/_pingpong\ + $U/_primes\ + $U/_find\ + $U/_xargs\ diff --git a/user/find.c b/user/find.c new file mode 100644 index 0000000..e185e9d --- /dev/null +++ b/user/find.c @@ -0,0 +1,84 @@ +#include "kernel/types.h" + +#include "kernel/fcntl.h" +#include "kernel/fs.h" +#include "kernel/stat.h" +#include "user/user.h" + +char* +fmtname(char* path) +{ + char* p; + + // Find first character after last slash. + for (p = path + strlen(path); p >= path && *p != '/'; p--) + ; + p++; + return p; +} + +void +find(char* root_path, char* filename) +{ + static char buf[512]; + char* p; + int fd; + struct dirent de; + struct stat st; + + if ((fd = open(root_path, O_RDONLY)) < 0) { + fprintf(2, "find: cannot open %s\n", root_path); + return; + } + if (fstat(fd, &st) < 0) { + fprintf(2, "find: cannot stat %s\n", root_path); + close(fd); + return; + } + + switch (st.type) { + case T_FILE: + if (!strcmp(fmtname(root_path), filename)) { + printf("%s\n", root_path); + } + break; + case T_DIR: + if (strlen(root_path) + 1 + DIRSIZ + 1 > sizeof(buf)) { + printf("find: path too long\n"); + break; + } + + strcpy(buf, root_path); + + p = buf + strlen(buf); + *p++ = '/'; + while (read(fd, &de, sizeof(de)) == sizeof(de)) { + if (de.inum == 0) + continue; + memmove(p, de.name, DIRSIZ); + p[DIRSIZ] = '\0'; + + // printf("i'm finding %s!\n", fmtname(buf)); + + if (!strcmp(fmtname(buf), ".") || !strcmp(fmtname(buf), "..")) { + continue; + } + + find(buf, filename); + } + } + close(fd); +} + +int +main(int argc, char* argv[]) +{ + if (argc < 3) { + fprintf(2, "usage: find [root_path] filename...\n"); + exit(1); + } + + for (int i = 2; i < argc; i++) { + find(argv[1], argv[i]); + } +} diff --git a/user/pingpong.c b/user/pingpong.c new file mode 100644 index 0000000..7b03a76 --- /dev/null +++ b/user/pingpong.c @@ -0,0 +1,44 @@ +#include "kernel/types.h" +#include "user/user.h" + +int +main(int argc, char* argv[]) +{ + int p[2]; + + if (argc > 1) { + fprintf(2, "usage: pingpong\n"); + exit(1); + } + + pipe(p); + + int pid = fork(); + + if (pid == 0) { + short n; + read(p[0], &n, sizeof(n)); + if (n == 42) { + fprintf(1, "%d: received ping\n", getpid()); + } + n++; + write(p[1], &n, sizeof(n)); + close(p[0]); + close(p[1]); + exit(0); + } + + short n = 42; + + write(p[1], &n, sizeof(n)); + read(p[0], &n, sizeof(n)); + if (n == 43) { + fprintf(1, "%d: received pong\n", getpid()); + } + close(p[0]); + close(p[1]); + + wait(0); + + exit(0); +} diff --git a/user/primes.c b/user/primes.c new file mode 100644 index 0000000..b359524 --- /dev/null +++ b/user/primes.c @@ -0,0 +1,74 @@ +#include "kernel/types.h" +#include "user/user.h" + +#define MAX 36 +#define FIRST_PRIME 2 + +int +generate_natural(); // -> out_fd +int +prime_filter(int in_fd, int prime); // -> out_fd + +int +main(int argc, char* argv[]) +{ + int prime; + + int in = generate_natural(); + while (read(in, &prime, sizeof(int))) { + // printf("prime %d: in_fd: %d\n", prime, in); // debug + printf("prime %d\n", prime); + in = prime_filter(in, prime); + } + + close(in); + + exit(0); +} + +int +generate_natural() +{ + int out_pipe[2]; + + pipe(out_pipe); + + if (!fork()) { + for (int i = FIRST_PRIME; i < MAX; i++) { + write(out_pipe[1], &i, sizeof(int)); + } + close(out_pipe[1]); + + exit(0); + } + + close(out_pipe[1]); + + return out_pipe[0]; +} + +int +prime_filter(int in_fd, int prime) +{ + int num; + int out_pipe[2]; + + pipe(out_pipe); + + if (!fork()) { + while (read(in_fd, &num, sizeof(int))) { + if (num % prime) { + write(out_pipe[1], &num, sizeof(int)); + } + } + close(in_fd); + close(out_pipe[1]); + + exit(0); + } + + close(in_fd); + close(out_pipe[1]); + + return out_pipe[0]; +} @@ -165,6 +165,9 @@ main(void) fprintf(2, "cannot cd %s\n", buf+3); continue; } + if(buf[0] == 'e' && buf[1] == 'x' && buf[2] == 'i' && buf[3] == 't'){ + exit(0); + } if(fork1() == 0) runcmd(parsecmd(buf)); wait(0); diff --git a/user/sleep.c b/user/sleep.c new file mode 100644 index 0000000..961f558 --- /dev/null +++ b/user/sleep.c @@ -0,0 +1,22 @@ +#include "kernel/types.h" +#include "user/user.h" + +int +main(int argc, char* argv[]) +{ + uint sec = 0; + + if (argc <= 1) { + fprintf(2, "usage: sleep [time (ticks)]\n"); + exit(1); + } + sec = atoi(argv[1]); + + sleep(sec); + + if (argc <= 2) { + exit(0); + } + + exit(0); +} diff --git a/user/xargs.c b/user/xargs.c new file mode 100644 index 0000000..b5b9bee --- /dev/null +++ b/user/xargs.c @@ -0,0 +1,60 @@ +#include "kernel/types.h" + +#include "kernel/param.h" +#include "kernel/stat.h" +#include "user/user.h" + +#define is_blank(chr) (chr == ' ' || chr == '\t') + +int +main(int argc, char* argv[]) +{ + char buf[2048], ch; + char* p = buf; + char* v[MAXARG]; + int c; + int blanks = 0; + int offset = 0; + + if (argc <= 1) { + fprintf(2, "usage: xargs <command> [argv...]\n"); + exit(1); + } + + for (c = 1; c < argc; c++) { + v[c - 1] = argv[c]; + } + --c; + + while (read(0, &ch, 1) > 0) { + if (is_blank(ch)) { + blanks++; + continue; + } + + if (blanks) { + buf[offset++] = 0; + + v[c++] = p; + p = buf + offset; + + blanks = 0; + } + + if (ch != '\n') { + buf[offset++] = ch; + } else { + v[c++] = p; + p = buf + offset; + + if (!fork()) { + exit(exec(v[0], v)); + } + wait(0); + + c = argc - 1; + } + } + + exit(0); +} |