xv6系列 util实验
Sleep
没啥难度,主要调用系统调用 sleep
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
char *err1 = "not right\0";
char *err2 = "sleep wrong\0";
if (argc != 2) {
write(2, err1, strlen(err1));
}
int n = atoi(argv[1]);
int ret = sleep(n);
if (ret < 0) {
write(2, err2, strlen(err2));
}
exit(0);
}
pingpong
熟悉一下fork以及pipe的用法,xv6 book介绍比较详细
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
char *err1 = "len(argc) not right\n0";
// char *err2 = "pipe faile\0";
char *err3 = "fork faile\0";
char buf[8];
if (argc != 1) {
write(2, err1, strlen(err1));
exit(1);
}
int p[2];
pipe(p);
int pid = fork();
if (pid < 0) {
write(2, err3, strlen(err3));
exit(1);
}
if (pid == 0) {
// child receive one byte
if (read(p[0], buf, 1) == 1) {
printf("%d: received pong\n", getpid());
}
// child send one byte
write(p[1], "c", 1);
exit(0);
}
// parent send one byte
write(p[1], "p", 1);
// parent receive one byte
if (read(p[0], buf, 1) == 1) {
printf("%d: received ping\n", getpid());
}
exit(0);
}
primes
看网上到处都是递归版本,实际只要找到循环节是啥即可
有两个注意的细节点
1. close要放在前面,只读不写的需要先把写close了,否则另一个子进程可能会卡死
2. wait需要加一下,否则输出容易串场
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
char *err1 = "fork failed\0";
int prev[2];
pipe(prev);
int pid = fork();
if (pid < 0) {
write(2, err1, strlen(err1));
exit(1);
}
if (pid == 0) {
while(1) {
int base = 0;
close(prev[1]); // 有两个点需要注意,这个close要放在前面,只读不写的需要先把写close了;wait需要加一下,否则容易串场
if(0 == read(prev[0], &base, sizeof(base))) {
// printf("read == 0\n");
close(prev[0]);
exit(0);
}
// printf("read <- %d\n", base);
printf("prime %d\n", base);
int next[2];
pipe(next);
int pid = fork();
if (pid < 0) {
write(2, err1, strlen(err1));
exit(1);
}
// parent
if (pid > 0) {
int cur = 0;
for(;0 != read(prev[0], &cur, sizeof(cur));) {
if (0 != cur % base) {
write(next[1], &cur, sizeof(cur));
}
}
close(prev[0]);
close(next[0]);
close(next[1]);
wait(0);
exit(0);
}
// child
close(prev[0]);
prev[0] = next[0];
prev[1] = next[1];
}
exit(0);
}
// parent
close(prev[0]);
for (int i = 2;i <= 32;i++) {
// printf("write -> %d\n", i);
write(prev[1], &i, sizeof(i));
}
close(prev[1]);
wait(0);
exit(0);
}
find
- pfilename是稍微改了ls.c的fmtfilename
- c语言中的字符串最后末尾不上 0
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
char*
pfilename(char *path)
{
char *p;
// Find first character after last slash.
for(p=path+strlen(path); p >= path && *p != '/'; p--)
;
p++;
return p;
}
int find(char *path, char *filename) {
int fd;
char buf[512], *p;
struct stat st;
struct dirent de;
if ((fd = open(path, 0)) < 0) {
fprintf(2, "find: cannot open %s\n", path);
return -1;
}
if(fstat(fd, &st) < 0) {
fprintf(2, "find: cannot stat %s\n", path);
close(fd);
return -1;
}
switch(st.type) {
case T_FILE:
if(0 == strcmp(pfilename(path), filename)) {
fprintf(1, "%s\n", path);
}
break;
case T_DIR:
strcpy(buf, path);
p = buf + strlen(buf);
*p++='/';
while(read(fd, &de, sizeof(de)) == sizeof(de)) {
if(de.inum == 0) {
continue;
}
if(0 == strcmp(".", de.name) || 0 == strcmp("..", de.name)) {
continue;
}
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0) {
printf("find: cannot stat %s\n", buf);
continue;
}
find(buf, filename);
}
break;
}
close(fd);
return 0;
}
int
main(int argc, char *argv[])
{
if (argc < 3) {
fprintf(2, "not enough arguments\n");
exit(1);
}
find(argv[1], argv[2]);
exit(0);
}