execve()系统调用

execve()系统调用学习

先来一个小程序,  它的功能是打印父子进程号, 传入的全部参数及两个环境变量(如果有):

process.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[],char *env[])
{
    int i;
   char *p; printf(
"\n=========I am a process image!============\n"); printf("\nMy pid = %d, parentpid = %d\n", getpid(), getppid()); for(i=0; i< argc; i++) printf("\nargv[%d]: %s\n",i ,argv[i]); p = getenv("env1"); if(p != NULL) printf("\nenv1 = %s\n",p); p = getenv("env2"); if(p != NULL) printf("\nenv2 = %s\n\n",p); printf("\n============= process =================\n\n"); sleep(atoi(argv[1])); return 99; }

 

另一段代码myexec.c如下:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define ERROR(flag)                 \
    if(flag)                \
{                    \
    printf("%d: ",__LINE__);    \
    fflush(stdout);            \
    perror("error");        \
    exit(errno);            \
}

int main()
{
    int ret = 0;
    
    char *argv[] = {"11","22",NULL};    
    char *env[] = {"env1=1111111111111","env2=2222222222222",NULL};
       
    printf("\nthis is myexec file, pid is %d,  ppid is %d\n",getpid(),getppid());
    
//    ret = execl("process","11","22",NULL);
//    ret = execlp("process","11","22",NULL);
//    ret = execle("process","11","22",NULL,NULL);
//    ret = execv("process",argv);
//    ret = execvp("process",argv);
    ret = execve("process",argv,env);
    ERROR(ret == -1);
    
    return 0;
}

执行"make process myexec"后, 在当前目录下生成process和myexec两个可执行文件. 执行结果如下:

porcess.c代码将myexec.c代码执行时execve()系统调用传入的参数及环境变量息数打印了出来.

-------------------------------------------------------------------------------------------------------------------------------------------------

将myexec.c改造成如下代码:

#include <stdio.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#define ERROR(flag)                 \
    if(flag)                \
{                    \
    printf("%d: ",__LINE__);    \
    fflush(stdout);            \
    perror("error");        \
    exit(errno);            \
}

int main(int argc,char *argv[],char *env[])
{
    pid_t pid;

    pid = fork();
    //pid = vfork();
    ERROR(pid == -1);
    if(pid == 0)
    {
        printf("\nChild process is running\n");     
        printf("\nMy pid = %d ,parent pid = %d\n",getpid(),getppid());
        
        char *arglist[] = {"sleep","3",NULL};
        execvp("./process",arglist);      
        printf("process never go to here!\n");
        
        _exit(0);    
    }

    int stat;
    pid_t child_pid;

    child_pid = wait(&stat);
    printf("child process has exited, pid = %d\n\n",child_pid);

    if(WIFEXITED(stat))
        printf("child exited with code %d\n\n",WEXITSTATUS(stat));
    else
        printf("child exit abnormally\n\n");

    return 0;
}

执行"make myexec process" 后, 执行结果如下图:

子进程通过execvp()执行process. 父进程通过wait()取得子进程号及其(正常)退出运行时(通过WEXITSTAYUS()取得)的返回值.

--------------------------------------------------------------------------------------------------------------------------------------------------------------

一种通过c代码运行终端命令的方法:

mysystem,c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    system("ls --color=tty");
    return 0;
}

编译链接后运行, 其执行效果与在终端运行"ls --color=tty"命令的效果相同.

posted @ 2015-12-27 19:20  zhanglong71  阅读(2973)  评论(0编辑  收藏  举报