博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
exec()函数
阅读量:4298 次
发布时间:2019-05-27

本文共 5313 字,大约阅读时间需要 17 分钟。

1、exec()函数执行一个新的程序
exec()函数原型如下
int execl(cons char *pathname, const char *arg0,....);

int execle(const char *pathname, const char *arg0,..../*char *const envp[]*/);

int execv(const char *pathname,char *const argv[];

int execve(const char *pathname,char *const argv[],char *const envp[]);

int execlp(const char *filename,const char *arro,...);

int execvp(const char *filename, char *const argv[]);
"l"表示list,说明执行程序的命令行参数以列表的方式提供,并且以NULL结尾,但是没有参数个数限制。
"v"表示vector,说明命令行参数要以二维数组的形式提供给新程序,这个数组的每一行是一个命令参数。
"e"表示传递给新程序的环境变量,这个列表是一个二维数组,每一行是一个环境变量。如果没有显示地传递一个环境
表量表,那么新程序将复制父进程的环境表。
以p结尾的exec()函数表示第一个参数不是完整的路径名,而是一个程序名。
返回值:如果成功不返回任何值,如失败则返回-1。
例:
#include
#include
#include
#include
#include
int main(void){ pid_t pid; pid = fork(); if(pid<0){ printf("fail to fork\n"); exit(0); }else if(pid == 0){ if(execvp("./hello",NULL) < 0) { printf("fail to exec\n"); printf("%s\n",strerror(errno)); exit(errno); } printf("the child is not hello\n"); exit(errno); } printf("the parent\n"); return 0;}$lshell.c hello hello.c test test.c$./test the parenthello
执行了exec()函数的进程不改变以下进程特征
     1、进程ID和父进程ID
     2、实际用户ID和实际组ID
     3、进程组ID和附加组ID
     4、控制终端
     5、会话ID
     6、时钟余留时间
     7、当前工作目录和根目录。
     8、文件创建屏蔽字和文件锁
     9、信号屏蔽字和未处理信号集
    10、资源限制。

改变

      1、有效用户ID和有效组ID
2、在程序中执行shell命令

system()函数调用shell指令

#include<stdlib.h>
int system(const char * cmdstring)
参数cmdstring是需要执行的shell命令。
system的返回值的情况比较复杂,system()函数是一个库函数,其中封装了fork、exec和waitpid这个3个系统,
其返回值也要根据这3个系统调用的情况来讨论

    1、如果fork()函数和waitpid函数执行失败,则system()函数返回-1

    2、如果exec()函数执行失败,system()函数返回如图shell调用了exit(127)一样,表示指定文件不可执行

    3、如果3个函数都成功执行,system()函数返回执行程序的终止状态,其值和echo $?的值是一样的。

    4、如果参数cmdstring所指向的命令字符串为NULL,system()函数返回1。

例:

#include
#include
#include
#include
#define MAX 1024int main(void){ int fd,n; char buf[MAX]; if(system("ls > temp.txt") == -1) { perror("fail to exec command\n"); exit(0); } if(fd = open("temp.txt",O_RDWR) == -1) { perror("fail to open\n"); exit(1); } if(fd = read(fd,buf,MAX) == -1){ perror("fail to read\n"); exit(1); } buf[n] = '\0'; printf("%s",buf); return 0;}
$gcc system.c -o system

$./system

temp.txt

system.c

system
3、等待进程退出操作
a、

wait()函数得到子进程的结束信息。

#include<sys/wait.h>

pid_t wait(int *statloc);

    调用wait()函数的进程会阻塞,直到该进程的任意一个子进程结束。wait()函数会取得结束的子进程的信息并返回子进程的进程ID,结束信息保存在参数statloc所指向的内存空间中,如果该进程没有子进程,则立即出错返回,返回值为-1.

状态                          判断宏                             取得宏
进程正常结束           WIFEXITED(status)           WEXITSTATUS(status)
进程异常结束           WIFSIGNALED(status)     WTERMSIG(status)
进程暂停                  WIFSTOPPED(status)      WSTOPSIG(status)

例:

#include
#include
#include
#include
int main(void){ pid_t pid; int num,status; pid = fork(); if(pid<0){ printf("fail to fork\n"); exit(0); }else if(pid == 0) { printf("the fist, exit normally\n"); exit(0); }else { if(wait(&status) == -1) { perror("fail to wait"); exit(1); } if(WIFEXITED(status) == 1) { printf("the status of first is :%d\n",WEXITSTATUS(status)); } } pid = fork(); if(pid<0) { printf("fail to fork\n"); exit(0); }else if(pid == 0) { printf("the second, exit abnormally\n"); num = 1/0; }else { if(wait(&status) == -1){ perror("fail to wait"); exit(1); } if(WIFEXITED(status) == 1) { printf("the terminated signal is :%d\n",WEXITSTATUS(status)); } } return 0;}

$gcc wait.c -o wait

$./wait
the first ,exot normally
the stasus of first is:0
the second,exit abnormally
the terminated signal is:8

b、#include<sys/wait.h>

pid_t waitpid(pid_t pid, int *statloc,int options);
pid :指定要等待的子进程的进程ID,其还有一些其他作用,如
    -1 :     等待任意子进程
   >0:        等待进程ID和pid相等的子进程
   0:         等待组ID和pid相等的子进程 
   <-1:      等待组ID等于pid绝对值的组内的任意子进程。
option:
        WCONTINNUED :         当进程在暂停后继续执行,且其状态尚未报告,则返回其状态
        WNOHANG:                  当等待进程尚未结束运行时不阻塞,waitpid()函数直接返回
        WUNTRACED:             当子进程暂停,并且其状态自暂停以来还未报告过,则返回其状态
例:
#include
#include
#include
#include
int main(void){ pid_t pid; int num,status; pid = fork(); if(pid<0) { printf("fail to fork\n"); exit(1); }else if(pid == 0) { printf("the to fork\n"); sleep(5); exit(0); }else { printf("the parent\n"); if(waitpid(pid,NULL,WNOHANG) == 0) { printf("the child is not available now\n"); } } printf("no waiting,parent done\n"); return 0;}
$gcc waitpid.c -o waitpid
./waitpid

the parent

the child is not available now
no waiting, parent done
the child
waitpid()函数和wait()函数的区别有以下3点:

     1、waitpid()函数可以指定一个子进程。

     2、waitpid()函数可以不阻塞等待一个子进程。

     3、waitpid()函数支持作业控制。

4、输出进程统计信息

#include
#include
#include
#include
pid_t wait3(int *statlic, int options, struct rusage *rusage);pid_t wait4(pid_t pid, int *statloc, int options,struct rusage *rusage);

转载地址:http://tynws.baihongyu.com/

你可能感兴趣的文章
ITK4.12+VS2015配置详解
查看>>
python图像处理---python的图像处理模块Image
查看>>
python在局域网中实现文件上传和下载功能
查看>>
功能1:人脸检测,效果不好,基本上一般判断错误。
查看>>
功能2:播放视频 + 摄像头视频
查看>>
功能3:读取摄像头视频,人脸检测
查看>>
Demo1:视频人体检测
查看>>
Demo2:图片人体检测 (图片hog参数,效果还可以了)
查看>>
Demo3:视频人体检测
查看>>
TensorFlow实现卷积神经网络CNN
查看>>
CT值
查看>>
TensorFlow入门:给小狗分类
查看>>
基于YOLOv3+Kalman-Filter实现Multi-target tracking
查看>>
OpenCV优化:图像的遍历4种方式
查看>>
图像方面面试问题汇集
查看>>
在ARM-Linux下实现车牌识别(一)------车牌提取
查看>>
在ARM-Linux下实现车牌识别(二)------车牌识别
查看>>
detectormorph.cpp源码解读
查看>>
OpenCV 中boundingRect、minAreaRect的用法区别
查看>>
libfacedetection 余老师的人脸检测
查看>>