• Lab 1: Unix utilities汇总


    这个实验主要学习了常用的一些系统调用。

    Lab 1: Unix utilities

    Boot xv6 (easy)

    git克隆,切换分支,qemu。根据要求进行操作即可。

    $ git clone git://g.csail.mit.edu/xv6-labs-2020
    $ cd xv6-labs-2020
    $ git checkout util
    $ make qemu
    
    • 1
    • 2
    • 3
    • 4

    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,"please enter a number!");
            exit(1);
        }else{
    
            int n = atoi(argv[1]);
            sleep(n);
            exit(0);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在 Makefile 中将 sleep 加入构建目标里。

    UPROGS=\
    	$U/_cat\
    	$U/_echo\
    	$U/_forktest\
    	$U/_grep\
    	$U/_init\
    	$U/_kill\
    	$U/_ln\
    	$U/_ls\
    	$U/_mkdir\
    	$U/_rm\
    	$U/_sh\
    	$U/_stressfs\
    	$U/_usertests\
    	$U/_grind\
    	$U/_wc\
    	$U/_zombie\
    	$U/_sleep\ .   # here !!!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    pingpong (easy)

    管道题,使用 fork() 复制本进程创建子进程,然后使用管道进行相互通信。

    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    
    int main(int argc ,char *argv[])
    {
        int pp2c[2],pp2p[2];
        pipe(pp2c);
        pipe(pp2p);
        int n = fork();
        if(n != 0 ){
            write(pp2c[1],"a",1);
            char buff;
            read(pp2p[0],&buff,1);
            printf("%d: received pong\n",n);
        }else{
            char buff;
            read(pp2c[0],&buff,1);
            printf("%d: received ping\n",n);
            write(pp2p[1],&buff,1);
            
        }
        exit(0);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    primes (moderate) / (hard)

    观察下图进行进行理解,使用fork实现素数筛的功能。
    在这里插入图片描述

    // primes.c
    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    
    
    
    void sieve(int pleft[2]){
    
        int p ;
        read(pleft[0] ,&p,sizeof(p));
        if(p == -1){
    
            exit(0);
        }
        printf("prime %d\n", p);
        int pright[2];
        pipe(pright);
        if(fork() == 0){
            // 子进程
            close(pright[1]);
            close(pleft[0]);
            sieve(pright);
        }else{
            close(pright[0]);
            int buff ;
            while(read(pleft[0] ,&buff,sizeof(buff)) && buff != -1){
                if(buff %p != 0 ){
                    write(pright[1] ,&buff,sizeof(buff));
                }
            }
            buff = -1;
            write(pright[1] ,&buff,sizeof(buff));
            wait(0);
            exit(0);
        }
    }
    
    int main(int argc,char* argv[]){
    
        int inputpipe[2];
        pipe(inputpipe);
    
        if(fork() == 0){
            // 子进程
            close(inputpipe[1]);
            sieve(inputpipe);
            exit(0);
    
        }else{
            close(inputpipe[0]);
       
            int i ;
            for( i = 2 ; i <=35;i++){
                write(inputpipe[1] ,&i,sizeof(i) );
                
            }
            i =-1;
            write(inputpipe[1] ,&i,sizeof(i) );
            
        }
        wait(0);
        exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    find (moderate)

    根据ls.c 改造得到

    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    #include "kernel/fs.h"
    
    
    void find(char *path,char *target)
    {
      char buf[512], *p;
      int fd;
      struct dirent de;
      struct stat st;
    
      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:
        if(strcmp(path+strlen(path) - strlen(target) ,target) == 0)
          printf("%s\n", path);
        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)){
          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;
          }
          // printf(buf);
          // printf("\n");
        		find(buf, target); // 递归查找
    		
        }
        break;
      }
      close(fd);
    }
    
    int main(int argc, char *argv[])
    {
      
    	if(argc < 3){
    		exit(0);
    	}
    	char target[512];
    	target[0] = '/'; // 为查找的文件名添加 / 在开头
    	strcpy(target+1, argv[2]);
    	find(argv[1], target);
    	exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    xargs (moderate)

    xargs介绍

    整体思路:

    • 将xargs命令传入的参数保存至指针数组,每个指针指向一个参数;
    • 解析输入参数,如果遇到’ ’ 或者\n 就将参数保存至指针数组,每次读取完成一行就使用exec进行运行
    • 最后一行进行单独判断运行,万一最后一行没有换行符
    // xargs.c
    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    #include "kernel/fs.h"
    
    
    void run(char *program , char ** args)
    {
        if(fork() == 0 ){
            exec(program,args);
            exit(0);
        }
        return ;
    }
    int main(int argc,char* argv[]){
    
        char buf[2048]; // 读入时使用的内存池
    	char *p = buf, *last_p = buf; // 当前参数的结束、开始指针
    	char *argsbuf[128]; // 全部参数列表,字符串指针数组,包含 argv 传进来的参数和 stdin 读入的参数
    	char **args = argsbuf; // 指向 argsbuf 中第一个从 stdin 读入的参数
        for(int i=1;i<argc;i++) {
    		// 将 argv 提供的参数加入到最终的参数列表中
    		*args = argv[i];
    		args++;
    	}
    
        char **pa = args;
    
        while(read(0,p,1) != 0 ){
            if(*p == ' ' || *p == '\n'){
                *p = '\0';
                *(pa++) = last_p;
                last_p = p+1;
                
                if(*p == '\n'){
        
                    
                    *pa = 0;
                    run(argv[1],argsbuf);
                    pa = args;
                }
            }
            p++;
    
        }
    
        if(pa != args) { // 如果最后一行不是空行
    		// 收尾最后一个参数
    
          
    		*p = '\0';
    		*(pa++) = last_p;
    		// 收尾最后一行
    		*pa = 0; // 参数列表末尾用 null 标识列表结束
    		// 执行最后一行指令
    		run(argv[1], argsbuf);
    	}
        while(wait(0) != -1) {}; 
    
        exit(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
  • 相关阅读:
    有blob列的表大小查询
    法学行政法论文选题有哪些?
    小白必看:如何查询微信账号权重?
    【最小共因数函数】
    国产开源数据库建模工具
    人工智能轨道交通行业周刊-第10期(2022.8.15-8.21)
    【AIGC】Stable Diffusion Prompt 每日一练0915:机车女孩
    【C++】二叉树进阶 -- 详解
    图解BM(Boyer-Moore)字符串匹配算法+代码实现
    关于Python和自动化
  • 原文地址:https://blog.csdn.net/qq_43458555/article/details/133754567