lab util grade 100
This commit is contained in:
parent
dc9153fcb9
commit
8de6f45af1
5
Makefile
5
Makefile
@ -188,6 +188,11 @@ UPROGS=\
|
|||||||
$U/_grind\
|
$U/_grind\
|
||||||
$U/_wc\
|
$U/_wc\
|
||||||
$U/_zombie\
|
$U/_zombie\
|
||||||
|
$U/_sleep\
|
||||||
|
$U/_pingpong\
|
||||||
|
$U/_primes\
|
||||||
|
$U/_find\
|
||||||
|
$U/_xargs\
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
74
user/find.c
Normal file
74
user/find.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "kernel/types.h"
|
||||||
|
#include "user/user.h"
|
||||||
|
#include "kernel/stat.h"
|
||||||
|
#include "kernel/fs.h"
|
||||||
|
|
||||||
|
int fmtname(const char *path) {
|
||||||
|
int p;
|
||||||
|
for(p=strlen(path); p >= 0 && *(path + p) != '/'; p--);
|
||||||
|
p++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void find(const char *path, const char* target) {
|
||||||
|
char buf[512], *p;
|
||||||
|
int fd;
|
||||||
|
struct dirent de;
|
||||||
|
struct stat st;
|
||||||
|
if((fd = open(path, 0)) < 0){
|
||||||
|
fprintf(2, "find: cannot open %s\n", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fstat(fd, &st) < 0){
|
||||||
|
fprintf(2, "find: cannot stat %s\n", path);
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(st.type){
|
||||||
|
case T_DEVICE:
|
||||||
|
case T_FILE:
|
||||||
|
if (strcmp(path + fmtname(path), target) == 0) {
|
||||||
|
printf("%s\n", path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_DIR:
|
||||||
|
if (strcmp(path + fmtname(path), target) == 0) {
|
||||||
|
printf("%s\n", path);
|
||||||
|
}
|
||||||
|
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
|
||||||
|
printf("find: path too long\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strcpy(buf, path);
|
||||||
|
p = buf+strlen(buf);
|
||||||
|
*p++ = '/';
|
||||||
|
while(read(fd, &de, sizeof(de)) == sizeof(de)){
|
||||||
|
if(de.inum == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
memmove(p, de.name, DIRSIZ);
|
||||||
|
p[DIRSIZ] = 0;
|
||||||
|
if(stat(buf, &st) < 0){
|
||||||
|
printf("find: cannot stat %s\n", buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
find(buf, target);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("\x1b[31mInvalid arguments\x1b[0m\n");
|
||||||
|
printf("\x1b[32musage\x1b[0m: find <base directory> <file name to find>\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
find(argv[1], argv[2]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
27
user/pingpong.c
Normal file
27
user/pingpong.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "kernel/types.h"
|
||||||
|
#include "user/user.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int p[2]; // hell, read from p[0] and write to p[1] no matter in pa/ch
|
||||||
|
if (pipe(p) == -1) exit(1);
|
||||||
|
uint8 senddata[] = {0xAC};
|
||||||
|
uint8 recvdata[] = {0};
|
||||||
|
int pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
// child
|
||||||
|
if (read(p[0], recvdata, 1) != 1) printf("error child read\n");
|
||||||
|
close(p[0]);
|
||||||
|
printf("%d: received ping\n", getpid());
|
||||||
|
if (write(p[1], senddata, 1) != 1) printf("error child write\n");
|
||||||
|
close(p[1]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (write(p[1], senddata, 1) != 1) printf("error parent write\n");
|
||||||
|
close(p[1]);
|
||||||
|
if (read(p[0], recvdata, 1) != 1) printf("error parent read\n");
|
||||||
|
printf("%d: received pong\n", getpid());
|
||||||
|
close(p[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
user/primes.c
Normal file
51
user/primes.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "kernel/types.h"
|
||||||
|
#include "user/user.h"
|
||||||
|
|
||||||
|
void pipeline(int leftfd) {
|
||||||
|
int pipefd[2];
|
||||||
|
int p; read(leftfd, &p, sizeof(p));
|
||||||
|
printf("prime %d\n", p);
|
||||||
|
int n;
|
||||||
|
int has_right = 0;
|
||||||
|
while (read(leftfd, &n, sizeof(n)) > 0) {
|
||||||
|
if (n % p != 0) {
|
||||||
|
if (!has_right) {
|
||||||
|
has_right = 1;
|
||||||
|
pipe(pipefd);
|
||||||
|
if (fork() == 0) {
|
||||||
|
close(pipefd[1]);
|
||||||
|
pipeline(pipefd[0]);
|
||||||
|
} else {
|
||||||
|
close(pipefd[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write(pipefd[1], &n, sizeof(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(leftfd);
|
||||||
|
if (has_right) {
|
||||||
|
close(pipefd[1]);
|
||||||
|
while(wait(0) != -1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int pipefd[2];
|
||||||
|
pipe(pipefd);
|
||||||
|
int pid = fork();
|
||||||
|
if (pid != 0) {
|
||||||
|
close(pipefd[0]); // no need to read in the feeding proc
|
||||||
|
for (int i = 2; i <= 35; ++ i) {
|
||||||
|
write(pipefd[1], &i, sizeof(i));
|
||||||
|
}
|
||||||
|
close(pipefd[1]);
|
||||||
|
while(wait(0) != -1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
close(pipefd[1]); // pipeline proc will have its own write pipe
|
||||||
|
pipeline(pipefd[0]);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
17
user/sleep.c
Normal file
17
user/sleep.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "kernel/types.h"
|
||||||
|
#include "user/user.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("\x1b[31mUnexpected argument\x1b[0m\n");
|
||||||
|
printf("usage: sleep <ticks>\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
int ticks = atoi(argv[1]);
|
||||||
|
int ret = sleep(ticks);
|
||||||
|
if (ret) {
|
||||||
|
printf("\x1b[31mFailed to sleep\x1b[0m\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
59
user/xargs.c
Normal file
59
user/xargs.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "kernel/param.h"
|
||||||
|
#include "kernel/types.h"
|
||||||
|
#include "user/user.h"
|
||||||
|
|
||||||
|
static inline int is_ws(const char ch) {
|
||||||
|
return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
int STDIN = 0;
|
||||||
|
char linebuf[1024];
|
||||||
|
char* p = linebuf;
|
||||||
|
char* _argv[MAXARG];
|
||||||
|
while (read(STDIN, p, 1) > 0) {
|
||||||
|
if (*p == '\n') {
|
||||||
|
int i;
|
||||||
|
int in_ws = 1;
|
||||||
|
for (i = 0; i < argc - 1; ++i) {
|
||||||
|
_argv[i] = argv[i + 1];
|
||||||
|
}
|
||||||
|
for (char* p0 = linebuf; p0 <= p; ++p0) {
|
||||||
|
if (is_ws(*p0)) {
|
||||||
|
if (!in_ws) {
|
||||||
|
in_ws = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
*p0 = '\0';
|
||||||
|
} else if (in_ws) {
|
||||||
|
in_ws = 0;
|
||||||
|
_argv[i] = p0;
|
||||||
|
}
|
||||||
|
if (i >= MAXARG) {
|
||||||
|
printf("warning: too many arguments");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
_argv[i] = 0;
|
||||||
|
// for (int j = 0; j < i; ++ j) {
|
||||||
|
// printf("%s\n", _argv[j]);
|
||||||
|
// }
|
||||||
|
if (fork() == 0) {
|
||||||
|
exec(_argv[0], _argv);
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
p = linebuf;
|
||||||
|
while (wait(0) != -1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
if (p >= linebuf + sizeof(linebuf)) {
|
||||||
|
printf("line buffer exceeded\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user