操作系统实践 job3
目录
job3/myecho.c
job3/mycat.c
知识点:
job3/mycp.c
job3/mysys.c
实现函数mysys,用于执行一个系统命令,要求如下
job3/sh1.c
job3/myecho.c
题目:
myecho.c的功能与系统echo程序相同
接受命令行参数,并将参数打印出来,例子如下:
$ ./myecho x x $ ./myecho a b c a b c
思路:
C程序的main函数原型,argc:命令行参数的个数,argv:命令行参数数组
int main(int argc, char *argv[]);
因此从第二行开始输出指令中的字符串就行
#include <stdio.h>
int main(int argc,char *argv[])
{int i;for(i=1;i<argc;i++)printf("%s ",argv[i]);printf("\n");return 0;
}
在一个终端中使用 gcc
编译器来编译程序并生成自定义目标文件
gcc -o myecho myecho.c
结果展示:
job3/mycat.c
题目:
mycp.c的功能与系统cp程序相同
将源文件复制到目标文件,例子如下:
要求使用系统调用open/read/write/close实现
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... $ ./mycp /etc/passwd passwd.bak $ cat passwd.bak root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin
知识点:
文件操作:https://www.linuxmooc.com/courses/io/
用到的几个函数:
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);//打开
int creat(const char *pathname, mode_t mode);//创建
int open(const char *pathname, int flags, mode_t mode);
int close(int fd);//关闭
#include <unistd.h>
int read(int fd, void *buf, size_t count);//读取
int write(int fd, void *buf, size_t count);//写入
off_t lseek(int fd, off_t offset, int whence);//定位
思路:
打开文件,文件名就是输入指令的第二个字符串,进行健壮性检查。
每次读取128字节数据并实时输出在屏幕上,
STDOUT_FILENO
是终端的描述符,直到文件末尾。也可以只读取1字节,更不容易溢出,就是效率可能没那么高。
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
void panic(char*message)
{perror(message);exit(EXIT_FAILURE);
}
int main(int argc,char *argv[])
{//open fileint fp=open(argv[128],O_RDONLY);if(fp<0)panic("open");//read filechar s[1];int flag;while((flag=read(fp,&s,1))>0){//write filewrite(STDOUT_FILENO,s,1);}close(fp);return 0;
}
在一个终端中使用 gcc
编译器来编译程序并生成自定义目标文件
gcc -o mycat mycat.c
结果:
job3/mycp.c
mycp.c的功能与系统cp程序相同
将源文件复制到目标文件,例子如下:
要求使用系统调用open/read/write/close实现
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ... $ ./mycp /etc/passwd passwd.bak $ cat passwd.bak root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin ...
思路和job2类似
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
void panic(char*message)
{perror(message);exit(EXIT_FAILURE);
}
int main(int argc,char *argv[])
{//open fileint fout=open(argv[1],O_RDONLY);if(fout<0)panic("open");//read filemode_t mode=0777;int fin=open(argv[2],O_RDWR|O_APPEND|O_CREAT,mode);char s[10];int flag;while((flag=read(fout,&s,1))>0){//write filewrite(fin,s,1);}close(fout);close(fin);return 0;
}
job3/mysys.c
实现函数mysys,用于执行一个系统命令,要求如下
mysys的功能与系统函数system相同,要求用进程管理相关系统调用自己实现一遍
使用fork/exec/wait系统调用实现mysys
不能通过调用系统函数system实现mysys
测试程序
#include <stdio.h> void mysys(char *command) {实现该函数,该函数执行一条命令,并等待该命令执行结束 } int main() {printf("--------------------------------------------------\n");mysys("echo HELLO WORLD");printf("--------------------------------------------------\n");mysys("ls /");printf("--------------------------------------------------\n");return 0; }测试程序的输出结果
-------------------------------------------------- HELLO WORLD -------------------------------------------------- bin core home lib mnt root snap tmp vmlinuz boot dev initrd.img lost+found opt run srv usr vmlinuz.old cdrom etc initrd.img.old media proc sbin sys var --------------------------------------------------
在mysys函数中创建一个子进程,调用execl函数实现sh命令,并等待子进程结束。
execl函数:
int execl(const char *path, const char *arg, ...);最后一个参数必须是NULL
第一个参数path指定被装入程序的路径。
这里需要使用的是sh指令,/bin/sh是指令路径,sh -c command是命令。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
void mysys(char *command)
{pid_t pid;if(command==NULL){printf("Error: wrong command!");exit(0);}pid=fork();if(pid==0){error=execl("/bin/sh","sh","-c",command,NULL);if(error<0)perror("execl");}wait(NULL);
}
int main()
{printf("--------------------------------------------------\n");mysys("echo HELLO WORLD");printf("--------------------------------------------------\n");mysys("ls /");printf("--------------------------------------------------\n");return 0;
}
展示:
job3/sh1.c
该程序读取用户输入的命令,调用函数mysys(上一个作业)执行用户的命令,示例如下
# 编译sh1.c $ cc -o sh1 sh1.c # 执行sh1 $ ./sh # sh1打印提示符>,同时读取用户输入的命令echo,并执行输出结果 > echo a b c a b c # sh1打印提示符>,同时读取用户输入的命令cat,并执行输出结果 > cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin实现内置命令cd、pwd、exit
首先在'>'后输入命令,当输入回车时触发功能函数。这里需要处理一下字符串,在回车处截断。
添加exit,cd 的功能这里调用了exit(),chdir(),getcwd()函数。
chdir()同cd
函数原型:
int chdir(const char *path);
功 能:更改当前工作目录。
参 数:Path 目标目录,可以是绝对目录或相对目录。
返回值:成功返回0 ,失败返回-1
getcwd()
函数原型:
char *getcwd( char *buffer, int maxlen );
功 能:获取当前工作目录
参数说明:getcwd()会将当前工作目录的绝对路径复制到参数buffer所指的内存空间中,参数maxlen为buffer的空间大小。
返 回 值:成功则返回当前工作目录,失败返回 FALSE。
exit()
结束当前进程/当前程序
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> #include<linux/string.h> #include<string.h> extern void mysys(char *command); int main() {while(1){char command[100]={0};char c;printf(">");//read from screenint i=0;do{c=getchar();command[i]=c;i++;}while(c!='\n');command[i-1]='\0'; //exit功能if(!strcmp(command,"exit"))exit(0); //pwd功能else if(!strcmp(command,"pwd")){char *path=getcwd(NULL,0);printf("Current directory:%s\n",path);free(path);} //cd功能else if(command[0]=='c'&&command[1]=='d'){char cd[100]={0};strcpy(cd,command+3);int error=chdir(cd);if(error<0)perror("cd");else{char *path=getcwd(NULL,0);printf("Current directory:%s\n",path);free(path);}} //其他功能else mysys(command);} }
要想调用mysys.c,首先得将其主函数注释掉。需要进行重定位,mysys作为外部符号需要用extern引用,并进行静态库链接。
将静态库中包含的目标模块先生成可重定位目标文件:
cc -c mysys.c
cc -c sh1.c
打包编译:
cc -o sh sh1.o mysys.o
展示:
操作系统实践 job3相关推荐
- 添加简单的linux内核模块,操作系统实践 第12章-添加最简单的Linux内核模块.ppt
操作系统实践 第12章-添加最简单的Linux内核模块.ppt 文档编号:310662 文档页数:16 上传时间: 2018-07-21 文档级别: 文档类型:ppt 文档大小:2.00MB 第12章 ...
- 泛在操作系统实践案例
本文字数:1399字 阅读时间:3 分钟 文章来源:<泛在操作系统实践与展望研究报告> 虽然泛在操作系统的概念是在 2018 年才正式由梅宏院士提出,但是与泛在操作系统相关的研究工作已经有 ...
- MIT6828操作系统实践记录(一)
MIT6828操作系统实践记录(一) 最近经常感受到被大佬碾压,想想自己写了几年代码但对操作系统的理解似乎仍然停留在课本上-OTZ,特开此篇来进行实践.总结.感谢大佬们,大佬们的碾压就是我前进的动力. ...
- 操作系统实践 linux命令期末汇总
操作系统实践 linux命令 Linux 1 简介 linux介绍 GPL linux发行版 linux系统标准化 登入与登出 常用快捷键 补充内容 Linux 2 Shell Shell 环境变量 ...
- Linux操作系统实践——Samba服务器搭建
文章目录 Linux操作系统实践--Samba服务器搭建 一.实验目的 二.实验内容 ② 学生教师服务 三. 题目分析及基本设计过程分析 ② 学生教师服务 1) 整体思路 2) 系统用户和组分配设计说 ...
- 操作系统实践(四/五)
本次实验课的内容涉及到以下几个方面: 1.文件的内核实现 2.标准的输入输出 3.系统调用dup和pipe 文件最基本的系统调用是open和close,open一个文件 ...
- 操作系统实践-BIOS
基本概念:https://wiki.osdev.org/BIOS 所有中断列表:http://www.ctyme.com/intr/int.htm IBM PC 介绍:http://classicco ...
- 学习操作系统实践-Linux 操作系统从入门到提高(主编 王秀丽 于群 王震)
前言 1.操作系统作为计算机软硬件的基础 2.Linux系统学习为明线,内容分层次递进,包括: (1)Linux系统基本使用(普通用户视角) (2)应用和系统编程(开发人员视角) (3)内核与应用(内 ...
- 【南航操作系统实践】job9
文章目录 操作系统实验job9 实验内容 实验代码 `pc.c` `pp.c` 实验思路 操作系统实验job9 实验内容 使用信号量解决生产者.计算者.消费者问题 pc.c 使用信号量实现 ping- ...
- ROS机器人操作系统实践(一)—— 环境搭建
虚拟机安装:后续ROS的大部分操作均在虚拟机中进行,选择VMware Workstation虚拟机平台. 可以在百度上搜索VMware Workstation的破解版安装,这里安装的是VMware W ...
最新文章
- R语言union函数计算数据对象(vector、list、dataframe)的并集:union函数计算两个vector向量、dataframe、列表list的并集
- [CES 2018] 与联想、小蚁合作,谷歌发布VR180系列VR相机
- 【开发环境】Ubuntu 中使用 VSCode 开发 C/C++ ③ ( 创建工程目录 | 添加 C++ 源代码 | 代码自动提示 )
- 树形结构:优先级队列,堆
- 处女座男生颜值测试软件,颜值在线又绅士的星座男(图)
- rsa 加密 js php,security.js+RSA做出加密功能
- 工作220:git clone的时候地址需要改成自己的用户名
- Java 反射(初步)
- 树——二叉树结点的删除与清除
- Project Euler Problem 27小结
- android 代码 华为 os,Android | 带你零代码实现安卓扫码功能
- 求计算机技术在创新上的应用,计算机技术在企业中的应用
- 打标工具labelme或者labelimg遇到图片闪退的完美解决方案
- 西威变频器avo下载调试资料_西门子变频器使用BOP-2 面板调试 G120
- 一文彻底搞懂 CTR 建模
- 【vue】webapp移动端模板
- 新浪微博平台架构(转)
- UOS/deepin上安装坚果云
- Install VirtualBox Guest Additions for elementary os
- 说话计算机,教计算机说话