#include #include #include #include #include #include #include #include #include #define BUFSIZE 512 // Функция для создания дочернего процесса с перенаправлением STDIN BOOL CreateChildProcess(LPTSTR commandLine, HANDLE hChildStdIn) { STARTUPINFO siStartInfo; PROCESS_INFORMATION piProcInfo; BOOL bSuccess = FALSE; ZeroMemory(&piProcInfo, sizeof(piProcInfo)); ZeroMemory(&siStartInfo, sizeof(siStartInfo)); siStartInfo.cb = sizeof(siStartInfo); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); siStartInfo.hStdInput = hChildStdIn; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; bSuccess = CreateProcess( NULL, // Имя исполняемого модуля commandLine, // Командная строка NULL, // Атрибуты безопасности процесса NULL, // Атрибуты безопасности потока TRUE, // Наследование дескрипторов 0, // Флаги создания NULL, // Окружение NULL, // Текущий каталог &siStartInfo, // STARTUPINFO &piProcInfo // PROCESS_INFORMATION ); if (bSuccess) { CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } return bSuccess; } void ReadFromPipe(HANDLE hReadPipe) { DWORD dwRead; CHAR chBuf[BUFSIZE]; BOOL bSuccess = FALSE; for (;;) { bSuccess = ReadFile(hReadPipe, chBuf, BUFSIZE, &dwRead, NULL); if (!bSuccess || dwRead == 0) break; chBuf[dwRead] = '\0'; printf("%s", chBuf); } } int main() { HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE hPipeSquarerRead, hPipeSquarerWrite; HANDLE hPipeCuberRead, hPipeCuberWrite; SECURITY_ATTRIBUTES saAttr; // Настраиваем security attributes для наследования дескрипторов saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Создаем каналы для процесса-возводителя в квадрат if (!CreatePipe(&hPipeSquarerRead, &hPipeSquarerWrite, &saAttr, 0)) { printf("CreatePipe failed (%d)\n", GetLastError()); return 1; } if (!SetHandleInformation(hPipeSquarerWrite, HANDLE_FLAG_INHERIT, 0)) { printf("SetHandleInformation for suarer failed (%d)\n", GetLastError()); return 1; } // Создаем каналы для процесса-возводителя в куб if (!CreatePipe(&hPipeCuberRead, &hPipeCuberWrite, &saAttr, 0)) { printf("CreatePipe failed (%d)\n", GetLastError()); return 1; } if (!SetHandleInformation(hPipeCuberWrite, HANDLE_FLAG_INHERIT, 0)) { printf("SetHandleInformation for cuber failed (%d)\n", GetLastError()); return 1; } // Создаем процесс для возведения в квадрат TCHAR sqCmdLine[] = "squarer.exe"; if (!CreateChildProcess(sqCmdLine, hPipeSquarerRead)) { printf("CreateProcess for squarer failed (%d)\n", GetLastError()); return 1; } // Создаем процесс для возведения в куб TCHAR cbCmdLine[] = "cuber.exe"; if (!CreateChildProcess(cbCmdLine, hPipeCuberRead)) { printf("CreateProcess for cuber failed (%d)\n", GetLastError()); return 1; } // Закрываем ненужные дескрипторы CloseHandle(hPipeSquarerRead); CloseHandle(hPipeCuberRead); // Передаем числа дочерним процессам for (int i = 1; i <= 5; i++) { DWORD dwWritten; char buffer[BUFSIZE]; int len; // Передаем число процессу-возводителю в квадрат len = sprintf_s(buffer, BUFSIZE, "%d\n", i); WriteFile(hPipeSquarerWrite, buffer, len, &dwWritten, NULL); // Передаем число процессу-возводителю в куб len = sprintf_s(buffer, BUFSIZE, "%d\n", i); WriteFile(hPipeCuberWrite, buffer, len, &dwWritten, NULL); printf("Parent sent: %d\n", i); Sleep(1000); } // Закрываем каналы записи CloseHandle(hPipeSquarerWrite); CloseHandle(hPipeCuberWrite); printf("Parent process finished.\n"); return 0; }