Compartilhar via


_pipe

Cria um pipe para leitura e gravação.

Importante

Não é possível usar essa API em aplicativos executados no Tempo de Execução do Windows.Para obter mais informações, consulte Funções CRT sem suporte pelo /ZW.

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

Parâmetros

  • pfds[2]
    Matriz para armazenar descritores de arquivos de leitura e gravação.

  • psize
    Quantidade de memória para a reserva.

  • textmode
    Modo de arquivo.

Valor de retorno

Retorna 0 se tiver êxito. Retorna – 1 para indicar um erro. No erro, errno é definido para um desses valores:

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

  • ENFILE, que indica um estouro na tabela de arquivos do sistema.

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

Para obter mais informações sobre esses e outros códigos de retorno, consulte 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 transmitir informações a outros programas. Um pipe é semelhante a um arquivo porque tem um ponteiro de arquivo, um descritor de arquivo, ou ambos, e pode ler ou gravar usando as funções de entrada e saída da biblioteca padrão. No entanto, um pipe não representa um arquivo ou um dispositivo específico. Em vez disso, representa o armazenamento temporário na memória que é independente da memória própria do programa e é inteiramente controlado 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 aquele que não precisa. Por exemplo, o processador de comando no Windows cria um pipe quando executa um comando como PROGRAM1 | PROGRAM2.

O descritor de saída padrão de PROGRAM1 é anexado ao descritor de gravação do pipe. O descritor de entrada padrão de PROGRAM2 é anexado ao descritor de leitura do pipe. Isso elimina a necessidade de criar arquivos temporários para passar informações a 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. Os descritores de arquivo de pipe são usados da mesma maneira que os outros descritores de arquivo. (As funções de entrada e de saída de nível baixo _read e _write podem ser lidas e gravadas em um pipe.) Para detectar a condição de fim de pipe, verifique 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 tradução para o pipe. A constante de manifesto _O_TEXT especifica uma tradução de texto e a constante _O_BINARY especifica uma tradução binária. (Consulte fopen, _wfopen para obter uma descrição dos modos de texto e binário.) Se o argumento de textmode for 0, _pipe usará o modo padrão de conversão que é especificado pela variável _fmode de modo padrão.

Em programas com 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é depois de a chamada de _pipe ser concluída.

Para usar a função _pipe para se comunicar entre um processo pai e um processo filho, cada processo deve ter apenas um descritor aberto no pipe. Os descritores devem ser opostos: se o pai tiver um descritor de leitura aberto, então, o filho deverá ter um descritor de gravação aberto. A maneira mais fácil de fazer isso é OR ( |) o sinalizador de _O_NOINHERIT 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 reproduza o processo filho. O retorno de chamada de ova, feche o descritor duplicado no processo pai. Para obter mais informações, consulte o exemplo 2 posteriormente neste artigo.

No sistema operacional Windows, um pipe é destruído quando todos os seus descritores são fechados. (Se todos os descritores de leitura no pipe forem fechados, a gravação 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 suficiente de buffer para concluir a solicitação de E/S.

Requisitos

Rotina

Cabeçalho necessário

Cabeçalho opcional

_pipe

<io.h>

<fcntl.h>,1 <errno.h>2

1 Para _O_BINARY e definições de _O_TEXT.

2 definições de errno.

Para obter mais informações de 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 ) );

      }
   }
}

Saída de Exemplo

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

Esse é um aplicativo de filtro básico. Reproduz o crt_pipe_beeper de aplicativo depois de criar um pipe que direciona o stdout de aplicativo reproduzido ao filtro. O filtro remove os caracteres ASCII 7 (aviso sonoro).

// 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;
}

Saída

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...

Equivalência do .NET Framework

Não aplicável. Para chamar a função padrão de C, use PInvoke. Para obter mais informações, consulte Exemplos de invocação de plataforma.

Consulte também

Referência

Processo e controle de ambiente

_open, _wopen