Reputation:
I use a FIFO (named pipe) for IPC. Now process A calls
mkfifo(path)
open(path)
Naturally open()
will block until the file is written to by process B. Now I need a way to invalidate a FIFO. Therefore I call
unlink(path)
Now I expected that any blocking open
call would return, but they don't and my process hangs indefinitely.
How can I unblock the open
call when the FIFO is unlinked?
Do I have to resort to O_NONBLOCK
?
PS: I tried the suggested write/unlink/close approach to no avail. The open
call blocks immediately.
void invalidate() {
int fd = open(path, O_WRONLY)
unlink(path)
close(fd)
}
I think the issue is
The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.
However invalidate
should work without knowing if the FIFO is currently opened for reading or not.
Upvotes: 2
Views: 898
Reputation: 780994
The invalidator should open the FIFO in non-blocking write mode. This way, its call to open()
won't hang if there are no readers waiting for it. It should then close the FIFO immediately.
Any processes that were waiting in a read-only open will return when the FIFO is opened. Then they'll immediately read EOF.
void invalidate() {
int fd = open(path, O_WRONLY | O_NONBLOCK);
unlink(path);
close(fd);
}
Upvotes: 2
Reputation: 60068
On Linux you can (nonportably) open a FIFO in O_RDWR
mode. When you do and hold the FIFO, other openers won't get blocked in their open
calls (regardless of whether those are readonly or writeonly open calls). Then you can unlink the FIFO while still holding the O_RDWR
file handle to it.
Example code:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int C, char **V)
{
int fd;
if(0>(fd=open(V[1], O_RDWR))) return perror("open"),1;
if(0>unlink(V[1])) return perror("unlink"),1;
}
Upvotes: 0
Reputation: 48572
Open the FIFO for writing, unlink
it, then close it. This will make process A's open
succeed, and the resulting FD will immediately be at EOF. (By the way, the unlink
is unnecessary if you just want to make open
return, but is still a good idea for cleaning up.)
Upvotes: 0