Quando o gato termina de ler um pipe?

5

Dado o seguinte código, por que o cat só imprime o conteúdo do pipe depois que eu digitei \n ou CTRL + D ? Quais são as condições para que o gato realmente imprima o que lê?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void){
    int pid,p[2];
    char ch;
    pipe(p);
    if((pid=fork()) == -1){
        fprintf(stderr,"Error:can't create a child!\n");
        exit(2);
    }
    if(pid){
        close(p[0]);
        while((ch=getchar())!=EOF){
            write(p[1],&ch,1);
        }
        close(p[1]);
        wait(0);
    }else{
        close(p[1]);
        close(0);
        dup(p[0]);
        close(p[0]);
        execlp("cat","cat",NULL);
    }
    return 0;
}
    
por Mmc Dispenser 08.05.2015 / 00:03

2 respostas

5

Isso não tem nada a ver com cat , pipes ou buffering. Seu "problema" é upstreams, no dispositivo terminal.

Se cada caractere digitado no teclado no terminal estivesse disponível para leitura pelo seu aplicativo imediatamente e cat , você poderia entrar a Backspace b Retornar , seu aplicativo leu a , em seguida, ^? , em seguida, b , em seguida, ^M , que não é o que você quer e não é o que você obtém. >

O que você quer e é para ler a^J .

Você obtém isso porque no modo canônico padrão, o driver de dispositivo do terminal tty line discipline ) implementa um editor de linhas que permite inserir texto e editá-lo (com recursos limitados), e o texto digitado está disponível apenas para leitura quando você pressiona Retornar .

Para evitar isso, você pode dizer ao dispositivo terminal para sair do modo canônico . Por exemplo, fazendo stty raw , você verá seu aplicativo e cat obterá os caracteres imediatamente, mas provavelmente o comportamento não é o esperado.

Você também notará que, para outros tipos de entrada, como um canal, os caracteres são emitidos assim que chegam, como em:

(printf x; sleep 1; echo y) | that-command
    
por 08.05.2015 / 10:23
-2

siga este ciclo:

while((ch=getchar())!=EOF)
{
        write(p[1],&ch,1);
}

com:

char carriageReturn = 0x0D;
write( p[1], &carriageReturn, 1 );
    
por 08.05.2015 / 02:10

Tags