c Linux中system()的替代方法,用于在Linux上执行终端命令

h5qlskok  于 2023-08-03  发布在  Linux
关注(0)|答案(5)|浏览(273)

我想在一个C程序中执行一个Linux的终端命令。目前我正在使用system()函数,但我想使用任何其他的system()函数是禁止根据MISRA。
例如,我如何替换

system("hwclock --systohc --utc");

字符串

wd2eg0qa

wd2eg0qa1#

首先你可以使用fork()创建一个子进程,然后在子进程中,你可以调用exec()来执行你想要的命令。
有一个简单的例子:

$ chmod u+x command.sh 
$ cat command.sh  
#!/usr/bin/env bash   
ls -l

字符串
test.c

#include<unistd.h>
int main(void)
{
  execl("./command.sh","command.sh",(char*)0);
  return 0;
}

yb3bgrhw

yb3bgrhw2#

您可以使用fork(),然后查找exec()系列函数。
或者,您可能还想看看popen()

s6fujrry

s6fujrry3#

这是一个非常有趣的问题。我对MISRA C的理解是,它为在关键系统中使用C语言提供了指导方针。但是,C语言标准库(包括system函数)只是现代应用程序中通常使用的库代码总和的一小部分,甚至常常用于嵌入式系统。
我从未开发过符合MISRA标准的应用程序,我只能找到MISRA指南的稍旧版本(2004年)。据我所知,MISRA对POSIX库函数的使用保持沉默,而POSIX库函数通常可以在任何基于Linux的系统上使用。如果MISRA真的对POSIX库函数保持沉默,那么POSIX库中的任何函数都应该是不受限制的。这将包括forkexecpopen,它们都是由POSIX定义的,而不是由C语言标准定义的。在这三者中,popen可能在功能/接口上与C system函数最相似。
也就是说,您可能想问问自己为什么MISRA C限制使用system函数,以及是否同样的原理也适用于上述三个函数的使用。

ezykj2lf

ezykj2lf4#

MISRA C:2012/2023规则21.21(之前为MISRA C:2012规则21.8的一部分)的信函规定,不得使用system()函数。
该规则的精神是,也不应使用等同的职能--该规则的基本原理解释了为什么:执行外部功能是一个主要的安全漏洞.
如果您真的需要这样做,那么正确的方法是 * 偏离 * 规则(提供合理性和缓解措施),而不是试图找到变通办法。
--请参阅个人资料了解所属机构。

mwg9r5ms

mwg9r5ms5#

使用fork + exec函数族通常是建议的方法,而a simple implementation is straightforward,但我发现它是边缘情况的雷区。
system()在内部使用fork + exec,看看glibc的实现,它的源代码非常庞大,可以处理所有的信号处理程序。但是信号处理程序清除+恢复必须以线程安全的方式处理,因此在多线程代码中也需要考虑竞争条件问题,这就是为什么glib的代码如此不可读。
我建议你使用posix_spawn,如果可用的话,它对用户更友好,而且不像system,它有一个更安全的接口。

相关问题