函数简介篇——进程创建函数:system()

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  《Linux系统编程》、《Linux网络编程》、《Unix环境高级编程》

system()函数

一、函数介绍:

  1.函数功能:同步的创建进程,即:进程创建新进程后立刻开始等待它结束。【依赖操作系统】
    一般用来运行简单的工具程序shell脚本,并得到对应的返回值。
    调用“/bin/sh-c command”执行特定命令,阻塞当前进程command命令执行完毕。

项目 说明
函数原型 int system(const char *command);
头文件 stdlib.h
参数说明 command:shell命令行指令
返回值 成功则返回执行命令状态(可用WEXITSTATUS得到)
失败则返回-1,并设置errno(fork失败或waitpid返回除EINTR外的错误).
sh不能执行则返回127(exec失败)
注意 ①若command是NULL且/bin/sh可用,则返回非零值,其他情况返回0
②执行该函数时,会调用fork、execve、waitpid等函数,若其中任一失败则该函数调用失败
③在命令执行的过程中,SIGCHILD信号是被阻塞的,而且 SIGINT和sIGQUIT信号会被忽略。
④若进程正以特殊权限运行(设置用户ID/设置组ID),又想生成另一进程执行另一程序则应使用fork().exec().且exec()之前需改回普通权限。

  2.函数实现:实现中调用fork()、exec()、waitpid()
    

二、示例实践:

  (1)示例功能说明:
    1.获取当前进程的ID并输出到屏幕上。
    2.使用system()函数进行系统调用ping某网址。
    3.将system()函数返回值输出到屏幕上。
  (2)源程序:system.c

#include<stdlib.h>
#include<unistd.h>

int main(int argc,char *argv[])
{
	int ret = 0;
	printf("系统分配的进程号是:%d\n",getpid());
	ret = system("ping www.baidu.com -c 2");
	printf("返回值:%d\n",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
三、对SIGINTSIGQUIT信号的忽略

  实现对SIGINTSIGQUIT信号的忽略有好几种实现方式,特别是当system()在循环中被调用的时候。如果在一个循环中调用system(),那么你需要保证子进程的退出状态要被正确检测。例如:

do {
	int ret;
	ret = system ("pidof rudderd" ) ;
	if(wIFSIGNALED (ret) & &( WTERMSIG (ret) ==SIGINT llwTERMSIG (ret) == sIGQUIT))
		break; /* or otherwise handle */
}while (1);
四、实现system()函数

  利用fork()exec系列waitpid()实现system()函数。

/*
 my_system -同步生成并等待命令
 "/ bin/sh -c <cmd>"
 任何类型的错误,或启动进程的退出码返回-1。不阻断或忽略任何信号。
*/
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。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值