This example is based on the example in the Microsoft documentation for the _pipe() run-time library function. It was brought to my attention by Valerie Puffet-Michel. I took the example and made it a bit more robust, partly to catch the Borland C++ bug described below.
Essentially, this example works on the Win32 rule that a child process can inherit the file handles that the parent opened. The program passes the file handle IDs on the command line to the child that it spawns. Since file handles and socket descriptors are the same thing in Win32, this works just as well for sockets as it does for the pipe handles used in the example. Note that you cannot pass file handles to arbitrary processes. They have to somehow inherit those handles, which implies that the process that created the handles has to have some sort of parental relationship to the process that wants to use those handles.
This example will not work under Borland C++ 5.0 because of a run-time library bug, documented in bug report 43101. The report does not give any workarounds for this problem, so you may be out of luck if you're trying to do this with Borland C++. Still, it will compile now. B-)
// Borland C++ 5.0: bcc32 fdpass.cpp // Visual C++ 5.0: cl fdpass.cpp #include <stdlib.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <process.h> #include <math.h> enum PIPES { READ = 0, WRITE = 1 }; #define NUMPROBLEM 8 #ifdef _MSC_VER #define CWAIT _cwait #else #define CWAIT cwait #endif void main(int argc, char *argv[]) { int hpipe[2]; char hstr[20]; int pid, problem, c; int termstat; if (argc == 1) { //// No arguments, so this must be the parent process // Open a set of pipes if (_pipe(hpipe, 256, O_BINARY) == -1) { perror("pipe failed"); exit(1); } // Convert read side of pipe to string and pass as an argument // to the child process. itoa(hpipe[READ], hstr, 10); if ((pid = spawnl(P_NOWAIT, argv[0], argv[0], hstr, NULL)) == -1) { perror("Spawn failed"); } // Put problem in write pipe; it will appear in child's read pipe. for (problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000) { if (write(hpipe[WRITE], (char*)&problem, sizeof(int)) == -1) { perror("parent write failed"); } else { printf("Son, what is the square root of %d?\n", problem); } } // Wait until spawned program is done processing. CWAIT(&termstat, pid, WAIT_CHILD); if (termstat & 0x0) { perror("Child failed"); } close(hpipe[READ]); close(hpipe[WRITE]); } else { //// There is a command line argument, so we must be a child process // Convert argument to integer handle value. hpipe[READ] = atoi(argv[1]); // Read problem from pipe and calculate solution. for (c = 0; c < NUMPROBLEM; c++) { if (read(hpipe[READ], (char*)&problem, sizeof(int)) == -1) { perror("child read failed"); } else { printf("Dad, the square root of %d is %3.2f.\n", problem, sqrt((double)problem)); } } } }
Back to the Advanced Issues page...
Back to the Examples page...
![]() |
Go to my home page |
![]() |
Go to my Important RFC Lists page |
![]() |
Go to the main Programming Resources page |
Please send updates and corrections to <tangent@cyberport.com>.