Windows Anonymous Pipe

Windows anonymous pipes are actually Ordinary pipes, and they behave similarly to their UNIX counterparts: they are unidirectional and employ parent-child relationships between the communicating processes. In addition, reading and writing to the pipe can be accomplished with the ordinary ReadFile() and WriteFile() functions. The Windows API use CreatePipe() function for creating pipes, which is passed four parameters. The parameters provide separate handles for
reading and
reading and
writing to the pipe
writing to the pipe
An instance of the STARTUPINFO structure, used to specify that the child process is to inherit the handles of the pipe.
An instance of the STARTUPINFO structure, used to specify that the child process is to inherit the handles of the pipe.
the size (in Bytes) of the pipe may be specified.
the size (in Bytes) of the pipe may be specified.
Windows requires the programmer to specify which attributes the child process will inherit, Unlike UNIX systems. This is accomplished by first initializing the SECURITY ATTRIBUTES structure allowing handles to be inherited and then redirecting the child process’s handles for standard input or standard output to the read or write handle of the pipe. As the child will be reading from the pipe, the parent must redirect the child’s standard input to the read handle of the pipe. As the pipes are half duplex, it is required to prohibit the child from inheriting the write-end of the pipe.
In the below code, we can see a parent process creating an anonymous pipe for communicating with its child −
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define BUFFER SIZE 25
int main(VOID) {
   HANDLE ReadHandle, WriteHandle;
   STARTUPINFO si;
   PROCESS INFORMATION pi;
   char message[BUFFER SIZE] = "Greetings";
   DWORD written;
   /* set up security attributes to allow pipes to be inherited */
   SECURITY ATTRIBUTES sa = {sizeof(SECURITY ATTRIBUTES), NULL, TRUE};
   /* allocate memory */
   ZeroMemory(π, sizeof(pi));
   /* create the pipe */
   if (!CreatePipe(&ReadHandle, &WriteHandle, &sa, 0)) {
   fprintf(stderr, "Create Pipe Failed"); return 1; }
   /* establishing the START INFO structure for the child process*/
   GetStartupInfo(&si);
   si.hStdOutput = GetStdHandle(STD OUTPUT HANDLE);
   /* redirecting standard input to the read end of the pipe */
   si.hStdInput = ReadHandle;
   si.dwFlags = STARTF USESTDHANDLES;
   /* don’t allow the child inheriting the write end of pipe */
   SetHandleInformation(WriteHandle, HANDLE FLAG INHERIT, 0);
   /* create the child process */
   CreateProcess(NULL, "child.exe", NULL, NULL, TRUE, /* inherit handles */ 0, NULL, NULL, &si, π);
   /* close the unused end of the pipe */ CloseHandle(ReadHandle);
   /* the parent writes to the pipe */
   if(!WriteFile(WriteHandle, message, BUFFER SIZE, &written, NULL))
   fprintf(stderr, "Error writing to pipe.");
   /* close the write end of the pipe */ CloseHandle(WriteHandle);
   /* wait for the child to exit */ WaitForSingleObject(pi.hProcess,INFINITE);        
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
   return 0;
}
The parent first closes its unused read end of the pipe, before writing to the pipe. The child process which reads from the pipe is shown in below code −
#include<stdio.h>
#include<windows.h>
#define BUFFER SIZE 25
int main(VOID){
   HANDLE Readhandle;
   CHAR buffer[BUFFER SIZE];
   DWORD read;
   /* getting the read handle of the pipe */
   ReadHandle = GetStdHandle(STD INPUT HANDLE);
   /* the child reads from the pipe */
   if (ReadFile(ReadHandle, buffer, BUFFER SIZE, &read, NULL))
      printf("child read %s", buffer);
   else
      fprintf(stderr, "Error reading from pipe");
   return 0;
}
Windows anonymous pipe - child process