[MSVCRT][CRT]: Improvements/fixes over popen(), from Wine code and ported by Andreas...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 17 Jul 2017 16:11:18 +0000 (16:11 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 17 Jul 2017 16:11:18 +0000 (16:11 +0000)
Should fix returned codes by popen() and pclose(), which are functions that are called by windres, and this latter expects them to succeed. This was not the case before, in ROS, and therefore
trying to e.g. compile ROS within ROS failed from time to time with windres throwing the error that "preprocessing failed".
CORE-11568 #resolve

svn path=/trunk/; revision=75365

reactos/dll/win32/crtdll/dllmain.c
reactos/dll/win32/msvcrt/dllmain.c
reactos/dll/win32/msvcrt20/msvcrt20.c
reactos/dll/win32/msvcrt40/msvcrt40.c
reactos/sdk/lib/crt/include/internal/popen.h [new file with mode: 0644]
reactos/sdk/lib/crt/include/internal/wine/msvcrt.h
reactos/sdk/lib/crt/precomp.h
reactos/sdk/lib/crt/stdio/popen.c

index f5023e6..41e481d 100644 (file)
@@ -161,6 +161,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
         /* Deinit of the WINE code */
         msvcrt_free_io();
         if (reserved) break;
+        msvcrt_free_popen_data();
         msvcrt_free_mt_locks();
         //msvcrt_free_console();
         //msvcrt_free_args();
index 8b277d1..d48d0d3 100644 (file)
@@ -98,6 +98,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
         /* Deinit of the WINE code */
         msvcrt_free_io();
         if (reserved) break;
+        msvcrt_free_popen_data();
         msvcrt_free_mt_locks();
         //msvcrt_free_console();
         //msvcrt_free_args();
index 1390cab..0bda9aa 100644 (file)
@@ -117,6 +117,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
         /* Deinit of the WINE code */
         msvcrt_free_io();
         if (reserved) break;
+        msvcrt_free_popen_data();
         msvcrt_free_mt_locks();
         //msvcrt_free_console();
         //msvcrt_free_args();
index 76cfffd..1509cf3 100644 (file)
@@ -113,6 +113,7 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
         /* Deinit of the WINE code */
         msvcrt_free_io();
         if (reserved) break;
+        msvcrt_free_popen_data();
         msvcrt_free_mt_locks();
         //msvcrt_free_console();
         //msvcrt_free_args();
diff --git a/reactos/sdk/lib/crt/include/internal/popen.h b/reactos/sdk/lib/crt/include/internal/popen.h
new file mode 100644 (file)
index 0000000..f91f4e2
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __CRT_INTERNAL_POPEN_H
+#define __CRT_INTERNAL_POPEN_H
+
+#ifndef _CRT_PRECOMP_H
+#error DO NOT INCLUDE THIS HEADER DIRECTLY
+#endif
+
+struct popen_handle {
+    FILE *f;
+    HANDLE proc;
+};
+extern struct popen_handle *popen_handles;
+extern DWORD popen_handles_size;
+
+#endif
index 319075a..5dc3a37 100644 (file)
@@ -95,6 +95,7 @@ extern void msvcrt_init_args(void);
 extern void msvcrt_free_args(void);
 extern void msvcrt_init_signals(void);
 extern void msvcrt_free_signals(void);
+extern void msvcrt_free_popen_data(void);
 
 extern unsigned create_io_inherit_block(WORD*, BYTE**);
 
index 95e29d6..10f6edf 100644 (file)
@@ -73,6 +73,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 #include <internal/mbstring.h>
 #include <internal/misc.h>
 #include <internal/mtdll.h>
+#include <internal/popen.h>
 #include <internal/rterror.h>
 #include <internal/safecrt.h>
 #include <internal/time.h>
index b9f45b0..56fb18a 100644 (file)
@@ -1,11 +1,12 @@
 /*
-* COPYRIGHT:   See COPYING in the top level directory
-* PROJECT:     ReactOS C runtime library
-* FILE:        lib/sdk/crt/stdio/popen.c
-* PURPOSE:     Pipe Functions
-* PROGRAMERS:  Eric Kohl
-               Hartmut Birr
-*/
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS C runtime library
+ * FILE:            lib/sdk/crt/stdio/popen.c
+ * PURPOSE:         Pipe Functions
+ * PROGRAMMERS:     Eric Kohl
+ *                  Hartmut Birr
+ *                  Also adapted from Wine team code by Andreas Maier.
+ */
 
 #include <precomp.h>
 #include <tchar.h>
@@ -22,11 +23,13 @@ int msvcrt_alloc_fd(HANDLE hand, int flag); //FIXME: Remove
 unsigned split_oflags(unsigned oflags); //FIXME: Remove
 
 #ifndef _UNICODE
-static struct popen_handle {
-    FILE *f;
-    HANDLE proc;
-} *popen_handles;
-static DWORD popen_handles_size;
+struct popen_handle *popen_handles = NULL;
+DWORD popen_handles_size = 0;
+
+void msvcrt_free_popen_data(void)
+{
+    free(popen_handles);
+}
 #endif
 
 /*
@@ -37,12 +40,14 @@ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
     _TCHAR *szCmdLine=NULL;
     _TCHAR *szComSpec=NULL;
     _TCHAR *s;
-    FILE *pf;
+    FILE *ret;
     HANDLE hReadPipe, hWritePipe;
     BOOL result;
     STARTUPINFO StartupInfo;
     PROCESS_INFORMATION ProcessInformation;
     SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+    struct popen_handle *container;
+    DWORD i;
 
     TRACE(MK_STR(_tpopen)"('%"sT"', '%"sT"')\n", cm, md);
 
@@ -80,6 +85,7 @@ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
         return NULL;
     }
 
+    memset(&ProcessInformation, 0, sizeof(ProcessInformation));
     memset(&StartupInfo, 0, sizeof(STARTUPINFO));
     StartupInfo.cb = sizeof(STARTUPINFO);
 
@@ -117,20 +123,47 @@ FILE *_tpopen (const _TCHAR *cm, const _TCHAR *md) /* program name, pipe mode */
     }
 
     CloseHandle(ProcessInformation.hThread);
