#include #include #include #include void errorExit(const char *txt); int main(int argc, char* argv[]) { SECURITY_ATTRIBUTES sa; memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; HANDLE hParentInput, hParentOutput; HANDLE hChildInput, hChildOutput; // Create a pipe for the child process's STDOUT. if (!CreatePipe( &hParentInput, &hChildOutput, &sa, 0 )) errorExit("Child output pipe creation failed"); // Ensure the hParentInput handle is not inherited. SetHandleInformation( hParentInput, HANDLE_FLAG_INHERIT, 0 ); // Create a pipe for the child process's STDIN. if (!CreatePipe( &hChildInput, &hParentOutput, &sa, 0 )) errorExit("Child input pipe creation failed"); // Ensure the hParentOutput handle is not inherited. SetHandleInformation( hParentOutput, HANDLE_FLAG_INHERIT, 0 ); // Create the child process PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdError = hChildOutput; si.hStdOutput = hChildOutput; si.hStdInput = hChildInput; si.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcess( "rcalc.exe", // Module name "rcalc.exe", // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable TRUE, // Inherit handles 0, // CREATE_NEW_CONSOLE, // Creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi // Pointer to PROCESS_INFORMATION structure )) errorExit("CreateProcess failed"); // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); while (true) { char inputLine[256]; char outputLine[64]; if (fgets(inputLine, 254, stdin) <= 0) break; inputLine[255] = 0; // for safety int len = (int) strlen(inputLine); if ( inputLine[0] == '\n' || inputLine[0] == 'q' ) break; // Write to child DWORD written = 0; if (!WriteFile( hParentOutput, inputLine, len, &written, NULL )) break; // Receive from child DWORD numRead = 0; if ( !ReadFile( hParentInput, outputLine, 62, &numRead, NULL ) || numRead == 0 ) break; outputLine[numRead] = 0; outputLine[63] = 0; // for safety printf("%s", outputLine); } if (!CloseHandle(hParentInput)) errorExit("Closing input handle failed"); if (!CloseHandle(hParentOutput)) errorExit("Closing output handle failed"); return 0; } void errorExit(const char *txt) { fprintf( stderr, "%s, error=%d\n", txt, GetLastError() ); ExitProcess(-1); }