pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


popen_replacement1.c - Win32 |_popen()| replacement
Posted by Anonymous on Tue 28th Nov 2023 07:57
raw | new post

  1.  
  2. /*
  3.  *
  4.  * popen_replacement1.c - Win32 |_popen()| replacement
  5.  * since Win32 _popen() keeps triggering EINVAL
  6.  *
  7.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  8.  */
  9. #define UNICODE 1
  10. #define _UNICODE 1
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <windows.h>
  15.  
  16.  
  17. typedef struct {
  18.     HANDLE hReadPipe;
  19.     HANDLE hWritePipe;
  20.     PROCESS_INFORMATION pi;
  21. } PIPE_INFO;
  22.  
  23. PIPE_INFO *mypopen(const char *command, const char *mode) {
  24.     static PIPE_INFO gpinfo = {0};
  25.     PIPE_INFO *pinfo = &gpinfo;
  26.     STARTUPINFOA si;
  27.     SECURITY_ATTRIBUTES sa = { 0 };
  28.     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  29.     sa.bInheritHandle = TRUE;
  30.     sa.lpSecurityDescriptor = NULL;
  31.  
  32.     if (!command || !mode) {
  33.         return NULL;
  34.     }
  35.  
  36.     // Create a pipe for communication between the parent and child processes.
  37.     if (!CreatePipe(&pinfo->hReadPipe, &pinfo->hWritePipe, &sa, 0)) {
  38.         (void)puts("pipe error");
  39.         return NULL;
  40.     }
  41.  
  42.     // Set the pipe handles to non-inheritable.
  43.     if (!SetHandleInformation(pinfo->hReadPipe, HANDLE_FLAG_INHERIT, FALSE)) {
  44.         CloseHandle(pinfo->hReadPipe);
  45.         CloseHandle(pinfo->hWritePipe);
  46.         (void)puts("SetHandleInformation error");
  47.         return NULL;
  48.     }
  49.  
  50.     // Initialize the STARTUPINFO structure.
  51.     ZeroMemory(&si, sizeof(si));
  52.     si.cb = sizeof(si);
  53.     si.hStdInput = NULL;
  54.     si.hStdOutput = pinfo->hWritePipe;
  55.     si.hStdError = GetStdHandle(STD_ERROR_HANDLE) /* pinfo->hWritePipe*/;
  56.     si.dwFlags |= STARTF_USESTDHANDLES;
  57.  
  58.     // Create the child process.
  59.     if (!CreateProcessA(NULL, (LPSTR)command, NULL, NULL, TRUE, 0/*DETACHED_PROCESS*/, NULL, NULL, &si, &pinfo->pi)) {
  60.         CloseHandle(pinfo->hReadPipe);
  61.         CloseHandle(pinfo->hWritePipe);
  62.         (void)puts("cannot create process");
  63.         return NULL;
  64.     }
  65.  
  66.     // Close the write handle to the pipe from the parent process.
  67.     CloseHandle(pinfo->hWritePipe);
  68.  
  69.     return pinfo;
  70. }
  71.  
  72. int mypclose(PIPE_INFO *pinfo) {
  73.     DWORD status;
  74.  
  75.     // Close the read handle to the pipe from the child process.
  76.     CloseHandle(pinfo->hReadPipe);
  77.  
  78.     // Wait for the child process to terminate.
  79.     WaitForSingleObject(pinfo->pi.hProcess, INFINITE);
  80.  
  81.     // Get the exit code of the child process.
  82.     if (!GetExitCodeProcess(pinfo->pi.hProcess, &status)) {
  83.         status = -1;
  84.     }
  85.  
  86.     // Close the process handles.
  87.     CloseHandle(pinfo->pi.hProcess);
  88.     CloseHandle(pinfo->pi.hThread);
  89.    
  90.     (void)printf("exit code=%d\n", (int)status);
  91.  
  92.     return status;
  93. }
  94.  
  95. int main(int ac, char *av[])
  96. {
  97.         (void)puts("# start.");
  98.         PIPE_INFO *pinfo = mypopen("C:\\cygwin64\\bin\\dir.exe", "r");
  99.         if (pinfo) {
  100.                 char buf[1024];
  101.                 DWORD n;
  102.  
  103.                 while (ReadFile(pinfo->hReadPipe, buf, sizeof(buf), &n, NULL)) {
  104.                         buf[n] = '\0';
  105.                         printf("|%s|,n=%ld\n", buf, (long)n);
  106.                 }
  107.  
  108.                 mypclose(pinfo);
  109.         }
  110.         (void)puts("# done.");
  111.         return 0;
  112. }

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at