Хотя я категорически не одобряю этот подход, существует способ достижения желаемой функциональности, по крайней мере, в некоторых версиях Linux.Для этого нужно использовать ioctl
с командой FIONREAD
, чтобы получить размер непрочитанных данных внутри канала.Соответствующая команда доступна не во всех Linux, но у меня она доступна.
Следующий небольшой фрагмент кода показывает, как этот метод может быть применен на практике.Пожалуйста, не думайте об этом, это только для иллюстрации.
#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";
}
На моей машине это обеспечивает следующий вывод: 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