The first attached piece of code is the python code I was using (in "test.py"). The second one is the c code (in "test.cpp" which I compiled to "test.out"). I am using ubuntu (18.04) wsl to run these programs.
I firstly established the pipes that will allow intercommunication between the two processes. Using fork I created a child process to call "test.out", which is the executable of the c code. I pass the file descriptors as arguments to the called program.
#Python
import os
import subprocess
import time
#establishing communication pipes
r_sub, w_py = os.pipe()
r_py, w_sub = os.pipe()
#creating a subprocess to run c code
pid = os.fork()
if pid > 0:
#Parent
os.close(r_sub)
os.close(w_sub)
print("[Py]Parent process is writing : r_py" str(r_py) " w_py" str(w_py) "r_sub" str(r_sub) " w_sub" str(w_sub))
text = b"message"
#Writing message to c .exe
os.write(w_py,text)
print("[Py]Written text:", text.decode())
os.close(w_py)
#Reading c message
rec = os.fdopen(r_py)
print("[Py]Received Message " rec.read())
else:
#Child
print("[SubP]Calling c .exe : r_sub" str(r_sub) " w_sub" str(w_sub) " r_py" str(r_py) " w_py" str(w_py))
#Calling .exe of c code
subprocess.call(["./test.out",str(r_sub),str(w_sub),str(r_py),str(w_py)])
//c
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <string>
#define MSGSIZE 16
int main(int argc, char *argv[]) {
if(argc < 5){
printf("[c ]File descriptors are not present");
return -1;
}
printf("[c ]I received file descriptors: r_sub%s w_sub%s r_py%s w_py%s\n",argv[1],argv[2],argv[3],argv[4]);
//Arguments are received as character arrays -> turning them to integers to use them as file descriptors
int r_sub = std::stoi(argv[1]), w_sub = std::stoi(argv[2]), r_py = std::stoi(argv[3]), w_py = std::stoi(argv[4]);
char buffer[MSGSIZE] = "";
close(r_py);
close(w_py);
//Here I find out that read fails
if(read(r_sub,buffer,MSGSIZE) == -1)
printf("\n:(\n");
printf("[c ]Received message: %s\n",buffer);
//Attempting to send message back to python
close(r_sub);
write(w_sub,"message back",MSGSIZE);
std::cout << "[c ]Finish\n\n";
return 0;
}
There are neither compilation errors nor "bad file descriptor" errors, but the communication does not work. Actually no information is received in either end. The Results:
python3 test.py
[Py]Parent process is writing : r_py5 w_py4r_sub3 w_sub6
[Py]Written text: message
[SubP]Calling c .exe : r_sub3 w_sub6 r_py5 w_py4
[c ]I received file descriptors: r_sub3 w_sub6 r_py5 w_py4
:(
[c ]Received message:
[c ]Finish
[Py]Received Message:
CodePudding user response:
You have some problems in your C program (like undefined behavior because you read your string literal out of bounds in write(w_sub, "message back", MSGSIZE);
) but the first problem is that your file descriptors aren't inherited by the started program - so they are all bad file descriptors in the C program. Always check - don't take anything for granted.
You can set the inheritance mode explicitly in python:
os.set_inheritable(r_sub, True) # do this for all fds that should be inherited
... or open the pipes with os.pipe2(0)
which makes them inheritable by default.
And make sure they aren't all closed when you start the sub-process:
subprocess.call(["./test.out",str(r_sub),str(w_sub),str(r_py),str(w_py)], close_fds=False)
# ^^^^^^^^^^^^^^^