说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
内容来源:
《Linux系统编程》、《Linux网络编程》
函数功能:同步的创建进程,即:进程创建新进程后立刻开始等待它结束。
一般用来运行简单的工具程序或shell脚本,并得到对应的返回值。
调用“/bin/sh-c command”执行特定命令,阻塞当前进程command命令执行完毕。
| 项目 | 说明 |
|---|---|
| 函数原型 | extern int system (const char *__command) __wur; |
| 头文件 | stdlib.h |
| 参数说明 | __command:shell命令行指令 |
| 返回值 | 成功则返回执行命令得到的返回状态(可用WEXITSTATUS得到) 失败则返回-1. sh不能执行则返回127 |
| 注意 | ①若command是NULL且/bin/sh可用,则返回非零值,其他情况返回0 ②执行该函数时,会调用fork、execve、waitpid等函数,若其中任一失败则该函数调用失败 ③在命令执行的过程中,SIGCHILD信号是被阻塞的,而且 SIGINT和sIGQUIT信号会被忽略。 |
(1)示例功能说明:
1.获取当前进程的ID并输出到屏幕上。
2.使用system()函数进行系统调用ping某网址。
3.将system()函数返回值输出到屏幕上。
(2)源程序:system.c
#include#include int main(int argc,char *argv[]) { int ret = 0; printf("系统分配的进程号是:%dn",getpid()); ret = system("ping www.baidu.com -c 2"); printf("返回值:%dn",ret); return 0; }
(3)编译并运行:
①编译程序:gcc system.c -o system
②运行程序:./system
(4)运行结果
系统分配的进程号是:4425 PING www.a.shifen.com (220.181.38.150) 56(84) bytes of data. 64 bytes from 220.181.38.150: icmp_seq=1 ttl=128 time=43.0 ms 64 bytes from 220.181.38.150: icmp_seq=2 ttl=128 time=43.2 ms --- www.a.shifen.com ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 43.071/43.169/43.267/0.098 ms 返回值:0三、对SIGINT和SIGQUIT信号的忽略
实现对SIGINT和SIGQUIT信号的忽略有好几种实现方式,特别是当system()在循环中被调用的时候。如果在一个循环中调用system(),那么你需要保证子进程的退出状态要被正确检测。例如:
do {
int ret;
ret = system ("pidof rudderd" ) ;
if(wIFSIGNALED (ret) & &( WTERMSIG (ret) ==SIGINT llwTERMSIG (ret) == sIGQUIT))
break;
}while (1);
四、实现system()函数
利用fork()、exec系列、waitpid()实现system()函数。
int my_system (const char *cmd)
{
int status;
pid_t pid;
pid = fork ( );
if (pid == -1)
return -l;
else if (pid -= 0)
{
const char *argv[ 4];
argv[ 0] ="sh" ;
argv[ 1] =“-c";
argv[ 2] = cmd;
argv[ 3] = NULL;
execv ("/bin/sh" ,argv) ;
exit (-1);
}
if( waitpid (pid, &status,0)== -1)
return -l;
else if (WIFEXITED (status))
return WEXITSTATUS (status);
return -l;
PS:
注意这个例子不像正式的system(),它没有阻塞或者禁止任何信号。根据你程序的情况,这可能是好事也可能是坏事。但是至少要保证SIGINT信号不被阻塞,这是很明智的,因为这样可以按照用户的意愿随时终止命令的执行。一个较好的实现可以将额外的指针做为参数,当参数为非空时,代表不同的错误。例如可能会加入fork_failed 和 shell failed。



