Condividi tramite


_pipe

Crea un pipe per la lettura e la scrittura.

Importante

Non è possibile usare questa API nelle applicazioni eseguite in Windows Runtime. Per altre informazioni, vedere Funzioni CRT non supportate nelle app della piattaforma UWP (Universal Windows Platform).

Sintassi

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

Parametri

pfds
Puntatore a una matrice di due int per contenere descrittori di file di lettura e scrittura.

psize
Quantità di memoria da riservare.

textmode
Modalità file.

Valore restituito

Restituisce 0 in caso di esito positivo. Restituisce -1 per indicare un errore. In caso di errore, errno viene impostato su uno di questi valori:

  • EMFILE, che indica che non sono disponibili altri descrittori di file.

  • ENFILE, che indica un overflow della tabella dei file di sistema.

  • EINVAL, che indica che la matrice pfds è un puntatore Null o che è stato passato un valore non valido per textmode.

Per altre informazioni su questi e altri codici restituiti, vedere errno, _doserrno, _sys_errliste _sys_nerr.

Osservazioni:

La funzione _pipe crea una pipe, ovvero un canale di I/O artificiale usato da un programma per passare informazioni ad altri programmi. Una pipe è simile a un file, perché ha un puntatore di file, un descrittore di file o entrambi. E può essere letto o scritto in usando le funzioni di input e output della libreria standard. Tuttavia, una pipe non rappresenta un file o un dispositivo specifico. Rappresenta invece uno spazio di archiviazione temporaneo in memoria, indipendente della memoria propria del programma e interamente controllato dal sistema operativo.

_pipe è simile a _open ma apre la pipe per la lettura e la scrittura e restituisce due descrittori di file invece di uno. Il programma può usare entrambi i lati della pipe o chiudere quello non necessario. Ad esempio, il processore dei comandi di Windows crea una pipe quando esegue un comando come PROGRAM1 | PROGRAM2.

Il descrittore di output standard di PROGRAM1 viene collegato al descrittore di scrittura della pipe. Il descrittore di input standard di PROGRAM2 viene collegato al descrittore di lettura della pipe. Questo allegato elimina la necessità di creare file temporanei per passare informazioni ad altri programmi.

La funzione _pipe restituisce due descrittori di file alla pipe nell'argomento pfds. L'elemento pfds[0] contiene il descrittore di lettura e l'elemento pfds[1] contiene il descrittore di scrittura. I descrittori di file della pipe vengono usato nello stesso modo di altri descrittori di file. Le funzioni _read di input e output di basso livello e _write possono leggere e scrivere in una pipe. Per rilevare la condizione di fine pipe, verificare la presenza di una _read richiesta che restituisce 0 come numero di byte letti.

L'argomento psize specifica la quantità di memoria, in byte, da riservare per la pipe. L'argomento textmode specifica la modalità di conversione per la pipe. La costante _O_TEXT manifesto specifica una traduzione testuale ANSI e la costante _O_BINARY specifica la traduzione binaria. Per una descrizione di testo e modalità binarie, vedere fopen. _wfopen Se l'argomento textmode è 0, _pipe usa la modalità di conversione predefinita specificata dalla variabile _fmodein modalità predefinita .

Nei programmi multithreading, non viene eseguito alcun blocco. I descrittori di file restituiti vengono appena aperti e non devono essere referenziati da alcun thread fino al completamento della _pipe chiamata.

Per usare la funzione _pipe per la comunicazione tra un processo padre e un processo figlio, ogni processo deve avere un solo descrittore aperto sulla pipe. I descrittori devono essere opposti: se il padre ha un descrittore di lettura aperto, il figlio deve avere un descrittore di scrittura aperto. È più semplice usare un "or" bit per bit (|) nel _O_NOINHERIT flag con textmode. Usare quindi _dup o _dup2 per creare una copia ereditabile del descrittore della pipe che si vuole passare al processo figlio. Chiudere il descrittore originale e quindi generare il processo figlio. Al completamento della chiamata di generazione, chiudere il descrittore duplicato nel processo padre. Per altre informazioni, vedere l'esempio 2 in questo articolo.

Nel sistema operativo Windows, una pipe viene eliminata quando tutti i relativi descrittori sono stati chiusi. Se tutti i descrittori di lettura sulla pipe sono stati chiusi, la scrittura nella pipe causa un errore. Tutte le operazioni di lettura e scrittura nella pipe attendono fino a quando non sono presenti dati sufficienti o spazio sufficiente per completare la richiesta di I/O.

Per impostazione predefinita, lo stato globale di questa funzione è limitato all'applicazione. Per modificare questo comportamento, vedere Stato globale in CRT.

Requisiti

Ciclo Intestazione obbligatoria Intestazione facoltativa
_pipe <io.h> <fcntl.h>,1 <errno.h>2

1 Per _O_BINARY e _O_TEXT definizioni.

2 errno definizioni.

Per altre informazioni sulla compatibilità, vedere Compatibility (Compatibilità).

Librerie

Tutte le versioni delle librerie di runtime C.

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

Esempio 2

Il codice di esempio è un'applicazione di filtro di base. Genera l'applicazione crt_pipe_beeper dopo la creazione di una pipe che indirizza l'applicazione stdout generato al filtro. Il filtro rimuove i caratteri ASCII 7 (campanello).

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

Applicazione di filtro effettiva:

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

Vedi anche

Processo e controllo dell'ambiente
_open, _wopen