I want to execute a terminal command of Linux in a C program. Currently I am using system()
function but I want to use any other as the system()
function is banned as per MISRA.
For example, how can I replace
system("hwclock --systohc --utc");
I want to execute a terminal command of Linux in a C program. Currently I am using system()
function but I want to use any other as the system()
function is banned as per MISRA.
For example, how can I replace
system("hwclock --systohc --utc");
First you can use fork()
to create a child process, then in the child process, you can call exec()
to execute command what you want.
There is a simple example:
$ 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;
}
You can make use of fork()
and then look up for exec()
family of functions.
Alternatively, you may want to have a look at popen()
also.
This is a very interesting question. My understanding of MISRA C is that it provides guidelines for the use of the C language in critical systems. But the C language standard library, which includes the system
function, is merely a small piece of the sum total of library code typically used in modern applications -- often even in embedded systems.
I've never developed an application to MISRA standards, and I've only been able to find a slightly older (from 2004) version of the MISRA guidelines. From what I can tell, MISRA is silent about the use of POSIX library functions, which you are typically going to have available on any kind of Linux-based system. If MISRA really is silent about POSIX library functions, then it stands to reason that any functions in the POSIX library should be unrestricted. That would include fork
, exec
, and popen
which are all defined by POSIX, not by the C language standard. Of the three, popen
is probably most similar in functionality/interface to the C system
function.
That said, you may want to ask yourself why MISRA C restricts the use of the system
function and whether or not the same rationale applies to the use of the above three functions as well.
The letter of MISRA C:2012/2023 Rule 21.21 (previously part of MISRA C:2012 Rule 21.8) is that the system()
function shall not be used.
The spirit of the Rule is that equivalent functions should not be used either - the rationale for the Rule explains why: executing external features is a major security vulnerability.
If you really need to do so, then the correct approach is deviate the Rule (with justification and mitigation) rather than trying to find a workaround.
-- See profile for affiliation.
Using fork
+ exec
family of functions is usually the suggested approach and a simple implementation is straightforward however what I've found is that it is a mine field of edge cases.
system()
uses fork + exec internally and just look at glibc's implementation its source code is huge to deal with all the signal handlers. But signal handlers clearance + restoration must be dealt in a thread safe manner so there's also race condition issues that need to be accounted in multithreaded code, which is why glib's code is so unreadable.
I suggest you use posix_spawn instead if available, which is far more user friendly and, unlike system
, has a safer interface.