unix环境高级编程 首发于 UNIX环境高级编程学习之路

网络编程 2024-03-04 08:42www.168986.cn编程入门
作用
用fork函数创建新的子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。
特点
调用exec函数并不创建新进程,所以前后的进程ID并未改变
exec用磁盘上的一个新程序替换了当前进程的正文段、数据段、堆段和栈段
函数形式
#include <unistd.h>
 
int execl(const char pathname, const char arg0, ... / (char )0 /;  //l代表列表list
 
int execv(const char pathname, char const argv[]);,       //v表示矢量vector
 
int execle(const char pathname, const char arg0, ... / (char )0, char const envp[] / );          //e代表environment,表明可以导入环境变量
 
int execve(const char pathname, char const argv[], char const envp[]);
 
int execlp(const char filename, const char arg0, ... / (char )0 /;
 
int execvp(const char filename, char const argv[]];,
 
int fexecve(int fd, char const argv[], char const envp[]);
返回值 若出错则返回-1,若成功则不返回。
 
参数说明
pathname
前4个函数参数为路径名
 
filename
两个以filename为参数的函数(execlp和execvp),如果包含“/”,则就将其视为路径名.则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件,
 
PATH介绍
PATH变量包含了一张目录表(称为路径前缀),目录之间用冒号(:)分隔。例如 PATH=/bin:/usr/bin:/usr/local/bin:. 因为大部分的可执行文件都放在bin中,默认为bin文件夹下,并且的.表示当前文件夹。
 
注意
若execlp或exevcvp使用路径前缀中的一个找到了一个可执行文件,该文件不是由连接编辑器产生的机器可执行文件,则就认为该文件时一个shell脚本,于是尝试调用/bin/sh,并以该filename作为shell的输入。
 
args介绍
execl、execlp和execle是l(列表)系列输入参数args就是新可执行二进制文件的输入参数。例如我们选中的可执行二进制文件为date,命令为date +%s,那么arg0就是"date",arg1就是"+%s",并且以NULL结尾。 四个函数则应该先构造一个指向各参数的指针数组,然后将该数组地址作为这四个函数的参数。
 
环境表介绍
e表示环境,以e结尾的3个函数(execle、execve和fexecve)都可以传递一个指向环境字符串指针数组的指针。其他四个函数则使用调用进程中的environ变量为新程序复制现有的环境。
 
注意 这7个函数只有execve是内核的系统调用。6个只是库函数,它们最终都要调用该系统调用。它们的关系如下
 
 
基本实现举例
#include <unistd.h>
int main(){
  int pid;
  puts("Begin!");
  fflush(NULL);
  pid=fork();
  if(pid < 0){
    perror("fork()");
    exit(1);
  }
  if(pid == 0){
    execl("/bin/date","date","+%s",NULL);
    perror("execl()");
    exit(1);
  }
  wait(NULL);
  puts("End!");
  exit(0);
}
解释
 
 
fig8.16.c
#include "apue.h"
#include <sys/wait.h>
 
char    env_init[] = { "USER=unknown", "PATH=/tmp", NULL };
 
int
main(void)
{
    pid_t   pid;
 
    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {  / specify pathname, specify environment /
        if (execle("/home/sar/bin/echoall", "echoall", "myarg1",
                "MY ARG2", (char )0, env_init) < 0)
            err_sys("execle error");
    }
 
    if (waitpid(pid, NULL, 0) < 0)
        err_sys("wait error");
 
    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {  / specify filename, inherit environment /
        if (execlp("echoall", "echoall", "only 1 arg", (char )0) < 0)
            err_sys("execlp error");
    }
 
    exit(0);
}
解释
 
 
注意 这里的echoall是任意命令行的意思

Copyright © 2016-2025 www.168986.cn 狼蚁网络 版权所有 Power by