MIT6.S081 Lab1

写在开头

6.S081/2021/Fall
当刚开始做这个实验的时候,我好像又陷入了一个误区,在实现Sleep的时候,我想了解Sleep到底是怎么完成运行的,浪费了一些时间,也没搞懂。
浪费了一段时间之后,我突然意识到:我并不熟悉MakeFile。
不熟悉MakeFile,我不可能去理解这个xv6是怎么运行的。
并且我的目的是去完成这个课程,并不是去了解xv6的运行过程。
如果我完成了这个课程,有了一个系统性的认识之后,到时候我再去了解这些问题。
可能以我现在的能力解决不了这个问题,并且会大大降低我做Lab的积极性。
不如一步一步的把Lab搞好,最后完成所有Lab之后再去研究(或者中途有些Lab会了解到这些知识)

总而言之就是一句话:先把既定的目标做好,做好目标之后会提高积极性,进入良性循环。难题之后再解决,避免降低积极性,陷入恶性循环。

希望自己今年能把这个Lab做完,不要不要半途而废。

Lab1 的主要工作是实现五个工具:Sleep、PingPong、Primes、Find、Xargs

Lab1

Sleep

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *args[])
{
    if (argc <= 1)
    {
        fprintf(2, "you need to give sleep time!\n");
        exit(1);
    }
    sleep(atoi(args[1]));
    exit(0);
}

PingPong

开始以为xv6的printf只能传char * 不能传%d 这种,所以写的有些臃肿了

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0
int main(int argv, char *args[])
{
    int p[2];
    pipe(p);
    int pid = fork();
    char *buf[10];
    if (pid == CHILD)
    {
        int child = getpid();
        int n = read(p[PIPE_READ], buf, sizeof buf);
        char arr[10];
        int now = 0;
        while (child)
        {
            arr[now] = '0' + child % 10;
            child /= 10;
        }
        printf(arr);
        printf(": received ping\n");
        write(p[PIPE_WRITE], buf, n);
        close(p[PIPE_READ]);
        close(p[PIPE_WRITE]);
        exit(0);
    }
    else
    {
        pid = getpid();
        write(p[PIPE_WRITE], "A", 1);
        int status;
        wait(&status);
        read(p[PIPE_READ], buf, sizeof buf);
        char arr[10];
        int now = 0;
        while (pid)
        {
            arr[now] = '0' + pid % 10;
            pid /= 10;
        }
        printf(arr);
        printf(": received pong\n");
        close(p[PIPE_READ]);
        close(p[PIPE_WRITE]);
    }
    exit(0);
}

Primes

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

#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0

void primes(int fd[2])
{
    int prime;
    close(fd[PIPE_WRITE]);
    if (read(fd[PIPE_READ], &prime, sizeof(int)) == EOF)
    {
	    return ;
        // exit(0); if use 'exit' to exit function 
        // will throw a error.the error is 'error: infinite recursion detected' 
    }
    // printf("primes %d ", getpid());
    printf("prime %d\n", prime);
    int pp[2];
    pipe(pp);
    int ProcessId = fork();
    if (ProcessId == CHILD)
    {
        primes(pp);
        exit(0);
    }
    else
    {
        int now;
        close(pp[PIPE_READ]);
        while (read(fd[PIPE_READ], &now, sizeof(int)) != EOF)
        {
            int cur = now;
            if (cur % prime != 0)
                write(pp[PIPE_WRITE], &cur, sizeof(int));
        }
        close(pp[PIPE_WRITE]);
        close(fd[PIPE_READ]);
        wait(WAIT);
        exit(0);
    }
}

int main()
{
    int fd[2];
    pipe(fd);
    int pid = fork();
    if (pid == CHILD)
    {
        primes(fd);
        exit(0);
    }
    for (int i = 2; i <= 35; i++)
    {
        write(fd[PIPE_WRITE], &i, sizeof(int));
    }
    close(fd[PIPE_READ]);
    close(fd[PIPE_WRITE]);
    wait(WAIT);
    exit(0);
}

