Compartilhar via


_pipe

Cria um pipe para leitura e gravação.

Importante

Esta API não pode ser usada em aplicativos executados no Windows Runtime. Para obter mais informações, confira Funções do CRT sem suporte em aplicativos da Plataforma Universal do Windows.

Sintaxe

int _pipe(
   int *pfds,
   unsigned int psize,
   int textmode
);

Parâmetros

pfds
Ponteiro para uma matriz de dois int para armazenar descritores de arquivo de leitura e gravação.

psize
Quantidade de memória a ser reservada.

textmode
Modo de arquivo.

Valor retornado

Retorna 0 se for bem-sucedido. Retorna -1 para indicar um erro. Em caso de erro, errno é definido como um destes valores:

  • EMFILE, que indica que nenhum outro descritor de arquivo está disponível.

  • ENFILE, que indica um estouro de sistema-arquivo-tabela.

  • EINVAL, que indica que a matriz pfds é um ponteiro nulo ou que um valor inválido para textmode foi passado.

Para obter mais informações sobre esses e outros códigos de retorno, confira errno, _doserrno, _sys_errlist e _sys_nerr.

Comentários

A função _pipe cria um pipe, que é um canal de E/S artificial que um programa usa para passar informações para outros programas. Um pipe se assemelha a um arquivo, porque tem um ponteiro de arquivo, um descritor de arquivo ou ambos. E ele pode ser lido ou gravado usando as funções de entrada e saída da Biblioteca Padrão. No entanto, um pipe não representa um arquivo ou dispositivo específico. Em vez disso, ele representa o armazenamento temporário na memória que é independente da memória do próprio programa e é controlada totalmente pelo sistema operacional.

_pipe é semelhante a _open, mas abre o pipe para leitura e gravação e retorna dois descritores de arquivo em vez de um. O programa pode usar ambos os lados do pipe ou fechar um que não é necessário. Por exemplo, o processador de comando do Windows cria um pipe quando ele executa um comando como PROGRAM1 | PROGRAM2.

O descritor de saída padrão de PROGRAM1 está anexado ao descritor de gravação do pipe. O descritor de entrada padrão de PROGRAM2 está anexado ao descritor de leitura do pipe. Este anexo elimina a necessidade de criar arquivos temporários para passar informações para outros programas.

A função _pipe retorna dois descritores de arquivo para o pipe no argumento pfds. O elemento pfds[0] contém o descritor de leitura e o elemento pfds[1] contém o descritor de gravação. Descritores de arquivo de pipe são usados da mesma maneira que outros descritores de arquivo. (As funções de entrada e saída de baixo nível _read e _write podem ler e gravar em um pipe). Para detectar a condição de fim de pipe, verifique se há uma solicitação _read que retorna 0 como o número de bytes lidos.

O argumento psize especifica a quantidade de memória, em bytes, a ser reservada para o pipe. O argumento textmode especifica o modo de translação para o pipe. A constante _O_TEXT de manifesto especifica uma tradução de texto ANSI e a constante _O_BINARY especifica a tradução binária. (Consulte fopen, _wfopen para obter uma descrição dos modos de texto e binários). Se o argumento textmode for 0, _pipe usará o modo de tradução padrão especificado pela variável de modo padrão _fmode.

Em programas multithread, nenhum bloqueio é executado. Os descritores de arquivo que são retornados foram abertos recentemente e não devem ser referenciados por qualquer thread até que a chamada _pipe seja concluída.

Para usar a função _pipe para a comunicação entre um processo pai e um processo filho, cada processo deve ter apenas um descritor aberto no pipe. Os descritores de deverão ser opostos: se o pai tiver um descritor de leitura aberto, o filho deve ter um descritor de gravação aberto. É mais fácil usar um "ou" (|) bit a bit no _O_NOINHERIT sinalizador com textmode. Em seguida, use _dup ou _dup2 para criar uma cópia herdável do descritor de pipe que você deseja passar para o filho. Feche o descritor original e gere o processo filho. No retorno da chamada de geração, feche o descritor duplicado no processo pai. Para obter mais informações, consulte o exemplo 2 mais adiante neste artigo.

No sistema operacional Windows, um pipe é destruído quando todos os seus descritores foram fechados. (Se todos os descritores de leitura no pipe foram fechados, gravar no pipe causará um erro). Todas as operações de leitura e gravação no pipe esperam até que haja dados suficientes ou espaço em buffer suficiente para realizar a solicitação de E/S.

Por padrão, o estado global dessa função tem como escopo o aplicativo. Para alterar esse comportamento, confira Estado global no CRT.

Requisitos

Rotina Cabeçalho necessário Cabeçalho opcional
_pipe <io.h> <fcntl.h>,1 <errno.h>2

1 Para definições de _O_BINARY e _O_TEXT.

errno 2 definições.

Para obter informações sobre compatibilidade, consulte Compatibilidade.

Bibliotecas

Todas as versões das bibliotecas em tempo de execução C.

Exemplo 1

// crt_pipe.c
/* This program uses the _pipe function to pass streams of
* text to spawned processes.
*/

#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <process.h>
#include <math.h>

enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
#define NUMPROBLEM 8

