I'm trying to set up some inter-process communication, and as a first idea I want to use a named pipe to forward messages from one process to the other. The thing I'm getting stuck on is ensuring that the first process only ever writes to the pipe, and the second process only ever reads from the pipe. Now, normally I could just write the program for the first process to only ever write to the pipe, and vice versa for the second process, but I'm somewhat paranoid and want the program to throw an error if it ever even tries to open the pipe in the wrong mode.
Essentially, what I'm trying to do is to "split" the pipe in half, so that the write-end is with my first program:
program1/
├── write-end-of-pipe
└── program1.c
and so that my read-end is with my second program:
program2/
├── read-end-of-pipe
└── program2.c
Ideally there could be actual files on the file system for the read/write ends of the pipe.
Right now, my best solution is the following:
Create a named pipe in
program1and change the file permissions to be write only by this user:cd ~/program1 mkfifo write-end-of-pipe chmod 200 write-end-of-pipeCreate a named pipe in
program2and change the file permissions to be read only by this user:cd ~/program2 mkfifo read-end-of-pipe chmod 400 read-end-of-pipeCreate a new user for forwarding, and have it run a daemon that forwards from the first named pipe to the second: (Assuming the user is already created:)
su - forwarding-daemon-user chmod 400 ~/program1/write-end-of-pipe chmod 200 ~/program2/read-end-of-pipe cat write-end-of-pipe > read-end-of-pipe &
The problem I have with this is twofold:
- It requires two pipes instead of just one.
- It requires a daemon. (My
catcommand earlier is not robust enough on its own, but it gets the point across.)
Is there a better way to create two files for a pipe, one of which can only be written to, and the other only read?
Edit 1: For some context on what I want to use this inter-process communication for: I think it would be cool if I could have a "screen-share" where one process written in one language creates a screen (essentially a video stream), and another process in an entirely different language displays the screen it receives. (Example use case: One language makes it easy to render a game, but you want to write your GUI in another language.) The reason for my paranoia about reading/writing is that I want to be able to swap out different programs that create screens or view screens, and I don't want to worry about connecting two screen creators together (if I provide a read end and a write end, then one program gets the wrong end if I make such a mistake, and the error is caught immediately instead of later when a pipe overflows) or otherwise broken programs causing silent problems.
Edit 2: I feel like I should give an explanation why having two separate users for the reading/writing is not an ideal solution for me. The main reason is that it is a significant step on the path towards containerization. Once you say, "I'll just control permissions via separate users/namespaces," you need to figure out how you are going to set up those users/namespaces, and that essentially means putting the program in a container. I want to avoid this because it's not as flexible; suddenly every program now needs a standardized way of being invoked, the named pipe connecting the two programs needs to be created by a special user that can peer into these containers, etc.
Hence, I would prefer to avoid multiple users, and similar techniques that require wrapping the program to be called. A solution that would work well would be if there was some way to "mount" the named pipe so that it has two different file permissions from the two different locations to be written to/read from, but I don't think this is possible on Linux.