1

I create FIFO to communicate between unrelated processes. In my project there is no way to break infinite loop in which the program runs. So, I can't unlink the FIFO.

I thought that I could remove and recreate with same name if the FIFO exist beforehand in writer process. But what if reader process open the FIFO before the write process has a chance to remove and recreate it? I could use sleep in this regard but it seems not efficient.

Moreover, I also thought that I could suspend the reader process until it receives a signal from the writer process but PID of the reader process is not known. Think them as two separate and different bash scripts. No sooner does OS start up than they start executions.

  • Is there a way to clean/flush the FIFO?
  • open() is used to open FIFO. If I close the FIFO and reopen it to write in a loop, is it cleaned/flushed? (guarantee?)

@Edit,

Checking inode always yields same inode number. I mean even though I use rm <fifo.name> via terminal, then recreate FIFO, same inode number is given.

FIFO = '/tmp/test.fifo'
fd = os.open(FIFO, os.O_RDONLY)

info = os.fstat(fd)
print("inf fstat " + str(info.st_ino))

statinfo = os.stat(FIFO)
print("inf stat " + str(statinfo.st_ino))

Output:

inf fstat 521406
inf stat 521406

stat information:

pi@raspberrypi:/tmp $ stat /tmp/test.fifo 
  File: /tmp/test.fifo
  Size: 0           Blocks: 0          IO Block: 4096   fifo
Device: b307h/45831d    Inode: 521406      Links: 1
Access: (0644/prw-r--r--)  Uid: ( 1000/      pi)   Gid: ( 1000/      pi)
Access: 2018-07-27 03:48:05.958234732 -0400
Modify: 2018-07-27 04:25:52.925375655 -0400
Change: 2018-07-27 04:25:52.925375655 -0400
 Birth -

As mentioned in a comment, here's a snippet of output from Ubuntu 16.04, previously uploaded to TextUploader:

soner@ubuntu:/tmp$ mkfifo test.fifo
soner@ubuntu:/tmp$ stat test.fifo 
  File: 'test.fifo'
  Size: 0           Blocks: 0          IO Block: 4096   fifo
Device: 801h/2049d  Inode: 2228362     Links: 1
Access: (0664/prw-rw-r--)  Uid: ( 1000/   soner)   Gid: ( 1000/   soner)
Access: 2018-07-26 23:41:31.482184467 +0300
Modify: 2018-07-26 23:41:31.482184467 +0300
Change: 2018-07-26 23:41:31.482184467 +0300
 Birth: -
soner@ubuntu:/tmp$ rm test.fifo 
soner@ubuntu:/tmp$ mkfifo test.fifo
soner@ubuntu:/tmp$ stat test.fifo 
  File: 'test.fifo'
  Size: 0           Blocks: 0          IO Block: 4096   fifo
Device: 801h/2049d  Inode: 2228362     Links: 1
Access: (0664/prw-rw-r--)  Uid: ( 1000/   soner)   Gid: ( 1000/   soner)
Access: 2018-07-26 23:41:46.766125062 +0300
Modify: 2018-07-26 23:41:46.766125062 +0300
Change: 2018-07-26 23:41:46.766125062 +0300
 Birth: -
