6.s081 Lab1: Xv6 and Unix utilities
先贴上代码,之后完善相应描述。
sleep
#include "kernel/types.h"
#include "user/user.h"
int main(int argc, const char *argv[]) {
if (argc != 2) {
fprintf(2, "Usage: sleep <ticks>\n");
exit(1);
}
int ticks = atoi(argv[1]);
if (ticks < 0) {
fprintf(2, "error: ticks should be larger than 0\n");
exit(1);
}
sleep(ticks);
exit(0);
}
pingpong
#include "kernel/types.h"
#include "user/user.h"
#include "kernel/stat.h"
#define PIPE_SIZE (2)
#define READ 0
#define WRITE 1
int main(int argc, const char *argv[]) {
// 父->子管道
int pc_pipe[PIPE_SIZE];
pipe(pc_pipe);
// 子->父管道
int cp_pipe[PIPE_SIZE];
pipe(cp_pipe);
char p_msg, c_msg;
int pid = fork();
if (pid < 0) {
fprintf(2, "error: fork() error\n");
exit(1);
} else if (pid == 0) {
// 子进程先从pc_pipe中读
// 再从cp_pipe中写
close(pc_pipe[WRITE]);
close(cp_pipe[READ]);
if (read(pc_pipe[READ], &c_msg, 1) == 1) {
fprintf(1, "%d: received ping\n", getpid());
close(pc_pipe[READ]);
write(cp_pipe[WRITE], "c", 1);
close(cp_pipe[WRITE]);
exit(0);
} else {
fprintf(2, "error: child not receive or receive not a byte\n");
exit(1);
}
} else {
// 父进程先向pc_pipe中写
// 再从cp_pipe中读
close(pc_pipe[READ]);
close(cp_pipe[WRITE]);
write(pc_pipe[WRITE], "p", 1);
close(pc_pipe[WRITE]);
if (read(cp_pipe[READ], &p_msg, 1) == 1) {
fprintf(1, "%d: received pong\n", getpid());
close(cp_pipe[READ]);
} else {
fprintf(2, "error: parent not receive or receive not a byte\n");
exit(1);
}
}
exit(0);
}
primes
#include "kernel/types.h"
#include "user/user.h"
#include "kernel/stat.h"
#define PIPE_SIZE (2)
#define READ (0)
#define WRITE (1)
void filter(int fds[]);
int main(int argc, char *argv[]) {
int fds[PIPE_SIZE];
pipe(fds);
int pid = fork();
if (pid < 0) {
fprintf(2, "error: fork() error\n");
exit(1);
}
if (pid == 0) {
// 子进程递归调用filter
filter(fds);
} else {
// 父进程向子进程发送,在子进程中进行过滤
close(fds[READ]);
for (int i = 2; i <= 35; ++i) {
write(fds[WRITE], &i, sizeof(i));
}
close(fds[WRITE]);
wait(0);
}
exit(0);
}
void filter(int fds[]) {
close(fds[WRITE]);
int prime = 0;
// 接收到的第一个数一定为素数
if (read(fds[READ], &prime, sizeof(prime)) <= 0)
return;
printf("prime %d\n", prime);
int new_pipe[PIPE_SIZE];
pipe(new_pipe);
int pid = fork();
if (pid < 0) {
fprintf(2, "error: fork() error\n");
exit(1);
}
if (pid == 0) {
filter(new_pipe);
} else {
int value = 0;
close(new_pipe[READ]);
// 对父进程通过管道传递的数进行过滤,再通过另一个管道传到子进程
while (read(fds[READ], &value, sizeof(value)) > 0) {
if (value % prime == 0)
continue;
write(new_pipe[WRITE], &value, sizeof(value));
}
close(fds[READ]);
close(new_pipe[WRITE]);
wait(0);
}
exit(0);
}
find
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
void find(char *path, char *filename);
int main(int argc, char *argv[])
{
if (argc < 2 || argc > 3)
{
fprintf(2, "Usage: find [<path>] <filename>\n");
exit(1);
}
// 默认从当前目录开始寻找
if (argc == 2)
{
find(".", argv[1]);
exit(0);
}
find(argv[1], argv[2]);
exit(0);
}
void find(char *path, char *filename)
{
struct stat st;
struct dirent de;
char buf[512], *p;
int fd = open(path, 0);
if (fd < 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_FILE:
// 若为文件,则直接比较当前文件名和给定文件名
// 需要把当前文件名从路径中抽取出来
p = path + strlen(path);
while (p >= path && *p != '/')
--p;
++p;
if (strcmp(p, filename) == 0)
{
printf("%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 || strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = '\0';
find(buf, filename);
}
break;
}
close(fd);
}
xargs
#include "kernel/types.h"
#include "user/user.h"
#include "kernel/param.h"
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(2, "error: too few arguments\n");
exit(1);
}
if (argc >= MAXARG) {
fprintf(2, "error: too many arguments\n");
exit(1);
}
char *params[MAXARG];
// 记录原始命令行参数
// 下标从1开始,argv[0]为xargs
for (int i = 1; i < argc; ++i) {
params[i-1] = argv[i];
}
char buf[512];
while(1) {
// 将标准输入转换成命令行参数
int i = 0;
while(1) {
int n = read(0, buf + i, 1);
if (n <= 0 || buf[i++] == '\n')
break;
}
if (i == 0)
break;
buf[i-1] = '\0';
params[argc-1] = buf;
int pid = fork();
if (pid < 0) {
fprintf(2, "error: fork() error");
exit(1);
} else if (pid == 0) {
exec(argv[1], params);
exit(0);
} else {
wait(0);
}
}
exit(0);
}

浙公网安备 33010602011771号