paulo1205 
		 
		(usa Ubuntu)
		 
		Enviado em 09/11/2016 - 12:05h 
		O comportamento normal -- pelo menos no UNIX -- quando você manda ler de um 
pipe  é que a operação de leitura fique bloqueada enquanto não chegarem todos os 
bytes  solicitados.  Por exemplo, se eu mando ler mil 
bytes , mas o remetente só envia novecentos e noventa e nove, a operação de leitura vai ficar parada esperando pelo 
byte  que falta para completar os mil.
No seu caso, você manda ler de 
byte  em 
byte , mas faz essa operação em 
loop .  Desse modo, se o remetente enviar um total de cem bytes, as cem primeiras iterações do loop de leitura vão completar imediatamente, mas a centésima primeira vai parar, esperando por mais um 
byte , mesmo que ele nunca seja enviado pelo transmissor.
A única forma de forçar o sincronismo de um 
pipe  através do próprio 
pipe  é fechar a ponta de envio de dados.  Nesse caso, o sistema operacional responde aos eventos de leitura no 
pipe  com uma quantidade de 
bytes  menor do que a solicitada.  Uma leitura de tamanho zero implica que a comunicação chegou ao final.
Para contornar o bloqueio em operações de leitura há diversos meios.  Dentre eles, lembro agora dos seguintes:
- Usar 
select () ou 
poll () para examinar o descritor de leitura, a fim de ver se há bytes disponíveis para leitura antes de disparar a operação de leitura propriamente dita.  Ao usar essas funções, você pode inclusive optar por usar um intervalo máximo de espera (
timeout ) para que cheguem dados pelo canal de comunicação.
- Marcar o descritor de leitura como não-blocante, através de uma chamada a 
fcntl ().  Nesse caso, chamadas a 
read () num 
pipe  em que a ponta de leitura ainda estiver aberta podem retornar com uma contagem de 
bytes  menor do que a solicitada.  No caso de não haver dados disponíveis no momento, o valor de retorno será 
-1 , e 
errno  terá o valor 
EAGAIN  (ou 
EWOULDBLOCK ; dependendo da implementação, os dois nomes podem inclusive ser equivalentes).  O fechamento da ponta de escrita continuará sendo indicado por um valor de retorno zero para 
read ().
- Usar alarmes assíncronos ou 
timers  cercando a operação de leitura, de modo que, se ela demorar mais do que o tempo programado, ela seja interrompida.  Nesse caso, se 
read () já tiver recebido alguns 
bytes , ela pode retornar com uma contagem menor do que a solicitada.  Se nenhum 
byte  tiver ainda sido lido, ela o valor de retorno é 
-1 , e o código de erro em 
errno  é 
EINTR .
Em conjunto com todos os casos acima, mas que também pode servir como quarta alternativa, você deve criar um protocolo de comunicação que lhe possibilite diminuir o esforço com operações de entrada e saída, bem como facilitar a identificação de possíveis pontos favoráveis a uma pausa na leitura.
Por exemplo, se você estabelecer que suas mensagens são orientadas a linha, você poderia se beneficiar das funções da biblioteca de E/S que já fazem operações orientadas a linha, e pode examinar cada linha lida a fim de ver se elas indicar que é o momento de parar de ler.  O código abaixo dá uma ideia aproximada disso (não testei o código, mas ele pode ter algumas 
race conditions , particularmente ).
    int read_errno; 
unsigned n_lines=0; 
char line[1000]; 
size_t line_len; 
char *rc; 
FILE *pipe_in; 
 
pipe_in=fdopen(pipe_fd[0], "r"); 
setvbuf(pipe_in, NULL, _IOLBF, 0);  // OPCIONAL: pode melhorar (ou piorar -- não testei) num protocolo orientado a linhas. 
while(1){ 
  alarm(5);  // Define um timeout de 5 segundos. 
  errno=0; 
  rc=fgets(line, sizeof line, pipe_in); 
  read_errno=errno;  // Salvo errno porque a próxima operação pode interferir com ele. 
  alarm(0);  // Desliga alarme após fim da operação de leitura. 
  if(rc==NULL){ 
    if(read_errno==EINTR) 
      continue;  // Timeout sem dados: repete o loop esperando a chegada de dados. 
    if(!feof(pipe_in))  // Testa se chegou ao fim de dados (fechamento da ponta de escrita do pipe). 
      fprintf(stderr, "Erro de leitura ao ler a %dª linha: %s.\n", n_lines+1, strerror(read_errno)); 
    break; 
  } 
  line_len=strlen(line); 
  if(line[line_len-1]!='\n'){ 
    // Linha incompleta: pode ser longa demais, ou pode ser que faltem dados no pipe. 
    if(line_len+1==sizeof line){ 
      // Dados não cabem na linha.  Dá o tratamento que você definir. 
    } 
    else{ 
      // Timeout durante a leitura da linha.  Você pode querer 
      // continuar lendo a partir do ponto em que parou, ou pode 
      // abortar.  Você escolhe. 
    } 
  } 
  else{ 
    // Linha completa.  Pode tomar decisões de protocolo em função do conteúdo recebido. 
    ++n_lines; 
    line[line_len-1]='\0'; 
    if(strcmp(line, "abort")==0){ 
      fclose(pipe_in); 
      break; 
    } 
    else if(strncmp(line, "echo ", 5)==0){ 
      puts(line+5); 
    } 
    else{ 
      fprintf(stderr, "Comando inválido \"%s\" na linha %u.\n", line, n_lines); 
    } 
  } 
}