int main( int argc, char *argv[] )
{
   int fdpipe[2];
   char hstr[20];
   int pid, problem, c;
   int termstat;

   /* If no arguments, this is the spawning process */
   if( argc == 1 )
   {

      setvbuf( stdout, NULL, _IONBF, 0 );

      /* Open a set of pipes */
      if( _pipe( fdpipe, 256, O_BINARY ) == -1 )
          exit( 1 );

      /* Convert pipe read descriptor to string and pass as argument
       * to spawned program. Program spawns itself (argv[0]).
       */
      _itoa_s( fdpipe[READ], hstr, sizeof(hstr), 10 );
      if( ( pid = _spawnl( P_NOWAIT, argv[0], argv[0],
            hstr, NULL ) ) == -1 )
          printf( "Spawn failed" );

      /* Put problem in write pipe. Since spawned program is
       * running simultaneously, first solutions may be done
       * before last problem is given.
       */
      for( problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000)
      {

         printf( "Son, what is the square root of %d?\n", problem );
         _write( fdpipe[WRITE], (char *)&problem, sizeof( int ) );

      }

      /* Wait until spawned program is done processing. */
      _cwait( &termstat, pid, WAIT_CHILD );
      if( termstat & 0x0 )
         printf( "Child failed\n" );

      _close( fdpipe[READ] );
      _close( fdpipe[WRITE] );

   }

   /* If there is an argument, this must be the spawned process. */
   else
   {

      /* Convert passed string descriptor to integer descriptor. */
      fdpipe[READ] = atoi( argv[1] );

      /* Read problem from pipe and calculate solution. */
      for( c = 0; c < NUMPROBLEM; c++ )
      {

        _read( fdpipe[READ], (char *)&problem, sizeof( int ) );
        printf( "Dad, the square root of %d is %3.2f.\n",
                 problem, sqrt( ( double )problem ) );

      }
   }
}
Son, what is the square root of 1000?
Son, what is the square root of 2000?
Son, what iDad, the square root of 1000 is 31.62.
Dad, the square root of 2000 is 44.72.
s the square root of 3000?
Dad, the square root of 3000 is 54.77.
Son, what is the square root of 4000?
Dad, the square root of 4000 is 63.25.
Son, what is the square root of 5000?
Dad, the square root of 5000 is 70.71.
Son, what is the square root of 6000?
SonDad, the square root of 6000 is 77.46.
, what is the square root of 7000?
Dad, the square root of 7000 is 83.67.
Son, what is the square root of 8000?
Dad, the square root of 8000 is 89.44.

Exemplo 2

O código de exemplo é um aplicativo de filtro básico. Ele gera o aplicativo crt_pipe_beeper depois de criar um pipe que direciona o stdout do aplicativo gerado para o filtro. O filtro remove caracteres ASCII 7 (bipe).

// crt_pipe_beeper.c

#include <stdio.h>
#include <string.h>

int main()
{
   int   i;
   for(i=0;i<10;++i)
      {
         printf("This is speaker beep number %d...\n\7", i+1);
      }
   return 0;
}

O aplicativo de filtro real:

// crt_pipe_BeepFilter.C
// arguments: crt_pipe_beeper.exe

#include <windows.h>
#include <process.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

#define   OUT_BUFF_SIZE 512
#define   READ_FD 0
#define   WRITE_FD 1
#define   BEEP_CHAR 7

char szBuffer[OUT_BUFF_SIZE];

int Filter(char* szBuff, ULONG nSize, int nChar)
{
   char* szPos = szBuff + nSize -1;
   char* szEnd = szPos;
   int nRet = nSize;

   while (szPos > szBuff)
   {
      if (*szPos == nChar)
         {
            memmove(szPos, szPos+1, szEnd - szPos);
            --nRet;
         }
      --szPos;
   }
   return nRet;
}

int main(int argc, char** argv)
{
   int nExitCode = STILL_ACTIVE;
   if (argc >= 2)
   {
      HANDLE hProcess;
      int fdStdOut;
      int fdStdOutPipe[2];

      // Create the pipe
      if(_pipe(fdStdOutPipe, 512, O_NOINHERIT) == -1)
         return   1;

      // Duplicate stdout file descriptor (next line will close original)
      fdStdOut = _dup(_fileno(stdout));

      // Duplicate write end of pipe to stdout file descriptor
      if(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)) != 0)
         return   2;

      // Close original write end of pipe
      _close(fdStdOutPipe[WRITE_FD]);

      // Spawn process
      hProcess = (HANDLE)_spawnvp(P_NOWAIT, argv[1],
       (const char* const*)&argv[1]);

      // Duplicate copy of original stdout back into stdout
      if(_dup2(fdStdOut, _fileno(stdout)) != 0)
         return   3;

      // Close duplicate copy of original stdout
      _close(fdStdOut);

      if(hProcess)
      {
         int nOutRead;
         while   (nExitCode == STILL_ACTIVE)
         {
            nOutRead = _read(fdStdOutPipe[READ_FD],
             szBuffer, OUT_BUFF_SIZE);
            if(nOutRead)
            {
               nOutRead = Filter(szBuffer, nOutRead, BEEP_CHAR);
               fwrite(szBuffer, 1, nOutRead, stdout);
            }

            if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode))
               return 4;
         }
      }
   }
   return nExitCode;
}
This is speaker beep number 1...
This is speaker beep number 2...
This is speaker beep number 3...
This is speaker beep number 4...
This is speaker beep number 5...
This is speaker beep number 6...
This is speaker beep number 7...
This is speaker beep number 8...
This is speaker beep number 9...
This is speaker beep number 10...

Confira também

Controle de processo e ambiente
_open, _wopen