MIT 6.S081---Lab util: Unix utilities

news2024/11/19 7:21:56

环境搭建

基本环境

选择的是Vmware+ubuntu的配置,注意ubuntu的版本一定要是20.04,作者试过16版本,不行,建议直接安装20.04版,不然环境配置都浪费不少时间有点得不偿失。(Vmware可以用Virtualbox代替)

qemu+xv6

参考官网教程
ps:刚装好的系统可以先更换镜像源(参考ubuntu 20.04 LTS 更换阿里云源)
这里将官网教程流程拷贝下来供大家拷贝:
第一步:


sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu 

第二步:

sudo apt-get remove qemu-system-misc
sudo apt-get install qemu-system-misc=1:4.2-3ubuntu6

测试结果如下显示就是对的:

# in the xv6 directory
make qemu
# ... lots of output ...
init: starting sh
$

gitee配置

本处采用git来协调不同平台的代码,由于gitub比较慢于是将代码上传到gitee上(上传的时候可能会显示冲突,解决方法参考:代码冲突强制覆盖上传),至于gitee如何配置环境可以参考Windows环境安装及配置git并连接gitee远程仓库和ubuntu下Git的安装和使用(针对gitee)

实验部分

sleep (easy)

实现一个简单的休眠函数,容易,调api即可

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


int main(int argc, char *argv[]) {
    // int i;
    if (argc == 2) {
        sleep(atoi(argv[1]));
    } else {
        fprintf(2, "there is a need for an augument to determin the time to sleep");
        exit(1);
    }
    exit(0);
}

pingpong (easy)

考察到了pipe()函数的使用,使用管道一端写一端读即可。

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

char buf[96];

char tmp[100];

char* itoch(int input) {
    int i = 0;
    int l, r;
    while (input != 0) {
        tmp[i++] = (input % 10) + '0';
        input /= 10;
    }
    l = 0;
    r = i - 1;
    while (l < r) {
        char temp = tmp[l];
        tmp[l] = tmp[r];
        tmp[r] = temp;
        l++;
        r--;
    }
    tmp[i] = '\0';
    // fprintf(1, tmp);
    return tmp;
}

int main(int argc, char *argv[]) {
    int pftos[2], pstof[2];
    pipe(pftos);
    pipe(pstof);
    // int pid = fork();
    // read
    // getpid
    if (fork() == 0) {
        //son pid
        close(pftos[1]);
        close(pstof[0]);
        // fprintf(1, "son read\n");
        if (read(pftos[0], buf, sizeof(buf)) != 1) {
            fprintf(2, "ping read error");
            exit(1);
        }
        // fprintf(1, "son read success\n");
        char* tmp = itoch(getpid());
        fprintf(1, tmp);
        fprintf(1, ": ");
        fprintf(1, "received ping\n");

        if (write(pstof[1], "i", 1) != 1) {
            fprintf(2, "pong write error");
            exit(1);
        }
        close(pftos[0]);
        close(pstof[1]);
        exit(0);
    }
    //parent pid
    close(pftos[0]);
    close(pstof[1]);
    // fprintf(1, "father write begin\n");
    if (write(pftos[1], "o", 1) != 1) {
        fprintf(2, "ping write error");
        exit(1);
    }
    // fprintf(1, "father write success\n");

    if (read(pstof[0], buf, sizeof(buf)) != 1) {
        fprintf(2, "pong read error");
        exit(1);
    }
    char* tmp = itoch(getpid());
    fprintf(1, tmp);
    fprintf(1, ": ");
    fprintf(1, "received pong\n");
    wait(0);
    close(pftos[1]);
    close(pstof[0]);
    exit(0);
}

primes (moderate)/(hard)

通过筛子来筛选,具体如下图所示:
在这里插入图片描述
需要注意两点:

  1. 注意文件描述符的关闭,如果不及时关闭描述符可能会用尽文件描述符;
  2. 注意关闭管道的写端,当管道的写端的引用为0时read读端才会返回零,代表文件结束。
    本处的代码并没有优化到最好,个人认为更好的实现可参考:6.S081-Lab1 总结笔记(0基础向)
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/spinlock.h"


