6.S081

xv6安装

# 依赖安装
sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu gcc-riscv64-unknown-elf binutils-riscv64-unknown-elf

参考链接: https://pdos.csail.mit.edu/6.S081/2021/tools.html

git clone git://g.csail.mit.edu/xv6-labs-2020
cd xv6-labs-2020
git checkout util
make qemu

Lab: Xv6 and Unix utilities

sleep

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

int
main(int argc, char *argv[]){
    int time;
    
    if(argc <= 1){
        fprintf(2, "usage: sleep <time>\n");
        exit(1);
    }
    time = atoi(argv[1]);
    sleep(time);
    exit(0);
}

pingpong

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

int
main(int argc, char *argv[])
{
    if(argc >= 2){
        fprintf(2, "Usage: pingpong\n");
        exit(1);
    }
    int p1[2], p2[2];
    pipe(p1);  // parent to child
    pipe(p2);  // child to parent
    if(fork() == 0){
        // Child process
        char buf[1];
        close(p1[1]);  // close write end of p1
        close(p2[0]);  // close read end of p2
        // Receive byte from parent
        read(p1[0], buf, 1);
        close(p1[0]);
        printf("%d: received ping\n", getpid());
        // Send byte to parent
        write(p2[1], buf, 1);
        close(p2[1]);
        exit(0);
    } else {
        // Parent process
        char buf[1] = {'a'};
        close(p1[0]);  // close read end of p1
        close(p2[1]);  // close write end of p2
        // Send byte to child
        write(p1[1], buf, 1);
        close(p1[1]);
        // Receive byte from child
        read(p2[0], buf, 1);
        close(p2[0]);
        printf("%d: received pong\n", getpid());
        wait(0);  // wait for child to exit
        exit(0);
    }
}

primes

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

void sieve(int p[2]) {
    close(p[1]);  // Close write end
    int prime;
    if (read(p[0], &prime, sizeof(prime)) <= 0) {
        close(p[0]);
        exit(0);
    }
    printf("prime %d\n", prime);
    
    int next_p[2];
    pipe(next_p);
    if (fork() == 0) {
        close(next_p[1]);  // Close write end in child
        sieve(next_p);
    } else {
        close(next_p[0]);  // Close read end in parent
        int num;
        while (read(p[0], &num, sizeof(num)) > 0) {
            if (num % prime != 0) {
                write(next_p[1], &num, sizeof(num));
            }
        }
        close(p[0]);
        close(next_p[1]);
        wait(0);
        exit(0);
    }
}

int
main() {
    int p[2];
    pipe(p);
    
    if (fork() == 0) {
        sieve(p);
    } else {
        close(p[0]);  // Close read end in parent
        
        for (int i = 2; i <= 35; i++) {
            write(p[1], &i, sizeof(i));
        }
        
        close(p[1]);
        wait(0);
        exit(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){
    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;
    }

    switch (st.type){
    case T_FILE:
        printf("find: the first argument must be a path\n");
        break;

    case T_DIR:
        if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
            printf("find: path too long\n");
            break;
        }
        strcpy(buf, path);
        p = buf + strlen(buf);
        *p++ = '/';
        while(read(fd, &de, sizeof(de)) == sizeof(de)){ // 从fd中读取固定大小数据块sizeof(de),获取目录项
            if(de.inum == 0 || strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
                continue;
            memmove(p, de.name, DIRSIZ);
            p[DIRSIZ] = 0;
            if(stat(buf, &st) < 0){
                printf("find: cannot stat %s\n", buf);
                continue;
            }
            if(st.type == T_DIR)
                find(buf, filename);
            else{
                if(strcmp(de.name, filename) == 0)
                    printf("%s\n", buf);
            }
        }
        break;
    default:
        break;
    }
    close(fd);
}

int
main(int argc, char *argv[]){
    if(argc < 2){
        fprintf(2, "usage: find <path> <file name>\n");
        exit(1);
    }else if(argc == 2)
        find(".", argv[1]);
    else
        find(argv[1], argv[2]);
    exit(0);
}

xargs

将标准输入转化为命令参数

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

int
main(int argc, char *argv[])
{
    if(argc <= 1){
        fprintf(2, "usage: xargs <command> [args...]\n");
        exit(1);
    }

    char buf[512];
    char *args[MAXARG];
    int i;

    // Copy original arguments
    for(i = 1; i < argc; i++) {
        args[i-1] = argv[i];
    }
    
    // Read from stdin character by character
    char *p = buf;
    while(read(0, p, 1) > 0) {
        if(*p == '\n') {
            // End of line - execute command
            *p = '\0'; // Null terminate
            
            // Add current argument
            args[i-1] = buf;
            args[i] = 0; // Null terminate args array
            
            // Fork and exec
            int pid = fork();
            if(pid == 0) {
                // Child
                exec(args[0], args);
            } else{
                wait(0);
                // Reset for next line
                p = buf;
                i = argc;
            }
        }else {
            p++;
        }
    }
    exit(0);
}

results matching ""

    No results matching ""