What is the equivalent of this exact function call in the C language?
exec()
in Python will attempt to execute any string as Python. system()
in C or C++ (or an equivalent system()
call in any other language, for that matter, like os.system()
in Python) will attempt to execute any string as a system call, which is your shell language and could be Bash, Python, Perl, another C executable, or anything else for that matter.
So, there isn't an exact equivalent. But, the closest thing is probably the system()
call, which can call any string as a command-line command as though you had typed it at the terminal.
The C system()
call, however, is really an exact equivalent of the Python os.system()
call. Generally, only scripted programming languages have the exec()
call, while all or most programming languages have a system()
call. C (in general, I suppose, as there are probably C interpreters out there) is a compiled language, not a scripted language.
Going further, if you need to read back the stdout or stderr output from the command you called, you need to pipe it back to your process (since it gets spawned in a new process) using a pipe as an Inter-Process Communication (IPC) mechanism. You can open an IPC pipe via a call to popen()
. You'd use that in place of the system()
call. See here for an example: How can I run an external program from C and parse its output?
Here's a system()
call example I tested on Linux Ubuntu. You're gonna love this! It makes me laugh just looking at it. But, it's insightful and instructive nonetheless, and if you think about it, it opens up a TON of really cool possibilities.
system_call_python.c (for the latest version of this code, see system_call_python.c in my eRCaGuy_hello_world repo here):
#include <stdlib.h> // For `system()` calls
#include <stdio.h> // For `printf()
#define PYTHON_CODE \
"imp = \"import os\"\n" \
"exec(imp)\n" \
"os.system(\"ping 127.0.0.1\")\n"
int main()
{
system("echo '" PYTHON_CODE "' > myfile.py");
system("python3 myfile.py");
return 0;
}
Build and run cmd + output:
eRCaGuy_hello_world/c$ mkdir -p bin && gcc -O3 -std=c11 -save-temps=obj system_call_python.c -o bin/system_call_python && bin/system_call_python
system_call_python.c: In function ‘main’:
system_call_python.c:41:5: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result]
system("echo '" PYTHON_CODE "' > myfile.py");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
system_call_python.c:42:5: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result [-Wunused-result]
system("python3 myfile.py");
^~~~~~~~~~~~~~~~~~~~~~~~~~~
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.086 ms
Here is what myfile.py looks like, which the C code above autogenerated (see it in my eRCaGuy_hello_world repo here):
imp = "import os"
exec(imp)
os.system("ping 127.0.0.1")
So there you have it: have C construct some program in Bash or Python, then have C call it. Alternatively you could have C construct a program in C and have it compile and then call it--a program writing a program.