typedef enum {
    true = 1,
    false = 0
} bool;

void buildProcess(int listenfd, int writefd) {
    int num;
    int self = -1;
    int status = fork();
    if (status == 0) {
        bool next = false;
        close(writefd);
        close(0);
        dup(listenfd);
        close(listenfd);
        //close(1);
        //dup(pfd[1]);
        //close(pfd[1]);
        int pfd[2];
        pipe(pfd);
        while (1) {
            int read_bytes = read(0, &num, 4);
            if (read_bytes == 0 || read_bytes == -1) {
                break;
            }
            if (self == -1) {
                self = num;
                printf("prime %d\n", num);
                continue;
            }
            
            if (num % self != 0) {
                if (!next) {
                    next = true;
                    buildProcess(pfd[0], pfd[1]);
                }
                write(pfd[1], &num, 4); 
            }
        } 
        close(pfd[0]);
        close(pfd[1]);
        close(0);
        wait(0);
        exit(0);
    } else if (status == -1) {
        fprintf(2, "fork error");
        exit(1);
    } 
    
}

int main(int argc, char* argv[]) {
    int i;
    bool next = false;
    int pfd[2];
    pipe(pfd);
    for (i = 2; i <= 35; ++i) {
        if (i == 2) {
            printf("prime %d\n", i);
        }
        if (i % 2 == 1) {
            if (!next) {
                next = true;
                buildProcess(pfd[0], pfd[1]);
                close(pfd[0]);
            }
            write(pfd[1], &i, 4);
        } 
    }
    close(pfd[1]);
    printf("end");
    wait(0);
    exit(0);
}

注释:有个待解决的问题,就是pipe后的两个文件描述符中,似乎不能将写端重定向到文件描述符1,具体原因待阅读源码后确认。

find (moderate)

这题算比较简单了,注意参考usr/find.c

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

void find(const char* root, const char* target) {
    char buf[512], *p;
    int fd;
    struct dirent de;
    struct stat st;

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

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

    if (st.type == T_FILE) {
        fprintf(2, "%s is no a directory!!!\n", root);
        close(fd);
        return;
    }

    if(strlen(root) + 1 + DIRSIZ + 1 > sizeof buf){
        printf("ls: path too long\n");
    }
    strcpy(buf, root);
    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;
        strcpy(p, de.name);
        int tmpfd;
        if((tmpfd = open(buf, 0)) < 0){
            fprintf(2, "open: cannot open %s\n", buf);
            return;
        }
        if(fstat(tmpfd, &st) < 0){
            fprintf(2, "fstat: cannot stat %s\n", buf);
            close(tmpfd);
            return;
        }
        if (st.type == T_FILE) {
            if (strcmp(de.name, target) == 0) {
                printf("%s/", root);
                printf("%s\n", de.name);
            }
        } else if (st.type == T_DIR) {
            find(buf, target);
        }
        close(tmpfd);
    }
    close(fd);
}

int main(int argc, char* argv[]) {
    if (argc != 3) {
        fprintf(2, "too many or too few parameters\n");
        exit(1);
    }
    find(argv[1], argv[2]);
    exit(0);
}

xargs (moderate)

注意exec的参数,别的话就是些细节啦

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

char buf[1024];

