本次实验课的内容涉及到以下几个方面:
    1.文件的内核实现
    2.标准的输入输出
    3.系统调用dup和pipe

  文件最基本的系统调用是open和close,open一个文件后会返回一个fd,作为这个文件的标识,后续有关于这个文件的操作都使用fd去完成。

1.文件的内核实现

  文件的内核实现中围绕着四个结构体:索引节点、file结构体、文件描述符表、进程控制块。下面介绍下它们各自存储的内容:
  索引节点中保存了文件的大小、文件存放在磁盘的位置、文件的创建时间、修改时间、文件的所有者、文件的访问权限
  file结构体file结构体存了被打开文件的信息、文件对应的索引节点(inode)、文件的当前访问位置、文件的打开模式(只读、只写、可读可写)
  文件描述符表是一个数组,数组的元素类型是指针,指针指向一个file结构体,用于保存被打开的文件。当内核打开文件时,分配一个file结构体表示被打开的文件,将该file结构体指针保存在文件描述符表中
  进程控制块是操作系统表示进程状态的数据结构,存放用于描述进程情况及控制进程运行所需的全部信息(进程标识信息、处理机状态、进程调度信息、打开文件列表,即文件描述符表,记录了该进程打开的文件)

2.标准的输入输出

  标准的输入输出就是指write和read

write(1, buf, sizeof(buf)); // 标准输入,就是键盘输入
read(0, buf, sizeof(buf)); //标准输出,就是终端输出

3.系统调用dup和pipe

   dup(重定向)
  dup就是让一个新的fd去指向一个文件,这样文件就有了两个指向。可以把老fd解放出来,去完成其他操作。
