mit6s081——lab1

181 阅读2分钟

lab地址

sleep (easy)

#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 <ticks>\n", 100);
        exit(-1);
    }
    int n = atoi(argv[1]);
    sleep(n);
    exit(0);
}

pingpong (easy)

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

// 父先给子
int main()
{
    int fp[2], sp[2]; // 父到子与子到父,管道只能单向
    pipe(fp);
    pipe(sp);

    char buf[1024];
    if (fork() == 0)
    {
        close(0);
        dup(fp[0]);
        read(0, buf, sizeof(buf)); // 管道的读取会一直等待
        // printf("I receive content from father:%s\n", buf);
        printf("%d: received ping\n", getpid());
        write(sp[1], "Thanks father's content", 100);
    }
    else
    {
        write(fp[1], "haha", 100);
        read(sp[0], buf, sizeof(buf));
        // printf("I receive content from son:%s\n", buf);
        printf("%d: received pong\n", getpid());
    }
    exit(0);
}

primes (moderate)/(hard)

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

// 算术基本定理:一个数是由素数组成的,如果这个数不是素数那么即为前面的素数所组成,如果该数为素数,则该数本身就是素数
// 管道是单向的,在读端关闭用于写的文件描述符,在写端关闭用于读的文件描述符

void seize(int p[2])
{
    int n, pr[2];
    read(p[0], &n, sizeof(int));
    if (n == -1)
    {
        exit(0);
    }
    printf("prime %d\n", n); // 第一个数肯定为素数
    pipe(pr);
    if (fork() == 0) // main中的fork已经接受第二次返回的0,现在fork即是创建子进程并返回非0(fork一次调用两次返回)
    {
        close(pr[1]);
        seize(pr);
    }
    else
    {
        close(pr[0]);
        int x;
        while (read(p[0], &x, sizeof(int)) && x != -1) // 用x != -1暂停管道读取的一直等待
        {
            if (x % n != 0)
                write(pr[1], &x, sizeof(int));
        }
        x = -1;
        write(pr[1], &x, sizeof(int));
        wait(0);
        exit(0);
    }
}

// 主进程
int main()
{

    int p[2];
    pipe(p);
    if (fork() == 0)
    {
        close(p[1]);
        seize(p);
    }
    else
    {
        close(p[0]);
        int i;
        for (i = 2; i <= 35; ++i)
            write(p[1], &i, sizeof(int));
        i = -1;
        write(p[1], &i, sizeof(int));
        wait(0);
    }
    exit(0);
}

find (moderate)

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

char *fmtname(char *path)
{
    char *buf = (char *)malloc(sizeof(char) * (DIRSIZ + 1));
    char *p;

    for (p = path + strlen(path); p >= path && *p != '/'; --p)
        ;
    p++;

    if (strlen(p) >= DIRSIZ)
        return p;
    memmove(buf, p, strlen(p));
    return buf;
}

void find(char *path, char *order)
{
    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);
        close(fd);
        return;
    }

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

    switch (st.type)
    {
    case T_FILE:
        if (strcmp(fmtname(path), order) == 0)
            printf("%s\n", path);
        close(fd);
        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;
            memmove(p, de.name, DIRSIZ);
            p[DIRSIZ] = 0;
            if (stat(buf, &st) < 0)
            {
                printf("find: cannot stat %s\n", buf);
                continue;
            }
            if (strcmp(fmtname(buf), ".") != 0 && strcmp(fmtname(buf), "..") != 0)
                find(buf, order);
        }
        close(fd);
        break;
    }
}

int main(int argc, char *argv[])
{
    find(argv[1], argv[2]);
    exit(0);
}

xargs (moderate)

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

int main(int argc, char *argv[])
{
    char *args[MAXARG];
    for (int i = 1; i < argc; ++i)
        args[i - 1] = argv[i];
    char buf[128];
    char *p = buf;
    while (read(0, p, 1) != 0)
    {
        if (*p == '\n')
        {
            *p = '\0';
            args[argc - 1] = buf;
            if (fork() == 0)
            {
                exec(argv[1], args);
                exit(0);
            }
            else
            {
                wait(0);
            }
            p = buf;
        }
        p++;
    }
    exit(0);
}