- /*
- *
- * popen_replacement1.c - Win32 |_popen()| replacement
- * since Win32 _popen() keeps triggering EINVAL
- *
- * Written by Roland Mainz <roland.mainz@nrubsig.org>
- */
- #define UNICODE 1
- #define _UNICODE 1
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- typedef struct {
- HANDLE hReadPipe;
- HANDLE hWritePipe;
- PROCESS_INFORMATION pi;
- } PIPE_INFO;
- PIPE_INFO *mypopen(const char *command, const char *mode) {
- static PIPE_INFO gpinfo = {0};
- PIPE_INFO *pinfo = &gpinfo;
- STARTUPINFOA si;
- SECURITY_ATTRIBUTES sa = { 0 };
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
- if (!command || !mode) {
- return NULL;
- }
- // Create a pipe for communication between the parent and child processes.
- if (!CreatePipe(&pinfo->hReadPipe, &pinfo->hWritePipe, &sa, 0)) {
- return NULL;
- }
- // Set the pipe handles to non-inheritable.
- if (!SetHandleInformation(pinfo->hReadPipe, HANDLE_FLAG_INHERIT, FALSE)) {
- CloseHandle(pinfo->hReadPipe);
- CloseHandle(pinfo->hWritePipe);
- return NULL;
- }
- // Initialize the STARTUPINFO structure.
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- si.hStdInput = NULL;
- si.hStdOutput = pinfo->hWritePipe;
- si.hStdError = GetStdHandle(STD_ERROR_HANDLE) /* pinfo->hWritePipe*/;
- si.dwFlags |= STARTF_USESTDHANDLES;
- // Create the child process.
- if (!CreateProcessA(NULL, (LPSTR)command, NULL, NULL, TRUE, 0/*DETACHED_PROCESS*/, NULL, NULL, &si, &pinfo->pi)) {
- CloseHandle(pinfo->hReadPipe);
- CloseHandle(pinfo->hWritePipe);
- return NULL;
- }
- // Close the write handle to the pipe from the parent process.
- CloseHandle(pinfo->hWritePipe);
- return pinfo;
- }
- int mypclose(PIPE_INFO *pinfo) {
- DWORD status;
- // Close the read handle to the pipe from the child process.
- CloseHandle(pinfo->hReadPipe);
- // Wait for the child process to terminate.
- WaitForSingleObject(pinfo->pi.hProcess, INFINITE);
- // Get the exit code of the child process.
- if (!GetExitCodeProcess(pinfo->pi.hProcess, &status)) {
- status = -1;
- }
- // Close the process handles.
- CloseHandle(pinfo->pi.hProcess);
- CloseHandle(pinfo->pi.hThread);
- return status;
- }
- int main(int ac, char *av[])
- {
- PIPE_INFO *pinfo = mypopen("C:\\cygwin64\\bin\\dir.exe", "r");
- if (pinfo) {
- char buf[1024];
- DWORD n;
- while (ReadFile(pinfo->hReadPipe, buf, sizeof(buf), &n, NULL)) {
- buf[n] = '\0';
- }
- mypclose(pinfo);
- }
- return 0;
- }
popen_replacement1.c - Win32 |_popen()| replacement
Posted by Anonymous on Tue 28th Nov 2023 07:57
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.