-    CloseHandle(ProcessInformation.hProcess);
+
+    _mlock(_POPEN_LOCK);
+    for(i=0; i<popen_handles_size; i++)
+    {
+        if (!popen_handles[i].f)
+            break;
+    }
+    if (i==popen_handles_size)
+    {
+        i = (popen_handles_size ? popen_handles_size*2 : 8);
+        container = realloc(popen_handles, i*sizeof(*container));
+        if (!container) goto error;
+
+        popen_handles = container;
+        container = popen_handles+popen_handles_size;
+        memset(container, 0, (i-popen_handles_size)*sizeof(*container));
+        popen_handles_size = i;
+    }
+    else container = popen_handles+i;
 
     if ( *md == 'r' )
     {
-        pf = _tfdopen(msvcrt_alloc_fd(hReadPipe,  split_oflags(_fmode)) , _T("r"));
+        ret = _tfdopen(msvcrt_alloc_fd(hReadPipe,  split_oflags(_fmode)) , _T("r"));
         CloseHandle(hWritePipe);
     }
     else
     {
-        pf = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w"));
+        ret = _tfdopen( msvcrt_alloc_fd(hWritePipe, split_oflags(_fmode)) , _T("w"));
         CloseHandle(hReadPipe);
     }
 
-    return( pf );
+    container->f = ret;
+    container->proc = ProcessInformation.hProcess;
+    _munlock(_POPEN_LOCK);
+
+    return ret;
+
+error:
+    if (ProcessInformation.hProcess != 0)
+        CloseHandle(ProcessInformation.hProcess);
+    return NULL;
 }
 
 #ifndef _UNICODE