V2.0-在记事本功能上添加fork和wait

news/2024/11/23 23:10:38/

第一篇只是简单使用了open,read,write,lseek实现了基本的记事本功能;

但是当前的系统是linux,应该发挥他的多进程,多线程的作用;

所以,本篇添加创建子进程和父进程等待子进程退出的功能。

有几个注意点:

wait()要与fork()配套出现,如果在使用fork()之前调用wait(),wait()的返回值则为-1,正常情况下wait()的返回值为子进程的PID.

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像下面这样:pid = wait(NULL);

如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。

WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。

(请注意,虽然名字一样,这里的参数status并不同于wait唯一的参数–指向整数的指针status,而是那个指针所指向的整数,切记不要搞混了。)

 WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status) 就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。

代码:
main.c


#include "./io.h"struct CMD_input CMD_test1={"creat","copy","display","delete","write"};
struct buffer_param *p;int main(int argc,char **argv)
{//printf("argc :%d,argv[0]:%s,argv[1]:%s,argv[2]:%s\r\n",argc,argv[0],argv[1],argv[2]);//agrc指在终端输入的个数//argv[0]是第1个参数;//argv[1]是第二个参数;,,,,,,//1-function:解析参数1。判断要做什么操作//当前只接解析“creat”,但是预留“cp”,"display","delete"接口p = ( struct buffer_param *)malloc(sizeof(struct buffer_param));memset(p,0,sizeof(struct buffer_param));strncpy(p->buffer_param0,argv[0],strlen(argv[0]));strncpy(p->buffer_param1,argv[1],strlen(argv[1]));strncpy(p->buffer_param2,argv[2],strlen(argv[2]));if(argc==4){strncpy(p->buffer_param3,argv[3],strlen(argv[3]));}log_test1();//打印所有参数read_CMD();//读取指令“creat,write,delete,display,copy”task_sch();//执行任务return 0;
}

io.c

