Böyle birkaç programı birleştirmeye çalışıyorum (lütfen herhangi bir ekstra içerir görmezden gelin, bu devam etmekte olan yoğun çalışmadır):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Tekrar programının kaynağının aşağıdaki gibi olduğu yerler:
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
inline std::string readline(int fd, const size_t len, const char delim = '\n')
{
std::string result;
char c = 0;
for(size_t i=0; i < len; i++)
{
const int read_result = read(fd, &c, sizeof(c));
if(read_result != sizeof(c))
break;
else
{
result += c;
if(c == delim)
break;
}
}
return result;
}
int main(int argc, char ** argv)
{
constexpr int max_events = 10;
const int fd_stdin = fileno(stdin);
if (fd_stdin < 0)
{
std::cerr << "#Failed to setup standard input" << std::endl;
return -1;
}
/* General poll setup */
int epoll_fd = epoll_create1(0);
if(epoll_fd == -1) perror("epoll_create1: ");
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd_stdin;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd_stdin, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd_stdin << " failed: " << strerror(errno) << std::endl;
}
if (argc > 1)
{
for (int i = 1; i < argc; i++)
{
const char * filename = argv[i];
const int fd = open(filename, O_RDONLY);
if (fd < 0)
std::cerr << "#Error opening file " << filename << ": error #" << errno << ": " << strerror(errno) << std::endl;
else
{
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = fd;
const int result = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
if(result == -1) std::cerr << "epoll_ctl add for fd " << fd << "(" << filename << ") failed: " << strerror(errno) << std::endl;
else std::cerr << "Added fd " << fd << " (" << filename << ") to epoll!" << std::endl;
}
}
}
struct epoll_event events[max_events];
while(int event_count = epoll_wait(epoll_fd, events, max_events, -1))
{
for (int i = 0; i < event_count; i++)
{
const std::string line = readline(events[i].data.fd, 512);
if(line.length() > 0)
std::cout << line << std::endl;
}
}
return 0;
}
Bunu fark ettim:
- Boruyu sadece için kullandığımda
./repeat
, her şey amaçlandığı gibi çalışıyor. - Sadece süreç değişimini kullandığımda, her şey amaçlandığı gibi çalışıyor.
- Ben süreç ikame kullanarak pv kapsüllemek, her şey istendiği gibi çalışır.
- Ancak, belirli bir yapıyı kullandığımda, stdin'den veriyi (bireysel karakterler) kaybediyorum!
Aşağıdakileri denedim:
- Ben arasındaki boru devre dışı bırakmak arabelleğe çalıştık
pv
ve./repeat
kullananstdbuf -i0 -o0 -e0
tüm süreçler üzerinde, ama bu işin görünmüyor. - Anket için epoll'u değiştirdim, işe yaramıyor.
- Ben arasındaki dere baktığınızda
pv
ve./repeat
birliktetee stream.csv
, bu doğru görünüyor. - Kullandığım
strace
neler olduğunu görmek için, ben tek byte çok görmek okur (beklendiği gibi) ve ayrıca bu veri eksik oluyor gösteriyor.
Acaba ne oluyor? Ya da daha fazla araştırmak için ne yapabilirim?
<(...)
? Bundan daha güzel bir yol var mı<( 0<&- ...)
?