home *** CD-ROM | disk | FTP | other *** search
- //
- // Copyright (c) 2000
- // Pasquale J. Villani
- // All Rights reserved
- //
- // This is our parent process. It reads data from standard input,
- // flips characters in the buffer from upper case to lower case and vice versa,
- // then write the buffer out.
- //
-
- #include <windows.h>
-
- #define BUFSIZE 4096
-
- #ifndef SUCCESS
- # define SUCCESS 0
- #endif
- #ifndef FAILURE
- # define FAILURE 1
- #endif
-
- HANDLE hChildStdinRd,
- hChildStdinWr,
- hChildStdinWrDup,
- hChildStdoutRd,
- hChildStdoutWr,
- hChildStdoutRdDup,
- hInputFile,
- hSaveStdin,
- hSaveStdout;
-
- BOOL SpawnChildProcess(CHAR *szChildName);
- VOID WriteToPipe(VOID);
- VOID ReadFromPipe(VOID);
- VOID ErrorExit(LPTSTR);
- VOID ErrMsg(LPTSTR, BOOL);
-
- int main(int argc, char *argv[])
- {
- SECURITY_ATTRIBUTES saAttr;
- BOOL fSuccess;
-
- // First, create the child process.
- if (!SpawnChildProcess("reverse"))
- ErrorExit("Create process failed");
-
- // Get a handle to the parent's input file.
- if (argc > 1)
- hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
- else
- hInputFile = hSaveStdin;
-
- if (hInputFile == INVALID_HANDLE_VALUE)
- ErrorExit("no input file\n");
-
- // Write to pipe that is the standard input for a child process.
- WriteToPipe();
-
- // Read from pipe that is the standard output for child process.
- ReadFromPipe();
-
- return 0;
- }
-
-
- BOOL SpawnChildProcess(CHAR *szChildName)
- {
- PROCESS_INFORMATION piProcInfo;
- STARTUPINFO siStartInfo;
- BOOL bRetVal;
- SECURITY_ATTRIBUTES saAttr;
- BOOL fSuccess;
-
- // Set the bInheritHandle flag so pipe handles are inherited.
- saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
- saAttr.bInheritHandle = TRUE;
- saAttr.lpSecurityDescriptor = NULL;
-
- // The steps for redirecting child process's STDOUT:
- // 1. Save current STDOUT, to be restored later.
- // 2. Create anonymous pipe to be STDOUT for child process.
- // 3. Set STDOUT of the parent process to be write handle of
- // the pipe, so it is inherited by the child process.
- // 4. Create a noninheritable duplicate of the read handle and
- // close the inheritable read handle.
- // Save the handle to the current STDOUT.
- hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
-
- // Create a pipe for the child process's STDOUT.
- if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
- ErrorExit("Stdout pipe creation failed\n");
-
- // Set a write handle to the pipe to be STDOUT.
- if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
- ErrorExit("Redirecting STDOUT failed");
-
- // Create noninheritable read handle and close the inheritable read // handle.
- fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
- GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE,
- DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- ErrorExit("DuplicateHandle failed");
-
- CloseHandle(hChildStdoutRd);
-
- // The steps for redirecting child process's STDIN:
- // 1. Save current STDIN, to be restored later.
- // 2. Create anonymous pipe to be STDIN for child process.
- // 3. Set STDIN of the parent to be the read handle of the
- // pipe, so it is inherited by the child process.
- // 4. Create a noninheritable duplicate of the write handle,
- // and close the inheritable write handle.
- // Save the handle to the current STDIN.
- hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
-
- // Create a pipe for the child process's STDIN.
- if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
- ErrorExit("Stdin pipe creation failed\n");
-
- // Set a read handle to the pipe to be STDIN.
- if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
- ErrorExit("Redirecting Stdin failed");
-
- // Duplicate the write handle to the pipe so it is not inherited.
- fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
- GetCurrentProcess(), &hChildStdinWrDup, 0,
- FALSE, // not inherited
- DUPLICATE_SAME_ACCESS);
- if (!fSuccess)
- ErrorExit("DuplicateHandle failed");
-
- CloseHandle(hChildStdinWr);
-
- // Set up members of STARTUPINFO structure.
- ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
- siStartInfo.cb = sizeof(STARTUPINFO); // Create the child process.
- bRetVal = CreateProcess(NULL,
- szChildName, // command line
- NULL, // process security attributes
- NULL, // primary thread security attributes
- TRUE, // handles are inherited
- 0, // creation flags
- NULL, // use parent's environment
- NULL, // use parent's current directory
- &siStartInfo, // STARTUPINFO pointer
- &piProcInfo); // receives PROCESS_INFORMATION
-
- // After process creation, restore the saved STDIN and STDOUT.
- if (!SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
- ErrorExit("Re-redirecting Stdin failed\n");
-
- if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
- ErrorExit("Re-redirecting Stdout failed\n");
-
- return bRetVal;
- }
-
- VOID WriteToPipe(VOID)
- {
- DWORD dwRead, dwWritten;
- CHAR chBuf[BUFSIZE];
-
- // Read from a file and write its contents to a pipe.
- for (;;)
- {
- if (!ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
- dwRead == 0)
- break;
- if (!WriteFile(hChildStdinWrDup, chBuf, dwRead,
- &dwWritten, NULL))
- break;
- }
-
-
- // Close the pipe handle so the child process stops reading.
- if (!CloseHandle(hChildStdinWrDup))
- ErrorExit("Close pipe failed\n");
- }
-
-
- VOID ReadFromPipe(VOID)
- {
- DWORD dwRead, dwWritten;
- CHAR chBuf[BUFSIZE];
- HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
-
- // Close the write end of the pipe before reading from the
- // read end of the pipe.
- if (!CloseHandle(hChildStdoutWr))
- ErrorExit("Closing handle failed");
-
- // Read output from the child process, and write to parent's STDOUT.
- for (;;)
- {
- if (!ReadFile(hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
- NULL) || dwRead == 0)
- break;
- if (!WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
- break;
- }
- }
-
-
- // Print an error message and abort.
- VOID ErrorExit(LPTSTR lpszMessage)
- {
- DWORD dwCnt, dwWritten;
- CHAR szString[BUFSIZE];
- HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
-
- dwCnt = wsprintf(szString, "%s\n", lpszMessage);
- WriteFile(hStderr, szString, dwCnt, &dwWritten, NULL);
- ExitProcess(FAILURE);
- }
-
-
-