当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1],其中fd[0]固定用于读管道,fd[1]固定用于写管道
匿名管道只能用于父子进程或者兄弟进程之间,数据只能从一端流向另一端
BOOL WINAPI CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_LPSECURITY_ATTRIBUTES IpPipeAttributets,
_In_ DWORD nSize
);
父进程读取一个文件内容,通过管道传给子进程,子进程再把内容从另外一个管道传给父进程。
父进程
#include<stdio.h>
#include<Windows.h>
#define BUFSIZE 4096
HANDLE hChildStdinRd,
hChildStdinWr,
hChildStdoutRd,
hChildStdoutWr,
hInputFile,
hStdout;
BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
int main(int argc, TCHAR* argv[]) {
SECURITY_ATTRIBUTES Attr;
BOOL Success;
Attr.nLength = sizeof(SECURITY_ATTRIBUTES);
Attr.bInheritHandle = TRUE;
Attr.lpSecurityDescriptor = NULL;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &Attr, 0)) {
printf("FALSE\n");
return 0;
}
SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0);
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &Attr, 0)) {
printf("FALSE\n");
return 0;
}//得到两个管道
SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0);
Success = CreateChildProcess();
if (!Success) {
printf("FALSE to create child\n");
return 0;
}
if (argc == 1) {
printf("input a file\n");
return 0;
}
printf("\nContents of :%s\n", argv[1]);
hInputFile = CreateFileW(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if(hInputFile == INVALID_HANDLE_VALUE) {
printf("create fail");
return 0;
}
WriteToPipe();
ReadFromPipe();
return 0;
}
VOID WriteToPipe(VOID) {
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
for (;;) {
if (!ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0) {
break;
}
if (!WriteFile(hChildStdinWr, chBuf, dwRead, &dwWritten, NULL)) {
break;
}
}
if (!CloseHandle(hChildStdinWr)) {
printf("Close Error");
}
}
VOID ReadFromPipe(VOID) {
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
if (!CloseHandle(hChildStdoutWr)) {
printf("Closing Error");
}
for (;;) {
if (!ReadFile(hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) || dwRead == 0) {//从子进程读取数据
break;
}
if (!WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL)) {
break;
}
}
}
BOOL CreateChildProcess() {
TCHAR Cmdline[] = TEXT("child.exe");//child.exe
PROCESS_INFORMATION ProcInfo;
STARTUPINFO StartInfo;
BOOL FuncRetn = FALSE;
ZeroMemory(&ProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&StartInfo, sizeof(STARTUPINFO));
StartInfo.cb = sizeof(STARTUPINFO);
StartInfo.hStdError = hChildStdoutWr;
StartInfo.hStdOutput = hChildStdoutWr;
StartInfo.hStdInput = hChildStdinRd;
StartInfo.dwFlags |= STARTF_USESTDHANDLES;
FuncRetn = CreateProcess(NULL,
Cmdline,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&StartInfo,
&ProcInfo);
if (FuncRetn == 0) {
printf("Create Error");
}
else {
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
return FuncRetn;
}
return TRUE;
}
子进程
#include<Windows.h>
#include<stdio.h>
#define BUFSIZE 4096
VOID main(VOID) {
CHAR chBuf[BUFSIZE];
DWORD dwRead, dwWritten;
HANDLE hChildStdinRd, hChildStdoutWr;
BOOL Success;
hChildStdoutWr = GetStdHandle(STD_OUTPUT_HANDLE);
hChildStdinRd = GetStdHandle(STD_INPUT_HANDLE);
if ((hChildStdinRd == INVALID_HANDLE_VALUE) || (hChildStdoutWr == INVALID_HANDLE_VALUE)) {
ExitProcess(1);
}
for (;;) {
Success = ReadFile(hChildStdinRd, chBuf, BUFSIZE, &dwRead, NULL);
if (!Success || dwRead == 0) {
break;
}
Success = WriteFile(hChildStdoutWr, chBuf, dwRead, &dwWritten, NULL);
if (!Success) {
break;
}
}
}