1. Lab Utilities¶
sleep¶
参照echo.c
,直接调用system的函数即可
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *argv[])
{
int n;
if (argc < 2) {
fprintf(2, "Please enter a number.\n");
exit(1);
}
n = atoi(argv[1]);
sleep(n);
exit(0);
}
然后在 makefile
的UPROGS
下面加上相应内容。
pingpoing¶
使用到了 fork
和 pipe
参考pipe() System call - GeeksforGeeks
p[0] 读数据 p[1] 写数据
不用的需要关闭
#include <kernel/types.h>
#include <kernel/stat.h>
#include <user/user.h>
int main(int argc, char *argv[]) {
int p[2];
if (pipe(p) < 0)
exit(1);
int pid = fork();
if (pid > 0) {
char buf;
write(p[1], argv[1], 1);
close(p[1]);
read(p[0],&buf,1);
close(p[0]);
printf("%d: received pong\n", getpid());
} else {
char buf;
read(p[0],&buf, 1);// 当p[0]没有数据时,这个进程会被挂起,进行等待。
close(p[0]);
printf("%d: received ping\n",getpid());
write(p[1], &buf, 1);
close(p[1]);
}
exit(0);
}
int pipe(int fds[2]);
Parameters : fd[0] will be the fd(file descriptor) for the read end of pipe. fd[1] will be the fd for the write end of pipe. Returns : 0 on Success. -1 on error.
primes¶
要求编写并发版本的质数筛
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
void process(int left[]) {
char p;
read(left[0], &p, 1);
printf("prime %d\n", p);
int num = 0;
if (read(left[0], &num, 1) == 0) { // 到达结尾 管道关闭
return;
}
int right[2];
pipe(right);
int pid = fork();
if (pid == 0) {
close(left[0]);
close(right[1]);
process(right);
close(right[0]);
} else if (pid > 0) {
close(right[0]);
do {
if (num % p != 0) {
write(right[1], &num, 1);
}
} while(read(left[0],&num,1) != 0);
close(left[0]);
close(right[1]);
wait(0);
} else {
printf("Error.\n");
exit(1);
}
}
int main() {
int right[2];
pipe(right);
int pid = fork();
if (pid == 0) {
close(right[1]);
process(right);
close(right[0]);
} else if (pid > 0) {
close(right[0]);
for (int i = 2; i <= 35; i++) { // 传数
char buf = i;
write(right[1], &buf, 1);
}
close(right[1]);
wait(0);
} else {
printf("Error.\n");
close(right[0]);
close(right[1]);
exit(1);
}
exit(0);
}
read()
函数返回成功读取的字节数。如果返回值为0,则表示已到达文件末尾(end-of-file)。
当使用read()
函数从管道中读取数据时,如果没有数据可供读取且管道中不再有任何写入端(也就是所有写入端都已关闭),read()
函数将会返回0,表示已到达文件末尾(end-of-file)。
find¶
#include "kernel/types.h"
#include "kernel/fs.h"
#include "kernel/stat.h"
#include "user/user.h"
char *fmtname(char *path) { // 返回最后一个'/'之后的内容
static char buf[DIRSIZ + 1];
char *p;
// Find first character after last slash.
for (p = path + strlen(path); p >= path && *p != '/'; p--)
;
p++;
// Return blank-padded name.
if (strlen(p) >= DIRSIZ)
return p;
memmove(buf, p, strlen(p));
memset(buf + strlen(p), 0, DIRSIZ - strlen(p)); // 把’ ’改成0
return buf;
}
int norecurse(char *path) { // 判断能否递归
char* buf = fmtname(path);
if(buf[0] == '.' && buf[1] == 0) {
return 1;
}
if(buf[0] == '.' && buf[1] == '.' && buf[2] == 0) {
return 1;
}
return 0;
}
void find(char *path,char *target) {
//printf("%s\n",path);
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;
}
//printf("path: %s; traget: %s;\n",path,target);
if (strcmp(fmtname(path),target) == 0) {
printf("%s\n",path);
}
switch(st.type){
case T_FILE:
// printf("%s %d %d %l\n", fmtname(path), st.type, st.ino, st.size);
break;
case T_DIR:
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
printf("ls: 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;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0){
printf("ls: cannot stat %s\n", buf);
continue;
}
// if (strcmp(fmtname(buf), target) == 0) {
// printf("%s\n",buf);
// }
//printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
if(norecurse(buf) == 0) {
find(buf,target);
}
}
break;
}
close(fd);
}
int main(int argc, char *argv[]) {
if(argc < 2) {
printf("usage: find [path] [target]\n");
exit(1);
}
if (argc < 3) {
find(".", argv[1]);
exit(0);
}
if(argc <4) {
find(argv[1], argv[2]);
exit(0);
}
printf("usage: find [path] [target\n]");
exit(1);
}
xargs¶
$ echo hello too | xargs echo bye
bye hello too
$
$ find . b | xargs grep hello
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/param.h"
# define MAXSIZE 2048
int main(int argc,char *argv[]) {
char buf[MAXSIZE];
// 获取标准化输入
int buf_idx = 0;
int n = read(0,buf,MAXSIZE); // 防止输入时间过长,需要一直读取
while (n>0) {
buf_idx += n;
n = read(0,&buf[buf_idx],MAXSIZE);
}
// for(int i=0;i<MAXSIZE;i++) {
// printf("%c",buf[i]);
// }
// printf("\n");
// 处理参数
char *xargv[MAXARG];
int xargc = 0;
for (int i=1; i<argc;i++) {
xargv[xargc] = argv[i];
xargc++;
}
char *p = buf;
for (int i = 0; i < MAXSIZE; i++) {
if(buf[i] == '\n') { //对每一行输入分别处理
int pid = fork();
if (pid == 0) {
buf[i] = 0;
xargv[xargc] = p; // 把参数加到最后
xargc ++ ;
xargv[xargc] = 0;
xargc++;
exec(xargv[0],xargv); // 执行程序
exit(0);
} else if (pid > 0) {
wait(0);
p = &buf[i+1];
} else {
printf("fork error.\n");
exit(1);
}
}
}
exit(0);
}