您的位置:首页 > 运维架构 > Shell

Linux进程程序替换以及简单的shell

2017-03-01 19:01 423 查看

  进程程序替换:程序从硬盘加载到内存中并通过地址空间映射。进程程序替换过程只是将代码和数据替换,并没有创建新的进程,因为pid不变。
exec函数家族包括6种:execl、execlp、execle、execv、execvp、execve



execve是最标准的系统调用函数,前5种都是基于execve函数。
只要exec函数调用成功,后续代码全部失效,所以不需要返回值来判断其是否调用成功。(适用于所有的exec开头的函数)
shell的运行原理:创建一个子进程程序,然后用子进程程序替换目标程序,(在此用的是exec函数家族),父进程等待,一旦出错立即退出,回收期退出码。
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
int main()
{
char cmd[128];
while(1)
{
printf("[test@my-host-name myshell]# ");
fflush(stdout);
//sleep(5);
ssize_t _s=read(0,cmd,sizeof(cmd)-1);
if(_s>0)
{
cmd[_s-1]='\0';
}
else
{
perror("read");
return 1;
}
//ls -a -l -n -i
char *_argv[32];
_argv[0]=cmd;
int i=1;
char *start=cmd;
while(*start)
{
if(isspace(*start))
{
*start='\0';
start++;
_argv[i]=start;
i++;
printf("i=%d\n",i);
continue;
}
printf("i=%d\n",i);
start++;
}
_argv[i]=NULL;
printf("%s\n",cmd);
pid_t id=fork();
if(id<0)
{
perror("fork");
}
else if(id==0)
{
//child ->run cmd
execvp(_argv[0],_argv);
exit(1);
}
else
{
int status=0;
pid_t ret=waitpid(id,&status,0);
if(ret>0 && WIFEXITED(status))
{
printf("exit code:%d\n",WEXITSTATUS(status));
}
else
{
perror("waitpid");
}
}
}
}

在上述代码中,read函数的返回值_s存在3种情况
_s>0:表示文件读取成功,且读取成功的数值小于等于sizeof(cmd)-1;
_s=0:表示做所读取的文件描述符已读到文件的结尾;
_s<0:表示读取文件出错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息