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/_wc\
|
||||
$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