soner@ubuntu:/tmp$ 
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Normally, the process that opens a FIFO for reading is blocked in the open call until there is a process open the FIFO for writing, and similarly, a process that opens a FIFO for writing is blocked until there is a process that opens the FIFO for reading. Once the processes are unblocked, they can communicate, and eventually one process will close their file descriptor for the FIFO, and the other then is notified (EOF for the reader, SIGPIPE or an error for the writer). If either of the processes wishes to resume using the FIFO, it must be reopened. – Jonathan Leffler Jul 27 '18 at 09:01
  • The recreating the FIFO with the same inode number is unusual. Normally, there'll be enough other activity on the file system that the FIFO won't be recreated with the same inode. However, I regard it as unlikely that the recreated FIFO is treated as the same FIFO by the kernel, even though they appear to have the same inode. I'm not 100% confident of that. Which platform are you working on? Do you do error checking of system calls? – Jonathan Leffler Jul 27 '18 at 09:04
  • @JonathanLeffler I'm working on _Raspberry PI Zero W_ with Raspbian OS. Actually I don't want to close reader process because it reads from FIFO and sends some textual information to LCD screen until the machine is turned off(or all processes are killed). Here my simplified code logic: https://textuploader.com/dznpo – Soner from The Ottoman Empire Jul 27 '18 at 09:08
  • If you want the reader to be able to keep reading without reopening the FIFO when each writer closes it, you need an extra writer — possibly the process itself. Once all the writers close the FIFO, it won't receive any more data — even if new writers try to open the FIFO. If there's one process that could write, the reader won't receive EOF, but new writers will be able to open and write. Be cautious! – Jonathan Leffler Jul 27 '18 at 09:13
  • @JonathanLeffler it is guaranteed that there is always one writer and one reader process each time. As you can see from the aforegiven link there are two while infinite loops for reading. It satisfies my wish. **The only issue here is** that cleaning content of FIFO when the machine is turned on every time. By the way, Raspbian OS is based on Debian – Soner from The Ottoman Empire Jul 27 '18 at 09:19
  • @JonathanLeffler Even Ubuntu 18.04 gives same result. I mean inode doesn't change. Could you glance at the output? https://textuploader.com/dznp7 – Soner from The Ottoman Empire Jul 27 '18 at 09:39
  • Instead of a FIFO, I would use an Unix domain datagram socket, bound to an abstract address. This way you avoid all the problems you're observing. – Nominal Animal Jul 27 '18 at 11:29
  • On a Mac, I ran a sequence of commands thus: `$ mkfifo x` — `$ ls -li x` — `8622846218 prw-r--r-- 1 jleffler staff 0 Jul 29 08:26 x` — `$ rm x` — `$ mkfifo x` — `$ ls -li x` — `8622846225 prw-r--r-- 1 jleffler staff 0 Jul 29 08:26 x` — `$ rm x` and as you may be able to see, the inode numbers were different (8622846218 vs 8622846225). This behaviour depends on your file system and on what other activity occurs on the file system at the same time. So, relying on the inode being the same is unwise; it still surprises me that you're seeing the consistency, but the evidence is clear. – Jonathan Leffler Jul 29 '18 at 15:27
  • Also testing on a Mac, I ran: `$ mkfifo fifo.1` — `$ (echo "Hello"; echo "Goodbye") > fifo.1 &` — `[1] 92494` — `$ read x < fifo.1` — `[1]+ Done ( echo "Hello"; echo "Goodbye" ) > fifo.1` — `$ echo $x` – `Hello` — `$ read x < fifo.1` — `^C-bash: fifo.1: Interrupted system call` — where the second read hung until I interrupted it. This shows that when the FIFO is closed on both ends, any residual data in the FIFO is emptied by the system. Thus, I believe your concerns about 'emptying the FIFO on startup' are unwarranted, at least on more or less traditional Unix systems. – Jonathan Leffler Jul 29 '18 at 15:39
  • If some process keeps the FIFO open (which cannot happen across a system reboot, of course), then the FIFO contents will remain available for use. That too could be demonstrated if necessary. – Jonathan Leffler Jul 29 '18 at 15:40
  • In your [comment](https://stackoverflow.com/questions/51527628/cleaning-flushing-of-named-pipe?noredirect=1#comment90075959_51527628) you mention [https://textuploader.com/dznpo](https://textuploader.com/dznpo). That has 'expired'. It is no longer available to us. That's why external links to other sites are frowned upon — the data isn't reliably persistent. Include the material in your question, please! We should not have to refer to an external site to comprehend the question. – Jonathan Leffler Jul 29 '18 at 15:45
  • @JonathanLeffler Thank you for your advice and sorry for late answer. I will not repeat the external link sharing from now on. Besides, you said _This shows that when the FIFO is closed on both ends, any residual data in the FIFO is emptied by the system_. I want to be sure I understand properly that after every boot(every reset to the OS), the remained FIFO's content cleaned automatically? Because the FIFO approximately stays open for 4-5 hours max. Then the OS is shutdown. After a while, re turned on. Moreover, when I restart the system `stat` shows its size `0` always. – Soner from The Ottoman Empire Aug 01 '18 at 11:01
  • 1
    A FIFO is empty on reboot. A FIFO remains empty until there is both a reader and a writer process with the FIFO open. The FIFO retains information while there is either a reader or a writer process. (Consider: `{ echo Hello; echo World; pause; } > FIFO &` (where `pause` is a program that executes the [`pause()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html) system call) followed by `read a < FIFO; echo $a` twice; that sequence echos `Hello` and `World` — and leaves the `pause` process to be killed. By contrast, if you omit the `pause`, you get `Hello` and then errors. – Jonathan Leffler Aug 01 '18 at 15:31
  • @JonathanLeffler That's why I wonder. Thank you sir indeed. – Soner from The Ottoman Empire Aug 01 '18 at 15:35

1 Answers1

1

Before reading from the FIFO, the reader can call os.fstat(fd) and os.stat(filename), and check whether the inode numbers are the same. If they're not, it means the writer has removed and recreated the FIFO, so it should reopen it before reading.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Could you check the question again? – Soner from The Ottoman Empire Jul 27 '18 at 07:53
  • Did the reading process have the FIFO open when you deleted the FIFO? After you delete a file (any type of file, including FIFOs) its inode can be reused, but the file isn't really deleted until all processes close it. – Barmar Jul 27 '18 at 15:18
  • I don't see any reading or writing processes there. This answer is about how to solve the problem when you need to clear the FIFO while another process is reading from it. Your test doesn't match those conditions. – Barmar Jul 28 '18 at 06:05