_pipe
読み取りおよび書き込み用のパイプを作成します。
重要
この API は、Windows ランタイムで実行するアプリケーションでは使用できません。 詳細については、「ユニバーサル Windows プラットフォーム アプリでサポートされていない CRT 関数」を参照してください。
構文
int _pipe(
int *pfds,
unsigned int psize,
int textmode
);
パラメーター
pfds
読み取りおよび書き込みファイル記述子を保持する 2 つの int
の配列へのポインター。
psize
予約するメモリの量。
textmode
ファイル モード。
戻り値
処理が正常に終了した場合は 0 を返します。 エラーを示す –1 を返します。 エラーの場合、errno
は、これらの値のいずれかに設定されます。
EMFILE
、これ以上のファイル記述子が使用できないことを示します。ENFILE
、ファイル システム テーブルのオーバーフローを示します。EINVAL
、配列pfds
が null ポインターであるか、またはtextmode
に対して無効な値が渡されたことを示します。
これらのリターン コードとその他のリターン コードについては、「errno
、_doserrno
、_sys_errlist
、_sys_nerr
」を参照してください。
解説
_pipe
関数は、プログラムの他のプログラムに情報を渡すために使用する人為的な I/O チャネルであるパイプを作成します。 パイプにはファイル ポインター、ファイル記述子、またはその両方があるため、ファイルに似ています。 また、標準ライブラリの入出力関数を使用して、読み取りまたは書き込みを行うことができます。 ただし、パイプは、特定のファイルまたはデバイスを表しません。 代わりに、プログラム自体のメモリに関係なく、オペレーティング システムによって完全に制御されるメモリの一時的なストレージを表します。
_pipe
は _open
に似ていますが、読み取りおよび書き込み用のパイプを開き、ファイル記述子を 1 つではなく 2 つ返します。 プログラムはパイプの両側を使用するか、または必要としない一方の側のパイプを閉じることができます。 たとえば、Windows のコマンド プロセッサは PROGRAM1 | PROGRAM2
などのコマンドを実行するときにパイプを作成します。
PROGRAM1
の標準出力記述子は、パイプの書き込み記述子に添付されます。 PROGRAM2
の標準入力記述子は、パイプの読み取り記述子に添付されます。 この添付ファイルを使用すると、他のプログラムに情報を渡すために一時ファイルを作成する必要がなくなります。
_pipe
関数は pfds
引数でパイプに 2 つのファイル記述子を返します。 要素 pfds
[0] には、読み取り記述子が含まれ、要素 pfds
[1] には書き込み記述子が含まれます。 パイプのファイル記述子は、他のファイル記述子と同様に使用されます。 (低レベルの入出力関数 _read
および _write
は、パイプとの間で読み取りと書き込みを行うことができます。パイプの終了条件を検出するには、読み取ったバイト数として 0 を返す _read
要求を確認します。
psize
引数は、パイプに予約するメモリの量をバイト数で指定します。 textmode
引数は、パイプの変換モードを指定します。 マニフェスト定数 _O_TEXT
は ANSI テキスト変換を指定し、定数 _O_BINARY
はバイナリ変換を指定します。 (テキスト モードとバイナリ モードの説明については、「 fopen
、 _wfopen
」を参照してください)。 textmode
引数が 0 の場合、 _pipe
は、既定のモード変数 _fmode
で指定された既定の変換モードを使用します。
マルチスレッド プログラムでは、ロックは実行されません。 返されたファイル記述子が新しく開き、_pipe
呼び出しが完了するまでスレッドでは参照できません。
_pipe
の関数を使用して親プロセスと子プロセスの間で通信するには、各プロセスがパイプで開いている記述子を 1 つだけ持つことが必要です。 記述子は正反対である必要があります。親が開いている読み取り記述子を持つ場合、子は開いている書き込み記述子を持つ必要があります。 textmode
で_O_NOINHERIT
フラグでビットごとの "or" (|
) を使用するのが最も簡単です。 次に、_dup
または _dup2
を使用して、子に渡すパイプ記述子の継承可能なコピーを作成します。 元の記述子を終了し、子プロセスを生成します。 生成の呼び出しから制御が戻ったら、親プロセスの重複記述子を閉じます。 詳細については、この記事で後述する例 2 を参照してください。
Windows オペレーティング システムでは、すべての記述子が閉じたときパイプは破棄されます。 (パイプ上のすべての読み取り記述子が閉じられている場合、パイプに書き込むとエラーが発生します)。パイプに対するすべての読み取りおよび書き込み操作は、I/O 要求を完了するのに十分なデータまたは十分なバッファー領域が存在するまで待機します。
既定では、この関数のグローバル状態の適用対象は、アプリケーションになります。 この動作を変更するには、「CRT でのグローバル状態」を参照してください。
要件
ルーチンによって返される値 | 必須ヘッダー | オプション ヘッダー |
---|---|---|
_pipe |
<io.h> |
<fcntl.h> ,1 <errno.h> 2 |
1 は _O_BINARY
定義と _O_TEXT
定義向け。
2 errno
定義。
互換性の詳細については、「 Compatibility」を参照してください。
ライブラリ
C ランタイム ライブラリのすべてのバージョン。
例 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.
例 2
サンプル コードは、基本的なフィルター アプリケーションです。 これは、生成されたアプリケーションの stdout
をフィルターに指定するパイプを作成した後、アプリケーションの crt_pipe_beeper
を生成します。 フィルターは ASCII 7 (ビープ音) 文字を削除します。
// 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;
}
実際のフィルター アプリケーション:
// 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...