还有一个变形的dup2,完成一样的功能。调用方式不同

  pipe(管道)
  pipe的实现是基于队列,一端作为输入端,一端作为输出端。整体结构如下:

  以上就是这次实验课的全部理论学习啦,下面看看作业吧!这次的作业没有关于dup和pipe的内容,是上节课mysys实现的变形。
  源代码如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>void mysys(char *command) {char *argv[512]; // 这里必须要用动态指针数组,因为execvp最后有一个NULL作为结束标志,静态的二维数组是无法实现的。int num = 0;char temp[512];for (int i=0; command[i]!='\0'; i++) {int index = 0;while (command[i]!='\0' && command[i] != ' ') {temp[index++] = command[i++];}temp[index] = '\0';if (command[i] == '\0')break;argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;}argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;argv[num] = NULL;pid_t  pid;if (command == NULL)return ;if ((pid = fork()) < 0) {}else if (pid == 0) {execvp(argv[0], argv);exit(127);}else {sleep(1);}return ;
}int main() {while (1) {write(1, "> ", 3); // 此处可以使用write/* printf("> "); 如果这样使用printf是不可以的,printf有输出缓冲区,遇到\n才会统一调用一次write。实现的方式有两种:1.printf("\n")2.fflush(stdout);*/// 在底层编程时,使用printf就可以,更方便char buf[80];int count;count = read(0, buf, sizeof(buf));// buf[count] = 0; //这个是错的,输入回车后,末尾还会读入一个\nbuf[count-1] = 0;if (strcmp(buf, "exit") == 0)//exit(127)也可以;break;mysys(buf);}return 0;
}

  第四次,打板儿!


  第五次的内容和上次一样的,区别的是作业,就写在一篇里了。
  源代码如下:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>void mysys(char *command) {char *argv[512]; // 这里必须要用动态指针数组,因为execvp最后有一个NULL作为结束标志,静态的二维数组是无法实现的。int num = 0;char temp[512];for (int i=0; command[i]!='\0'; i++) {int index = 0;while (command[i]!='\0' && command[i] != ' ') {temp[index++] = command[i++];}temp[index] = '\0';if (command[i] == '\0')break;argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;}argv[num] = (char *)malloc(strlen(temp));strcpy(argv[num], temp);num++;argv[num] = NULL;pid_t  pid;if (command == NULL)return ;if ((pid = fork()) < 0) {}else if (pid == 0) {/*思路:对输入命令进行判断,如果是echo再进一步判断有没有重定向标志: >目标文件,如果有按重定向方法写入指定文件,否则按正常echo输出`*/if (strcmp(argv[0], "echo") == 0) {int i, j;int tag = 0;for (i=0; i<num; i++) {for (j=0; argv[i][j] != '\0'; j++) {if (argv[i][j] = '>' && argv[i][j+1] != '\0' && i == num-1) {tag = 1;break;}}if (tag == 1)break;}if (tag == 1) { // tag为1说明存在重定向,下面截取目标文件名及写入内容// 截取文件名char filename[10];int filename_index = 0;for (int j=1; argv[i][j]!='\0'; j++) {filename[filename_index++] = argv[i][j];}filename[filename_index] = '\0';char content[20];int content_index = 0;// 截取内容,已知为echo命令,从5号以后为内容for (int k=5; command[k]!='\0'; k++) {if (command[k] == '>') {content[content_index] = '\0';break;}else content[content_index++] = command[k];}// 使用重定向方式,将fd改为1int fd;fd = open(filename, O_CREAT|O_RDWR, 0777);dup2(fd, 1); // 函数格式(源,目标)write(1, content, sizeof(content));}else {execvp(argv[0], argv);}}elseexecvp(argv[0], argv); exit(127);}else {sleep(1);}return ;
}int main() {while (1) {write(1, "> ", 3); // 此处需要使用write,用printf的话会不输出char buf[80];int count;count = read(0, buf, sizeof(buf));// buf[count] = 0; //这个是错的,输入回车后,末尾还会读入一个\nbuf[count-1] = 0;if (strcmp(buf, "exit") == 0)break;mysys(buf);}return 0;
}

  这次的作业主要是增加一个要求:echo另外一个内容写入指定文件(之前的echo是输出到屏幕,重定向后将1号指向文件,就不会在上输出了)。但悲催的是:我这份代码能够完成新功能,对于普通功能的echo没用了(呜呜呜),也就是echo a b c没了反应,到现在也没找到问题。如果有人看出来,请在下方评论区留言,感谢!

  上节课老师还让实现pwd,cd,使用execvp无法完成,想了好久都没有结果,但其实是有系统调用的:

char *cwd = getcwd(buff,sizeof(buff)); // pwd,返回值cwd即为结果
chdir(comnd[1]); // cd,comnd为路径

因作者水平有限,如有错误之处,请在下方评论区指正,谢谢!

操作系统实践(四/五)相关推荐

  1. 四川大学计算机综合实践报告,四川大学计算机操作系统第四实验报告

    1.实验报告(学生打印后提交)实验名称: 作业调度系统 实验时间: 2015 年 6 月 4 日实验人员:_(姓名)_(学号)_(年级)实验目的: 理解操作系统中调度的概念和调度算法. 学习 Linu ...

  2. React Native在Android当中实践(五)——常见问题

    React Native在Android当中实践(一)--背景介绍 React Native在Android当中实践(二)--搭建开发环境 React Native在Android当中实践(三)--集 ...

  3. EntityFramework之领域驱动设计实践(五)

    聚合 聚合(Aggregate)是领域驱动设计中非常重要的一个概念.简单地说,聚合是这样一组领域对象(包括实体和值对象),这组领域对象联合起来表述一个完整的领域概念.比如,根据Eric Evans&l ...

  4. 20189200余超 2018-2019-2 移动平台应用开发实践第五作业

    20189200余超 2018-2019-2 移动平台应用开发实践第五作业 输入/输出 输入输出可以说是计算机的基本功能.作为一种语言体系,java中主要按照流(stream)的模式来实现.其中数据的 ...

  5. 【Microsoft Azure 的1024种玩法】七十四.五分钟在Azure Virtual Machines中快速部署一套软件项目管理及自动构建工具

    [简介] Apache Maven由 Apache 软件基金会所提供的一个软件项目管理及自动构建工具,Maven 为开发者提供了一套完整的构建生命周期框架.开发团队几乎不用花多少时间就能够自动完成工程 ...

  6. 激光SLAM理论与实践-第五期 第一次作业(矩阵坐标变换)

    章节: 1.激光SLAM理论与实践-第五期 第一次作业(矩阵坐标变换) 2.激光SLAM理论与实践-第五期 第二次作业(里程计标定) 3.激光SLAM理论与实践-第五期 第三次作业(去运动畸变) 4. ...

  7. 计算机操作系统 (第四版汤小丹老师) 复习笔记第一章

    教材为西安电子科技大学 汤小丹老师 第四版 1.1操作系统目标和作用 1.目标 目前存在着多种类型的OS,不同类型的OS,其目标各有所侧重.通常在计算机硬件上配置的OS,其目标有以下几点: 方便性 便 ...

  8. 激光SLAM理论与实践-第五期 第七次作业

    1.章节: 1.激光SLAM理论与实践-第五期 第一次作业(矩阵坐标变换) 2.激光SLAM理论与实践-第五期 第二次作业(里程计标定) 3.激光SLAM理论与实践-第五期 第三次作业(去运动畸变) ...

  9. 《操作系统第四版》(刘振鹏 王煜)复习总结

    操作系统(一) 操作系统引论 用户接口与作业管理 进程和线程的概念 存储器管理 文件管理 设备管理 一.引论 1.1 操作系统的概念 1.1.1计算机系统 硬件系统+软件系统(程序和文件) 软件分为: ...

  10. DDD(Domain Driven Design) 领域驱动设计从理论到实践 四

    - 接上 SOA 架构 ​     面向服务架构(Service Oriented Architecture,SOA)对于不同的人来说意思不同.这里梳理一下SOA原则: 服务契约 : 通过契约文档,服 ...

最新文章

  1. vue当前浏览器是否为ie_Vue进阶(六十八):JS-判断当前浏览器是否为IE
  2. 选购高清监控摄像机的十个技巧
  3. spcomm控件的使用
  4. Docker ElK安装部署使用教程
  5. 相同的树Python解法
  6. zabbix客户端掉线查看进程time_wait过多
  7. 单片机can通信可以接多少个设备_总结BMS上CAN收发器电路的几个要点
  8. python绘图 条形图 直方图 饼图 箱型图 误差图 多图绘制 图表注释 三维图形
  9. iOS CocoaPods:Updating local specs repositories一直停在那里了
  10. Spring Cloud Ribbon 的请求分发与原理
  11. fft 估计载波频率程序_调幅信号载波频率的高精度估计方法及装置与流程
  12. 纳米金13nm|金属纳米粒子/Nano gold制备方法-齐岳生物
  13. qlearning走迷宫matlab,GitHub - MrMiilk/qlearning_robot: 用 qlearning 算法走迷宫
  14. wamp+php+下载,WAMP(Windows+Apache+Mysql+PHP) 下载配置一条龙
  15. 数据可视化-Tableau-网店运营可视化分析
  16. 逻辑回归(logistic regression)原理理解+matlab实现
  17. SQL Server、MySQL知识点
  18. 读 Linux 像读小说「GitHub 热点速览 v.22.03」
  19. [教程]centos7.x 及centos8 硬盘安装法#免U盘#采坑记
  20. html输入框传给服务器,如何将浏览器上的数据,提交到服务器?

热门文章

  1. matlab中函数的公式计算,MATLAB怎样定义函数(入门) 有一函数 f(x,y)=x^2+sinxy+2y , 写一程序, 输入自变量的值,输出函数值....
  2. 1.3编程基础之算术表达式与顺序执行 01 A+B问题 (Python3实现)
  3. 1360:奇怪的电梯(lift) 《信息学奥赛一本通》
  4. STM32H743+CubeMX-低功耗定时器LPTIM输出PWM波
  5. python初学者怎么找工作_学python找工作好找吗
  6. Java笔记-Java端口扫描功能(含TCP包分析以及原理)
  7. Linux工作笔记-ssh中-X属性的使用(Linux传界面)
  8. Qt creator5.7 OpenCV249之均值滤波(含源码下载)
  9. java 声明静态类,为什么你不能在Java中将类声明为静态?
  10. python创建角色_如何使用 Python 创建一名可操控的角色玩家