int main(int argc, char* argv[]) {
    int i;
    int line = 0;
    int size = read(0, buf, sizeof buf);
    char* input[argc];
    for (i = 1; i < argc; ++i) {
        input[i - 1] = argv[i];
    }
    if (size == -1) {
        fprintf(2, "read error");
    }

    for (i = 0; i < size; i++) {
        if (buf[i] == '\n') {
            line++;
        }
    }
    char arguments[line][32];
    int pos = 0, curr = 0;
    for (i = 0; i < size; ++i) {
        if (buf[i] == '\n') {
            arguments[curr][pos] = '\0';
            curr++;
            pos = 0;
        } else {
            arguments[curr][pos++] = buf[i];
        }
    }
    for (i = 0; i < line; ++i) {
        input[argc - 1] = arguments[i];
        if (fork() == 0) {
            exec(argv[1], input);
            exit(0);
        }
        wait(0);
    }
    exit(0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1338166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深信服技术认证“SCSA-S”划重点:文件上传与解析漏洞

为帮助大家更加系统化地学习网络安全知识&#xff0c;以及更高效地通过深信服安全服务认证工程师考核&#xff0c;深信服特别推出“SCSA-S认证备考秘笈”共十期内容&#xff0c;“考试重点”内容框架&#xff0c;帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…

ES-搜索

聚合分析 聚合分析&#xff0c;英文为Aggregation&#xff0c;是es 除搜索功能外提供的针对es 数据做统计分析的功能 - 功能丰富&#xff0c;提供Bucket、Metric、Pipeline等多种分析方式&#xff0c;可以满足大部分的分析需求 实时性高&#xff0c;所有的计算结果都是即时返回…

新增Chat AI小助手功能,支持Slack平台用户认证及消息推送,JumpServer堡垒机v3.10 LTS版本发布

2023年12月25日&#xff0c;JumpServer开源堡垒机正式发布v3.10 LTS&#xff08;Long Term Support&#xff09;版本。JumpServer开源项目组将对v3.10 LTS版本提供长期支持&#xff0c;定期迭代发布小版本&#xff0c;持续进行问题修复更新并针对部分功能进行优化。欢迎广大用户…

FTP不同方式使用与搭建与端口号常识了解

目录 一、FTP介绍 二、winServer2012搭建ftp服务器 在虚拟机搭建具体步骤 2.1、新建组&#xff1a; 2.2、新建用户名 2.3、把用户名与组绑定 2.4、安装ftp 2.5、配置ftp服务器 2.6、给文件夹调整权限 2.7、测试 a、服务器本机测试 b、外部机器测试 C、借助工具Mobal…

Unity预设体

目录 预设体是什么&#xff1f; 如何创建预设体&#xff1f; 如何修改预设体&#xff1f; 如何删除预设体&#xff1f; 预设体是什么&#xff1f; Unity中的预设体&#xff08;Prefab&#xff09;是一种可重复使用的游戏对象模板。它允许开发者创建一个或多个游戏对象&…

RabbitMQ入门指南(九):消费者可靠性

专栏导航 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、消费者确认机制 二、失败重试机制 三、失败处理策略 四、业务幂等性 1.通过唯一标识符保证操作的幂等性 2.通过业务判断保证操作的幂等性 总结 前言 RabbitMQ是一个高效、可靠的开源消息队列系…

【python与机器学习3】感知机和门电路:与门,或门,非门等

目录 1 电子和程序里的与门&#xff0c;非门&#xff0c;或门&#xff0c;与非门 &#xff0c;或非门&#xff0c;异或门 1.1 基础电路 1.2 所有的电路情况 1.3 电路的符号 1.4 各种电路对应的实际电路图 2 各种具体的电路 2.1 与门&#xff08;and gate&#xff09; 2…

python降低图像的灰度分辨率——冈萨雷斯数字图像处理

原理&#xff1a; 降低图像的灰度分辨率是指减少图像中不同灰度级别的数量&#xff0c;从而使图像看起来更加粗糙或简化。这可以通过减少灰度级别的数量或重新映射灰度级别来实现。以下是一些常见的降低图像灰度分辨率的原理和方法&#xff1a; 灰度量化&#xff08;Gray Lev…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(5)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识&#xff08;4&#xff09; 1.1 PCI总线的组成 PCI总线作为处理器系统的本地总线&#xff0c;是处理器系统的一个组成部件。因此&#xff0c;讲述PCI总线的组成结构&#xff0c;不…

ADRC-跟踪微分器TD的Maltab实现及参数整定

目录 问题描述&#xff1a; 跟踪微分器TD基本概念&#xff1a; Matlab及其实现&#xff1a; 跟踪效果&#xff1a; 例1&#xff1a;跟踪信号 sin(t) 0.5*rand(1,1)。 例2&#xff1a;跟踪部分时段为方波的信号&#xff0c;具体形式见代码get_command。 参数整定&#xf…

【贪心算法】专题练习一

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 前言 1.什么是贪心算法&#xff1f;——贪婪鼠目寸光 贪心策…

【Windows】共享文件夹拍照还原防火墙设置(入站,出站设置)---图文并茂详细讲解

目录 一 共享文件夹(两种形式) 1.1 普通共享与高级共享区别 1.2 使用 二 拍照还原 2.1 是什么 2.2 使用 三 防火墙设置&#xff08;入栈&#xff0c;出站设置&#xff09; 3.1 引入 3.2 入站出站设置 3.2.1入站出站含义 3.3入站设置 3.4安装jdk 3.5使用tomcat进行访…

【C#】Visual Studio 2022 远程调试配置教程

在某些特殊的情况下&#xff0c;开发机和调试机可能不是同一台设备&#xff0c;此时就需要远程调试了。 开发机配置 首先需要确保两台机器在同一局域网下。 创建共享文件夹 随便找个地方新建一个文件夹&#xff0c;用来放编译结果。例如我这里是 D:\DebuggingWorkspace\。 …

git集成github(一):主要步骤

一、创建仓库 1、创建本地git仓库 在pcharm主界面顶栏&#xff0c;点击VCS&#xff0c;再点击创建git仓库&#xff0c;然后选择项目根路径&#xff0c;点击确认。这时&#xff0c;可以看到顶栏的VCS变成了git。 2、远程仓库下载到本地 打开一个远程仓库&#xff0c;点击code…

“C语言“——scanf()、getchar() 、putchar()、之间的关系

scanf函数说明 scanf函数是对来自于标准输入流的输入数据作格式转换&#xff0c;并将转换结果保存至format后面的实参所指向的对象。 而const char*format 指向的字符串为格式控制字符串&#xff0c;它指定了可输入的字符串以及赋值时转换方法。 简单来说给一个打印格式(输入…

PYTHON数据处理:CSV和JSON

#CSV和JSON格式的数据在python上的处理 CSV和JSON数据类型都是都是常见的两种在python中的数据分析类型&#xff0c;这里我有两个入门项目详细讲解这两种数据的处理。 处理一个CSV形式的地方的天气的数据&#xff0c;然后创建一个表格&#xff1b; 分析JSON形式的地震数据&…

扩展mybatis-plus,保留逻辑删、逻辑查的前提下,扩展硬删除、硬查询

引入相关依赖 <!-- 提示&#xff1a;1. common-mybatis-plus:2100.8.8 中只有4个类文件&#xff0c;是对硬删除、硬查询的扩展支持&#xff0c;如果你不想引入依赖的话&#xff0c;你可以把这四个文件复制到自己的项目中即可2. common-mybatis-plus:2100.8.8 对应mybatis-p…

CEEMDAN +组合预测模型(CNN-LSTM + ARIMA)

目录 往期精彩内容&#xff1a; 前言 1 风速数据CEEMDAN分解与可视化 1.1 导入数据 1.2 CEEMDAN分解 2 数据集制作与预处理 3 基于CEEMADN的 CNN-LSTM 模型预测 3.1 定义CEEMDAN-CNN-LSTM预测模型 3.2 定义模型参数 3.3 模型训练&#xff0c;训练结果 4 基于ARIMA的…

数据结构与算法:基于比较的排序算法:选择、冒泡、插入、归并的动图演示和java代码,排序时间复杂度、空间复杂度、稳定性总结表格

选择排序 选择排序是先在0~N-1上选择一个最小值排到最前面&#xff0c;然后再在1到N-1上选一个次小的&#xff0c;以此类推。 public static selectionSort(int[] arr){if(arrnull||arr.length<2){return;} //每次从i n-1 选一个最小的放前面for(int i0;i<arr.length-…

深入Apache Commons Config:管理和使用配置文件

第1章&#xff1a;引言 咱们都知道&#xff0c;在软件开发中&#xff0c;管理配置文件是一件既重要又让人头疼的事。想象一下&#xff0c;咱们的应用程序有一堆设置需要调整&#xff0c;比如数据库的连接信息、应用的端口号&#xff0c;或者是一些功能的开关。如果这些信息硬编…