primes2

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
void grepPrime(int fd)
{
    int p[2];
    pipe(p);
    int prime;
    if (read(fd, &prime, sizeof(int)) == EOF)
    {
        return;
    }
    printf("prime %d\n", prime);
    int pid = fork();
    if (pid == 0)
    {
        close(fd);
        close(p[PIPE_WRITE]);
        grepPrime(p[PIPE_READ]);
        close(p[PIPE_READ]);
    }
    else
    {
        close(p[PIPE_READ]);
        int now;
        while (read(fd, &now, sizeof(int)) != EOF)
        {
            if (now % prime != 0)
            {
                write(p[PIPE_WRITE], &now, sizeof(int));
            }
        }
        close(fd);
        close(p[PIPE_WRITE]);
        wait(WAIT);
    }
}

int main()
{
    int fd[2];
    pipe(fd);
    int pid = fork();
    if (pid == 0)
    {
        close(fd[PIPE_WRITE]);
        grepPrime(fd[PIPE_READ]);
    }
    else
    {
        close(fd[PIPE_READ]);
        for (int i = 2; i <= 35; i++)
        {
            write(fd[PIPE_WRITE], &i, sizeof(int));
        }
        close(fd[PIPE_WRITE]);
        wait(WAIT);
    }
    exit(0);
}

Find

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

char *fmt(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));
    buf[strlen(p)] = 0; // end of file name
    return buf;
}
void find(char *path, char *pattern)
{
    int fd;
    struct stat st;
    struct dirent de;
    char buf[512], *p;
    // char *fmtname = fmt(path); // current dir/file name (exclude parents)
    if ((fd = open(path, 0)) < 0)
    {
        fprintf(2, "ls: cannot open %s\n", path);
        return;
    }
    if (fstat(fd, &st) < 0)
    {
        fprintf(2, "ls: cannot stat %s\n", path);
        close(fd);
        return;
    }
    switch (st.type)
    {
    case T_FILE:
        char *file = fmt(path);
        if (strcmp(file, pattern) == 0)
        {
            printf("%s\n", path);
        }
        close(fd);
        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 (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
                continue;
            if (de.inum == 0)
                continue;
            memmove(p, de.name, DIRSIZ);
            p[DIRSIZ] = 0;
            find(buf, pattern);
        }
        close(fd);
        break;
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        fprintf(2, "error , amount of arguments is error");
    }
    find(argv[1], argv[2]);
    exit(0);
}

Xargs

最开始没有想到怎么读入数据,是看到别人的answer之后才想到使用while(read(1))

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

#define READ 0
#define WRITE 1
#define MAXARG 32

int main(int argv, char *args[])
{
    char *argument[MAXARG];
    int index = 0;
    for (int i = 1; i < argv; i++)
    {
        argument[index++] = args[i];
    }
    char buf[512];
    char *p = buf;
    // test "echo 1\n2 | xarg echo line"
    // int fd[2];
    // pipe(fd);
    // char *test = "1\n2";
    // write(fd[WRITE], test, sizeof test);
    // close(fd[WRITE]);
    while (read(READ, p, 1) == 1)
    {
        if ((*p) != '\n')
        {
            p++;
        }
        else
        {
            *p = 0;
            argument[index] = buf;
            int pid = fork();
            if (pid == 0)
            {
                exec(argument[0], argument);
                fprintf(2, "error");
                exit(1);
            }
            wait(0);
            p = buf;
        }
    }
    if (p != buf)
    {
        *p = 0;
        argument[index] = buf;
        int pid = fork();
        if (pid == 0)
        {
            exec(argument[0], argument);
            fprintf(2, "error");
            exit(1);
        }
        wait(0);
    }
    exit(0);
}

posted @ 2024-06-04 14:19  x1uc  阅读(24)  评论(0)    收藏  举报