对于linux下system 函数的深度理解 整理

本文详细探讨了Linux环境下system函数的工作原理、返回值及其潜在问题。system函数通过fork和exec调用来执行命令,期间会忽略SIGINT和SIGQUIT信号。返回值包括错误值、子进程执行结果等,当在SUID/SGID程序中使用时可能带来安全问题。文章还介绍了如何处理system函数的错误状态,并推荐在某些情况下使用popen函数作为替代。最后,文章提到了一个由于系统升级改变SIGCHLD处理方式导致的问题,建议在使用system函数前恢复SIGCHLD为默认处理方式,以防止类似问题发生。
摘要由CSDN通过智能技术生成
                  这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为是其他的代码影响到这个,或是内核驱动文件系统什么的异常导致,昨天有出现了这个问题,就随手百了一下度,问题出现了,很多人都说system()函数要慎用要少用要能不用则不用,system()函数不稳定? 
 下面对system函数做一个简单的介绍: 
头文件 
 #i nclude 
定义函数 
 int system(const char * string); 
函数说明 
 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。 返回值 =-1:出现错误 =0:调用成功但是没有出现子进程 >0:成功退出的子进程的id 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。 
附加说明 
 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。 system函数已经被收录在标准c库中,可以直接调用,使用system()函数调用系统命令的基本使用方法如下: 
#include  
int main()
system("mkdir $HOME/.SmartPlatform/"); 
system("mkdir $HOME/.SmartPlatform/Files/"); 
system("cp mainnew.cpp $HOME/.SmartPlatform/Files/"); 
return 0; 
 下面我们来看看system函数的源码: 
#include  
#include  
#include  
#include  
int system(const char * cmdstring)
pid_t pid; 
int status; 
if(cmdstring == NULL)
return (1); 
if((pid = fork())<0)
status = -1; 
else if(pid = 0)
{
 execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); -exit(127); //子进程正常执行则不会执行此语句 } 
else
while(waitpid(pid, &status, 0) < 0)
{
 if(errno != EINTER){ status = -1; break; 
}
 } 
return status; 
花了两天时间仔细研究了一下,在网上发现了一篇精品博客,介绍的很详细了,谢谢博主,直接转, 原文如下: 
http://my.oschina.net/renhc/blog/53580 
【C/C++】Linux下使用system()函数一定要谨慎 
曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入。只是简单的知道用这个函数执行一个系统命令,这远远不够,它的返回值、它所执行命令的返回值以及命令执行失败原因如何定位,这才是重点。当初因为这个函数风险较多,故抛弃不用,改用其他的方法。这里先不说我用了什么方法,这里必须要搞懂system()函数,因为还是有很多人用了system()函数,有时你不得不面对它。 
先来看一下system()函数的简单介绍: 
#include  
int system(const char *command); 
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored. system()函数调用/bin/sh来执行参数指定的命令,/bin/sh 一般是一个软连接,指向某个具体的shell,比如bash,-c选项是告诉shell从字符串command中读取命令; 在该command执行期间,SIGCHLD是被阻塞的,好比在说:hi,内核,这会不要给我送SIGCHLD信号,等我忙完再说; 在该command执行期间,SIGINT和SIGQUIT是被忽略的,意思是进程收到这两个信号后没有任何动作。 
再来看一下system()函数返回值: 
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2). Thus, the exit code of the command will be WEXITSTATUS(s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值