2020 MIT6.s081 os Lab: Xv6 and Unix utilities


友情链接:全部实验哟

实验链接

https://pdos.csail.mit.edu/6.S081/2020/labs/util.html

Sleep

代码如下:

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{

  if(argc < 2){
    fprintf(2, "Usage:  sleep number seconds\n");
    exit(1);
  }

  int sleep_sec = atoi(argv[1]);
  sleep(sleep_sec);
  exit(0);
}


Pingpong

题意如下:

首先介绍一下管道:

  1. 管道只能从一段写入,另一端读出;
  2. 管道不是普通的文件,他存在于内存中,不存在于某个文件系统;
  3. 管道没有名字,只能在具有公共祖先的进程中使用;
  4. 半双工,同一时刻,只能在一个方向有数据流动。

代码如下:


#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{

  int pipefd[2];
  int cpid;
  char buf = 'c';
  if (pipe(pipefd) == -1) {
      printf("pipe error\n");
      exit(1);
  }

  cpid = fork();
  if (cpid == -1) {
      printf("fork error\n");
      exit(1);
  }

  if (cpid == 0) { // child process
      read(pipefd[0], &buf, 1);
      cpid = getpid();
      printf("%d: received ping\n", cpid);
      write(pipefd[1], &buf, 1);

  } else {
      write(pipefd[1], &buf, 1);
      // if we do not sleep here, the parent would read from the pipe, and the child would not be able to read from the pipe
      // if you do not want to sleep here, you should use two pipes instead of one
      sleep(1);
      read(pipefd[0], &buf, 1);
      cpid = getpid();
      printf("%d: received pong\n", cpid);
  }
  exit(0);
}


Primes

题意如下:

题目需要计算2至35之间的所有质数,步骤如下:

  1. 每个进程从自己的父进程读数据(第一个进程除外,因为其没有父进程),经过处理之后,将结果写到自己的孩子进程;
  2. 每个进程的处理过程如下:接收到的第一个数字必定为质数P,如果自己接收到数据能被P整除,那它肯定不是质数,则该数字不传给自己的孩子进程,否则,将其传给自己的孩子进程;
  3. 其实这和算法题中,计算指定区间的质数一样,先去除区间内所有能被2整除的数,在剩下的数字中再除去所有能被3整除的数,在剩下的数字中再除去所有能被5整除的数,依次类推。。。

代码如下:

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"


void work(int parent_pipe[]) {
    close(parent_pipe[1]);
    int child_pipe[2];

    int base;
    if (read(parent_pipe[0], &base, 4) == 0) {
        exit(0);
    }
    printf("prime %d\n", base);
    if (pipe(child_pipe) == -1) {
        printf("pipe error\n");
        exit(0);
    }

    int cpid = fork();
    if (cpid == -1) {
        printf("fork error\n");
        exit(1);
    }

    if (cpid != 0) { // parent
        close(child_pipe[0]);
        while (1) {
            int recv = 0;
            int ret = read(parent_pipe[0], &recv, sizeof(int));
            if (ret == 0) {
                break;
            }
            if (recv % base != 0) {
                int send = recv;
                write(child_pipe[1], &send, sizeof(int));
            }
        }
        close(parent_pipe[0]);
        close(child_pipe[1]);
        wait(0);
    } else {
        work(child_pipe);
    }
    exit(0);
}

int main(int argc, char *argv[]) {
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        printf("pipe error\n");
        exit(1);
    }

    int cpid = fork();
    if (cpid == -1) {
        printf("fork error\n");
        exit(1);
    }

    if (cpid == 0) { // child process
        work(pipefd);
    } else {
        close(pipefd[0]);
        // the first process pipe write all numbers to the next pipe
        for (int i = 2; i <= 35; i++) {
            write(pipefd[1], &i, sizeof(int));
        }
        close(pipefd[1]);
        wait(0);
    }
    exit(0);
}


find

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"


void get_files(const char* file_path, const char* file_name) {
    char buf[512], *p;
    int fd;
    struct dirent de;
    struct stat st;

    if((fd = open(file_path, 0)) < 0){
        fprintf(2, "find: cannot open %s\n", file_path);
        return;
    }

    if(fstat(fd, &st) < 0){
        fprintf(2, "find: cannot stat %s\n", file_path);
        close(fd);
        return;
    }

    switch(st.type) {
        case T_FILE:
            printf("Find a file instead of a path: %s\n", file_path);
            break;

        case T_DIR:
            if(strlen(file_path) + 1 + DIRSIZ + 1 > sizeof(buf)){
                printf("find: path too long\n");
                break;
            }
            strcpy(buf, file_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("ls: cannot stat %s\n", buf);
                    continue;
                }
                // printf("find a file: %s\n", de.name);
                if (st.type == T_DIR) {
                    get_files(buf, file_name);
                } else if (st.type == T_FILE) {
                    if (strcmp(file_name, de.name) == 0) {
                        printf("%s\n", buf);
                    }
                }
            }
            break;
    }
    close(fd);
}

int main(int argc, char *argv[])
{
    if(argc < 3) {
        printf("Usage: <path> <filename>\n");
        exit(0);
    }
    char* file_path = argv[1];
    char* file_name = argv[2];
    get_files(file_path, file_name);
    exit(0);
}


xargs

代码如下:


#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/param.h"

int
getcmd(char *buf, int nbuf)
{
    memset(buf, 0, nbuf);
    gets(buf, nbuf);
    if(buf[0] == 0) // EOF
        return -1;
    return 0;
}

int main(int argc, char *argv[])
{
    if(argc < 2) {
        printf("Usage: xargs <cmd>\n");
        exit(0);
    }

    if (argc - 1 > MAXARG) {
        printf("Too many args. \n");
        exit(0);
    }

    char* cmd_args[MAXARG];
    int j = 0;
    for (int i = 1; i < argc; i++) {
        cmd_args[j] = malloc(512 * sizeof(char));
        memset(cmd_args[j], 0, 512 * sizeof(char));
        strcpy(cmd_args[j], argv[i]);
        j++;
    }

    char* cmd = argv[1];
    static char buf[100];
    while(getcmd(buf, sizeof(buf)) >= 0) {
        int len = strlen(buf) - 1;
        buf[len] = '\0';
        char pre = -1;
        int k = 0;
        for (int i = 0; i < len; i++) {
            if (buf[i] == ' ') {
                if (pre == ' ') {
                    continue;
                } else {
                    cmd_args[j][k] = 0;
                    j++;
                    k = 0;

                }
            } else {
                if (k == 0) {
                    cmd_args[j] = malloc(512 * sizeof(char));
                    memset(cmd_args[j], 0, 512 * sizeof(char));
                }
                cmd_args[j][k] = buf[i];
                k++;
            }
            pre = buf[i];
        }
        if (fork() == 0) { // child process
            exec(cmd, cmd_args);
            fprintf(2, "exec %s failed\n", cmd);
            exit(0);
        } else {
            wait(0);
        }
    }
    wait(0);
    exit(0);
}


课程推荐资料

csp

  1. a tech talk at goole
  2. 2010 Google IO talk with Russ Cox

github

https://github.com/aerfalwl/mit-xv6-labs-2020.git

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值