#include "./io.h"
extern struct buffer_param *p;
extern struct CMD_input CMD_test1;
int flag_of_QUITEDIT=0;
char path_of_file[30];
char flag_of_key_event=0;void log_test1()
{printf("param0:%s\r\n",p->buffer_param0);printf("param1:%s\r\n",p->buffer_param1);printf("param2:%s\r\n",p->buffer_param2);printf("param3:%s\r\n",p->buffer_param3);
}
int read_CMD()
{if(strncmp(p->buffer_param1,CMD_test1.CMD_CREAT,strlen(p->buffer_param1))==0)//creat{memset(path_of_file,0,sizeof(path_of_file));sprintf(path_of_file,"./%s",p->buffer_param2);flag_of_key_event = Key_event_creatFile;//creat(buffer_param2, S_IRWXU);}else if(strncmp(p->buffer_param1,CMD_test1.CMD_WRITE,strlen(p->buffer_param1))==0)//write{memset(path_of_file,0,sizeof(path_of_file));sprintf(path_of_file,"./%s",p->buffer_param2);flag_of_key_event = Key_event_writeFile;///写入数据}    else if(strncmp(p->buffer_param1,CMD_test1.CMD_DISPLAY,strlen(p->buffer_param1))==0)//display{memset(path_of_file,0,sizeof(path_of_file));sprintf(path_of_file,"cat ./%s",p->buffer_param2);flag_of_key_event = Key_event_displayFile;///} else if(strncmp(p->buffer_param1,CMD_test1.CMD_CP,strlen(p->buffer_param1))==0)//copy{memset(path_of_file,0,sizeof(path_of_file));sprintf(path_of_file,"cp ./%s ./%s",p->buffer_param2,p->buffer_param3);flag_of_key_event = Key_event_copyFile;///} else if(strncmp(p->buffer_param1,CMD_test1.CMD_DELETA,strlen(p->buffer_param1))==0)//display{memset(path_of_file,0,sizeof(path_of_file));sprintf(path_of_file,"rm ./%s",p->buffer_param2);flag_of_key_event = Key_event_deleteFile;///} return 0;
}int task_sch()
{int return_of_fork;int status_childProcess;//子进程退出状态switch(flag_of_key_event){case Key_event_creatFile:return_of_fork = fork();//创建1个子进程if(return_of_fork<0)printf("creat childprocess failed\r\n");else if(return_of_fork==0)creat_file();else if(return_of_fork>0)wait(NULL);break;case Key_event_writeFile:return_of_fork = fork();//创建1个子进程if(return_of_fork<0)printf("creat childprocess failed\r\n");else if(return_of_fork==0)write_file();else if(return_of_fork>0)wait(&status_childProcess);printf("child process exit status:%d\n",WEXITSTATUS(status_childProcess));break;case Key_event_displayFile:            return_of_fork = fork();//创建1个子进程if(return_of_fork<0)printf("creat childprocess failed\r\n");else if(return_of_fork==0)display_file();else if(return_of_fork>0)wait(&status_childProcess);printf("child process exit status:%d\n",WEXITSTATUS(status_childProcess));break;case Key_event_copyFile:return_of_fork = fork();//创建1个子进程if(return_of_fork<0)printf("creat childprocess failed\r\n");else if(return_of_fork==0)copy_file();else if(return_of_fork>0)wait(&status_childProcess);printf("child process exit status:%d\n",WEXITSTATUS(status_childProcess));break;case Key_event_deleteFile:return_of_fork = fork();//创建1个子进程if(return_of_fork<0)printf("creat childprocess failed\r\n");else if(return_of_fork==0)delete_file();else if(return_of_fork>0)wait(&status_childProcess);printf("child process exit status:%d\n",WEXITSTATUS(status_childProcess));break;            default :break;}
}int creat_file()
{int ret=0;ret = creat(p->buffer_param2, S_IRWXU);//if(ret==-1){printf("creat file failed\r\n");}exit(Key_event_creatFile);//退出子进程return ret;}int write_file()
{int ret=0;int fd=0;char readbuffer[128]={0};fd = open(path_of_file,O_RDWR | O_CREAT,0666) ;if(fd == -1){printf("unexist %s\n",path_of_file);}	else{printf("open file1 success\n");printf("if you want exit edit ,please input “QUIT”\r\n");printf("please input string :\r\n");while(flag_of_QUITEDIT==0){printf(">");memset(readbuffer,0,sizeof(readbuffer));fgets(&readbuffer[0],50,stdin);if(strncmp(readbuffer,"QUIT",strlen("QUIT"))==0){flag_of_QUITEDIT=1;}//add"enter"to string{int len;len = strlen(readbuffer);readbuffer[len] = '\n';readbuffer[len+1] = '\0';}ret = write(fd,readbuffer,strlen(readbuffer));if(ret == -1){perror("write");exit(-1);}if(flag_of_QUITEDIT==1){close(fd);exit(Key_event_writeFile);}}}
}int display_file()
{int fd=0;fd = system(path_of_file);//printf("fd = %d\r\n",fd);if(fd>0){printf("cat file failed\r\n");}close(fd);exit(Key_event_displayFile);
}int copy_file()
{int fd=0;int fdSRC=0;int fdDES=0;char *readBuf = NULL;//fd = system(path_of_file);//printf("fd = %d\r\n",fd);//使用lseek实现copy;源文件:p->buffer_param2;目标文件:p->buffer_param3fdSRC = open(p->buffer_param2,O_RDWR);//打开文件if(fdSRC==-1){printf("src open failed\r\n");}else{//源文件打开成功int size = lseek(fdSRC,0,SEEK_END);//读取文件大小lseek(fdSRC,0,SEEK_SET);//把光标移动到文件头部readBuf = (char *)malloc(sizeof(char)*size + 8);//指针指向这么大的空间int n_read = read(fdSRC, readBuf, 1024);//把源文件的数据读取到buffer中fdDES = open(p->buffer_param3,O_RDWR|O_CREAT,0600);//创建目标文件int n_write = write( fdDES,readBuf,strlen(readBuf));//向目标文件写入信息close(fdSRC);close(fdDES);exit(Key_event_copyFile);}}int delete_file()
{int fd=0;fd = system(path_of_file);//printf("fd = %d\r\n",fd);if(fd!=0){printf("deete file failed\r\n");}exit(Key_event_deleteFile);
}

io.h

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#define Key_event_creatFile 0x01
#define Key_event_writeFile 0x02
#define Key_event_displayFile 0x03
#define Key_event_copyFile 0x04
#define Key_event_deleteFile 0x05
struct CMD_input{char CMD_CREAT[10];char CMD_CP[10];char CMD_DISPLAY[10];char CMD_DELETA[10];char CMD_WRITE[10];
};struct buffer_param{char buffer_param0[10];char buffer_param1[10];char buffer_param2[10];char buffer_param3[10];
};
void log_test1();
int read_CMD();
int task_sch();
int creat_file();
int write_file();
int display_file();
int copy_file();
int delete_file();

 编译运行,如图父进程等待子进程退出后,打印出了子进程退出的状态;

如果子进程是被exit(2);退出的;

那么打印的printf("child process exit status:%d\n",WEXITSTATUS(status_childProcess));就是2.


http://www.ppmy.cn/news/102562.html

相关文章

Unity使用SteamVR2.0实现基本功能(瞬移,抓取物品,射线点击,UI交互等)

基础设置 把SteamVR的Player预制件拖到一个空场景,删掉场景内原本的相机 一.瞬移 新建一个Plane,当做地板找到SteamVR的人物瞬移控制器 Teleporting ,把它拖到场景里 1. 范围移动 我们需要在可以移动的区域,也就是碰撞器上,挂TeleportArea脚本 这个脚本会自动修改你的材质球…

嵌入式实操--迁移git仓库至gitlab(二)

本文主要是通过迁移的思维&#xff0c;记录本人初次将git仓库迁移至gitlab进行管理 本文只讲述操作的实际方法&#xff0c;假设gitlab git已安装成功 。 1. 将git仓库进行克隆 由于git仓库用于管理代码&#xff0c;所以当中有很多的分支及tags&#xff0c;为了进行仓库迁移就…

排序算法专题_1_GnomeSort (侏儒排序)——最简单的排序

最简单的排序算法不是冒泡排序…&#xff0c;不是插入排序…&#xff0c;而是Gnome排序&#xff01; The simplest sort algorithm is not Bubble Sort…, it is not Insertion Sort…, it’s Gnome Sort! Gnome Sort is based on the technique used by the standard Dutch G…

华为OD机试真题 Java 实现【递增字符串】【2023Q1 200分】,附详细解题思路

一、题目描述 定义字符串完全由“A’和B"组成&#xff0c;当然也可以全是"A"或全是"B。如果字符串从前往后都是以字典序排列的&#xff0c;那么我们称之为严格递增字符串。 给出一个字符串5&#xff0c;允许修改字符串中的任意字符&#xff0c;即可以将任…

某SRC的渗透测试实战

前言 因为不甘心被称作会只点鼠标的猴子&#xff0c;所以开始了一次某SRC漏洞挖掘&#xff0c;为期一个多星期。文章有点长&#xff0c;但请耐心看完&#xff0c;记录了完整的SRC漏洞挖掘实战 渗透过程 因为选择的幸运儿没有对测试范围进行规划&#xff0c;所以此次范围就是…

斑梨电子Air101开发板LuatOS XT804内核QFN32支持128x160分辨率

spotpear.cn/index/product/detail/id/1332.html detail.tmall.com/item.htm?id719888144249 【产品简介】 [] Air101开发板使用Air101处理器&#xff0c;内置2MFlash和176KLuatOS专属RAM&#xff0c;最高主频可以达到240MHz,采用QFN32封装&#xff0c;18组GPIO可用。开发板…

Linux压缩和归档命令的速查表

在Linux系统中&#xff0c;有多种命令可用于压缩和归档文件和目录。这些命令使我们能够将文件和目录打包成单个文件&#xff0c;并可以选择压缩以节省存储空间。本文将提供一个Linux压缩和归档命令的速查表&#xff0c;帮助您快速查找和了解各种常用命令及其用法。 压缩文件和目…

如何在 Linux 中进行网络地址转换 (NAT)?

网络地址转换&#xff08;Network Address Translation&#xff0c;简称NAT&#xff09;是一种在网络中使用的技术&#xff0c;它允许将私有网络中的IP地址映射到公共网络上&#xff0c;从而实现多个设备共享单个公共IP地址。在Linux系统中&#xff0c;我们可以使用一些工具和配…