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



  进程程序替换:程序从硬盘加载到内存中并通过地址空间映射。进程程序替换过程只是将代码和数据替换,并没有创建新的进程,因为pid不变。

exec函数家族包括6种:execlexeclpexecleexecvexecvpexecve

Linux进程程序替换以及简单的shell_第1张图片

execve是最标准的系统调用函数,前5种都是基于execve函数。

只要exec函数调用成功,后续代码全部失效,所以不需要返回值来判断其是否调用成功。(适用于所有的exec开头的函数)

shell的运行原理:创建一个子进程程序,然后用子进程程序替换目标程序,(在此用的是exec函数家族),父进程等待,一旦出错立即退出,回收期退出码。

代码如下:

#include
#include
#include
#include
#include
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:表示读取文件出错。


你可能感兴趣的:(Linux,Linux,shell,进程程序替换)