简体   繁体   中英

How to get remaining buffer size of a Named Pipe(FIFO) in linux

In my application I am using Linux Named Pipe for a streaming data transfer. One application(app1) writes stream data to this FIFO, and other application(app2) reads from it.

When FIFO size is full, partial record will be written out to FIFO from app1, as Pipe's buffer size(4096 bytes) filled up. By this records are getting merged with some other record. So I want to know what is the remaining size in pipe buffer , before writing a record. With this I can compare current record size with remaining size in pipe buffer, If record size is more, then App1 will wait and write full complete record whenever pipe becomes free, as App2 will be reading continuously. I have tried using this, but no use:

fcntl(fd, F_GETPIPE_SZ );

Also is there a way to check this remaining pipe's buffer size using C or C++?

While I strongly discourage this approach, there is a way of achieving desired functionality, at least on some versions of Linux . For that one need to use ioctl with FIONREAD command to get the size of unread data inside pipe. The corresponding command is not available on all Linuxes out there, but it is available on mine.

Following small snippet of code shows how this technique could be applied in practice. Please do not think much of it, it is there for illustration only.

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include <iostream>

int main() {
    const size_t buf_sz = 4096;
    int fd[2];
    pipe(fd);

    int cap = fcntl(fd[0], F_GETPIPE_SZ);
    std::cout << "Pipe capacity: " << cap << "\n";
    int sz = 0;
    while (((cap - sz) >= buf_sz)) {

        char buf[buf_sz];
        write(fd[1], buf, sizeof(buf));
        ioctl(fd[1], FIONREAD, &sz);
        std::cout << "Avaialble to write: " << cap - sz << "\n";
    }
    std::cout << "No more room in the pipe.\n";
    char buf[buf_sz];
    read(fd[0], buf, buf_sz);
    ioctl(fd[1], FIONREAD, &sz);
    std::cout << "Available now: " << cap - sz << "\n";
}

On my machine, it provides following output: saristov@saristovlinux:~$ g++ test_pipe.cpp && ./a.out

Pipe capacity: 65536
Avaialble to write: 61440
Avaialble to write: 57344
Avaialble to write: 53248
Avaialble to write: 49152
Avaialble to write: 45056
Avaialble to write: 40960
Avaialble to write: 36864
Avaialble to write: 32768
Avaialble to write: 28672
Avaialble to write: 24576
Avaialble to write: 20480
Avaialble to write: 16384
Avaialble to write: 12288
Avaialble to write: 8192
Avaialble to write: 4096
Avaialble to write: 0

No more room in the pipe.
Available now: 4096

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM