Enviado em 09/11/2016 - 09:23h
Olá pessoal !/* **------------------------------------------------------------------- ** ** PIPE TEST: ** ** ARQUIVO: ** pipe.c ** ** COMPILE: ** gcc pipe.c -o pipe -Wall ** **------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <io.h> #include <fcntl.h> char string[1024], buf[10]; int stdout_saved, i; int mypipe[2]; int main() { stdout_saved = dup (STDOUT_FILENO); // salva #ifdef __linux__ if (pipe(mypipe)) { #endif #ifdef _WIN32 if (_pipe (mypipe, 1024, O_TEXT)) { #endif printf ("pipe nao funfa ...\n"); return 0; } dup2 (mypipe[1], STDOUT_FILENO); // redireciona para stdout close (mypipe[1]); printf("PRIMEIRA LINHA\n"); printf("Segunda LInha\n"); printf("TERCEIRA CASA\n"); printf("CONTINUANDO FINALIZANDO testando\n"); printf("ULTIMA LINHA\n"); fflush (stdout); //------------------------------------------- // FICA PRESO AQUI NO LOOP ... //------------------------------------------- // Como copiar para o string sem "terminar o pipe" ??? //------------------------------------------- // i = 0; while (read(mypipe[0], buf, 1)) { string[i++] = buf[0]; } string[i] = 0; //------------------------------------------- dup2 (stdout_saved, STDOUT_FILENO); // normaliza ( stdout ) para testar /* //------------------------------------------------------------ // se colocar aqui funciona normal ... nao fica presso no loop //------------------------------------------------------------ // i = 0; while (read(mypipe[0], buf, 1)) { string[i++] = buf[0]; } string[i] = 0; */ printf("STRING(%s)\n", string); return 0; }
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.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); } } }
Resolver problemas de Internet
Como compartilhar a tela do Ubuntu com uma Smart TV (LG, Samsung, etc.)
Descritores de Arquivos e Swappiness
Como instalar no Linux Jogos da Steam só para Windows
Instalando o Team Viewer no Debian Trixie - problema no Policykit
O Que Fazer Após Instalar Ubuntu 25.04