
创建子进程后,父进程具有监听子进程的运行状态的能力,用到的函数为:
#include <sys/waith>pid_t wait(int status);
pid_t waitpid(pid_t pid, int status, int options);
以上函数用于等待子进程子进程的状态变化回调并且获取状态变化信息。所能获取到的状态变化包括:子进程运行结束、子进程被信号量暂停、子进程被信号量恢复运行。
父进程执行了wait函数后,如果子进程已经发生了状态变化,则wait函数立即就会有返回结果;否则wait函数会一直阻塞直至子进程状态发生变化。
通常意义上,如果子进程已经发生了状态变化,但还未被父进程或其它系统回调执行wait,则把此时的子进程称为是可等待的(waitable)。
子进程运行结束后,父进行执行wait函数可以推动系统释放与子进程相关的资源;否则子进程将会被维持在僵尸进程的状态下一直存在。
这是进程间同步的问题。解决方法是:fork一个子进程执行system调用,父进程调用 wait 或 waitpid 等待子进程的终止信息。
父进程调用 wait 或 waitpid 时可能会:
阻塞(如果它的所有子进程都还在运行)。
带子进程的终止信息立即返回(如果一个子进程已终止,正等待父进程读取其终止信息)。
出错立即返回(如果它没有任何子进程)。
wait 和 waitpid 这两个函数的区别是:
如果父进程的所有子进程都还在运行,调用wait将使父进程阻塞,而调用waitpid时如果在options参数中指定WNOHANG可以使父进程不阻塞而立即返回0。
wait等待第一个终止的子进程,而waitpid可以通过pid参数指定等待哪一个子进程。
函数详解
(执行shell 命令)
相关函数
fork,execve,waitpid,popen
表头文件
#include<stdlibh>
定义函数
int system(const char string);
函数说明
system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
返回值
如果fork()失败 返回-1:出现错误
如果exec()失败,表示不能执行Shell,返回值相当于Shell执行了exit(127)
如果执行成功则返回子Shell的终止状态
如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),仅当命令处理程序可用时,返回非零值,可以通过这一特征判断在一个给定的 *** 作系统上是否支持system函数(当system函数返回值为0时,表明system函数无效,在UNIX系统中,system函数总是可用的);。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。
附加说明
在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。
范例 #include<stdlibh>main(){system(“ls -al /etc/passwd /etc/shadow”);}执行结果:
-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shado
例2: char tmp[];sprintf(tmp,/bin/mount -t vfat %s /mnt/usb,dev);system(tmp);其中dev是/dev/sda1
与exec的区别
1、system()和exec()都可以执行进程外的命令,system是在原进程上开辟了一个新的进程,但是exec是用新进程(命令)覆盖了原有的进程
2、system()和exec()都有能产生返回值,system的返回值并不影响原有进程,但是exec的返回值影响了原进程
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)