'Communication through named pipe works with file descriptors but not with unbuffered operation to FILE*
I have two programs that need to communicate with each other. I choose named pipe as IPC mechanism. One program is in C++ and the other one is a python script but for testing purposes, I will show the behaviours with two C programs.
Let's say program A is the C++ one and program B is the python script. I have two named pipes: one for A to B communications and one for B to A communications. I need the pipes to be unbuffered because I will use the read operation as a synchronization mechanism and I want to be able to send 1 byte of data, plus no text will be transmitted between the programs, only raw bytes.
Program A:
- creates the named pipes in unbuffered mode and fork and launch the python script (i.e. Program B)
- read from pipe to program B
- write to pipe for program B
Program B:
- write to pipe for program A
- read from pipe to program A
In program A I use the functions fopen,fwrite and fread for IO operations. In python, I used the open (not os.open) function.
My problem is that at step 2 of program B I have a BUS ERROR on program A at step 3, plus in program A the data read at step 2 is not the data send from step 1 of program B.
Here is a diagram of what happened:
To understand what happened, I created to small C programs that I launched manually to reproduce the error:
equivalent to program A:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
umask(0);
mkfifo(".ed.fifo", 0777);
mkfifo(".de.fifo", 0777);
FILE* toDebugger = fopen(".ed.fifo", "wb");
FILE* fromDebugger = fopen(".de.fifo", "rb");
setbuf(toDebugger, "U");
setbuf(fromDebugger, "U");
uint8_t g;
fread(&g,1,1,fromDebugger);
printf("received %#x\n",g);
g = 0xAB;
fwrite(&g,1,1,toDebugger);
fclose(toDebugger);
fclose(fromDebugger);
return EXIT_SUCCESS;
}
equivalent to program B:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (void)
{
FILE* fromEmulator = fopen(".ed.fifo", "rb");
FILE* toEmulator = fopen(".de.fifo", "wb");
setbuf(fromEmulator, "U");
setbuf(toEmulator, "U");
uint8_t g = 5;
fwrite(&g,1,1,toEmulator);
fread(&g,1,1,fromEmulator);
printf("received from c++: %#x\n", g);
fclose(toEmulator);
fclose(fromEmulator);
return EXIT_SUCCESS;
}
In those two test programs, I tried to use file descriptors instead of FILE* with the functions open, read and write and everything worked perfectly:
equivalent to program A:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
umask(0);
mkfifo(".ed.fifo", 0777);
mkfifo(".de.fifo", 0777);
int toDebugger = open(".ed.fifo", O_WRONLY);
int fromDebugger = open(".de.fifo", O_RDONLY);
uint8_t g;
read(fromDebugger,&g,1);
printf("received %#x\n",g);
g = 0xAB;
write(toDebugger,&g,1);
close(toDebugger);
close(fromDebugger);
return EXIT_SUCCESS;
}
equivalent to program B:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (void)
{
int fromEmulator = open(".ed.fifo", O_RDONLY);
int toEmulator = open(".de.fifo", O_WRONLY);
uint8_t g = 5;
write(toEmulator,&g,1);
read(fromEmulator,&g,1);
printf("received from c++: %#x\n", g);
close(toEmulator);
close(fromEmulator);
return EXIT_SUCCESS;
}
My question is why using directly file descriptors makes things suddenly work as expected, and since in my real application program B is in python, is using file descriptors in python possible and portable on windows?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|

