-
-
Notifications
You must be signed in to change notification settings - Fork 128
/
system_call_python.c
125 lines (99 loc) · 4.96 KB
/
system_call_python.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
This file is part of eRCaGuy_hello_world: https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world
GS
8 Dec. 2021
A C program which writes and calls Python, which Python program then converts text into executable
Python code (via `exec()`), which Python code calls the bash/system call executable `ping`.
4 layers: (1) C --> (2) Python --> (3) Text-to-Python via `exec()` --> (4) system/bash `ping` call.
A quadruple system abstraction demo (show `system()` calls in C): this is a program in C which:
1. writes a program in Python
2. which the C program then calls via a system call,
3. and the Python program runs and converts some text into a call which it `exec`s, and then it
4. uses another system call from the Python script to call the bash/system `ping` cmd to
5. ping the loopback IP address and get a response.
In short, it's a C program which uses system calls to write and call a Python script which then uses
a system call to ping. Pretty neat. I posted the code below in my answer here:
https://stackoverflow.com/a/70285228/4561887
To compile and run (assuming you've already `cd`ed into this dir):
1. In C:
mkdir -p bin && gcc -Wall -Wextra -Werror -O3 -std=c11 -save-temps=obj system_call_python.c \
-o bin/system_call_python && bin/system_call_python
2. In C++
mkdir -p bin && g++ -Wall -Wextra -Werror -O3 -std=c++17 -save-temps=obj system_call_python.c \
-o bin/system_call_python && bin/system_call_python
References:
1. I posted the code below in my answer here: https://stackoverflow.com/a/70285228/4561887
*/
// #include <assert.h> // For `assert()` and `static_assert()` macro wrappers in C11
#include <stdbool.h> // For `true` (`1`) and `false` (`0`) macros in C
#include <stdint.h> // For `uint8_t`, `int8_t`, etc.
#include <stdlib.h> // For `system()` calls
#include <stdio.h> // For `printf()`
#define PYTHON_CODE \
"# This is a Python program written (autogenerated) by and called by the C or C++ program\n" \
"# \"" __FILE__ "\". Run the C or C++ program to re-generate & call this Python program.\n" \
"imp = \"import os\"\n" \
"exec(imp)\n" \
"os.system(\"ping 127.0.0.1\")\n"
int main()
{
printf("Start\n");
// (I was going to write the command in a C array, like this, but decided against it and used a
// string literal down below instead.)
// const char cmd1[] = "echo '" PYTHON_CODE "' > system_call_python.py";
// printf("%s\n", cmd1);
int return_val;
return_val = system("echo '" PYTHON_CODE "' > system_call_python.py");
if (return_val != 0)
{
printf("Error: writing python file failed.\n");
}
// NB: for fun, you can uncomment the line just below as well, but watch out! The `&` is a bash
// symbol which causes the cmd to launch in a new process, so Ctrl + C will NOT kill the `ping`
// process. Rather, you'll have to do `pgrep ping` or `ps aux | grep ping` to find the process
// ID (PID) of the process, then you'll have to type `kill PID_number` to kill it manually.
// return_val = system("python3 system_call_python.py &");
return_val = system("python3 system_call_python.py");
if (return_val != 0)
{
printf("Error (non-zero return code): calling the Python program failed.\n");
}
printf("End\n");
return 0;
}
/*
SAMPLE OUTPUT:
In C:
eRCaGuy_hello_world/c$ mkdir -p bin && gcc -Wall -Wextra -Werror -O3 -std=c11 -save-temps=obj system_call_python.c -o bin/system_call_python && bin/system_call_python
Start
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.067 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.087 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.046 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.044 ms
^C
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4096ms
rtt min/avg/max/mdev = 0.044/0.062/0.087/0.018 ms
Error (non-zero return code): calling the Python program failed.
End
OR, in C++:
eRCaGuy_hello_world/c$ mkdir -p bin && g++ -Wall -Wextra -Werror -O3 -std=c++17 -save-temps=obj system_call_python.c \
> -o bin/system_call_python && bin/system_call_python
Start
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.091 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.061 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.057 ms
64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.073 ms
64 bytes from 127.0.0.1: icmp_seq=7 ttl=64 time=0.092 ms
^C
--- 127.0.0.1 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 6131ms
rtt min/avg/max/mdev = 0.024/0.067/0.092/0.022 ms
Error (non-zero return code): calling the Python program failed.
End
*/