Imprimindo de um tubo FIFO sem interferir?

2

Eu tenho um par de programas em C enviando mensagens de um lado para outro através de pipes nomeados FIFO no Unix, e eu quero ver o que está passando pelos pipes usando um programa externo. O problema é que, se eu usar cat , ele pára depois da próxima vez que meu programa chamar write() e fechar o canal, interrompendo a comunicação entre os programas ... e, então, coisas ruins acontecem. Eu não entendo porque cat está fechando meu cachimbo. EDIT: Na verdade, eu fiz exatamente a mesma coisa hoje, e em vez de fechar o pipe, ele apenas fez o processo parar de ler a partir dele.

Então, há algo como cat , exceto que ele não irá interferir nos canais, apenas imprima o que ele vê passando?

Caso seja relevante, eu crio os canais assim em C:

outs[i2/2] = open("/tmp/pipe_w", O_WRONLY);
ins[i2/2] = open("/tmp/pipe_r", O_RDONLY);

Atualização: aqui está um exemplo de terminal.

Meus processos imprimem essa saída quando eles abrem os canais:

Opened in pipe at /tmp/ai1In
Opened out pipe at /tmp/ai1Out

Então faço isso em um shell separado:

admin$ cat /tmp/ai1Out
ai1

Ele vê a mensagem "ai1" passar e, em seguida, nada. O processo de leitura desse cachimbo acaba esperando para sempre. Eu mato cat , mas o pipe ainda não está sendo lido.

Atualização 2:

cat [path] | tee [path] funciona em alguns casos. Isso não interfere de maneira notável no meu ai1Out pipe, mas interfere com ai1In . A diferença deve ser devida ao meu código. Independentemente disso, isso significa que executar este comando tem algum efeito sobre os outros processos usando os pipes, o que eu não quero. Quando eu tento ler ai1Out , eu apenas vejo isso, então o processo de gravação para esse pipe recebe um erro em sua próxima write() call:

admin$ cat /tmp/ai1In | tee /tmp/ai1In
]2,15,43,66,65,61,53,20,30,27,40,16,50,41,48[[[[[[[[
    
por sudo 18.04.2015 / 09:56

1 resposta

3

A definição de um pipe é que os dados gravados nele são lidos no outro extremo. Um pipe não duplica dados. Ler em um tubo é uma operação destrutiva. Se houver dois leitores em um pipe, cada byte será lido por apenas um dos leitores.

Se você quiser espionar a comunicação entre dois programas através de um pipe, você pode fazê-lo inserindo tee entre os programas. Existem dois canais: um do gravador para tee e um de tee para o leitor.

mkfifo pipe_w pipe_r
writer >pipe_w
reader <pipe_r
<pipe_w tee pipe_r

O esquema de nomeação de canal na sua pergunta é inconsistente, por isso não sei exatamente o que você tentou. Parece que você tentou alimentar os dados de um canal de volta para si mesmo. Isso não funciona: você criou um loop fechado em que alguns dos dados voltam para o pipe para sempre (apenas alguns dos dados, porque é imprevisível quais bytes retornarão ao pipe e quais bytes irão para o original). leitor).

Se houver um canal entre dois processos e você não puder alterar o encanamento, a maneira mais fácil de espioná-lo é rastrear o processo do gravador ou do leitor. Por exemplo, se o processo do gravador tiver o PID 123 e tiver o canal aberto no descritor de arquivo 4, no Linux, você pode usar

strace -p123 -e write=4
    
por 19.04.2015 / 00:18

Tags