在Linux中,把程序载入内存并执行程序映像的操作与创建新的进程的操作是分离的,一次系统调用会把二进制程序加载到内存中,替换地址原来的内容并开始调用,利用系统调用exec()。另外一种系统调用时创建一个新的进程,基本上相当于复制其父进程,这个过程称为fork().
在shell下面运行 ls 的命令,strace ls 查看命令如下:
execve("/bin/ls", ["ls"], [/* 61 vars */]) = 0
brk(NULL) = 0x978b000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7705000
。。。。。。。。。。
可以看出,在敲出ls后,程序后台实际做了一件事就是系统调用execve函数。
shell命令的实现原理类似余下代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int ck_execvp(int argc,char *argv[])
{
char* srt[argc];
int i;
for(i = 0;i<argc;i++)
{
srt[i] = argv[i+1];
}
srt[i] = NULL;
execvp("srt[0]",srt);
return 0;
}
int main(int argc,char *argv[])
{
int pid;
pid = fork();
if(pid > 0)
{
printf("this is father process\n");
exit(0);
}
if(pid == 0)
{
printf("this is child process\n");
ck_execvp(argc,argv);
exit(0);
}
if(pid == -1)
{
perror("fork");
}
return 0;
}