Started piping implementation.
authorHartmut Birr <osexpert@googlemail.com>
Tue, 7 May 2002 22:27:42 +0000 (22:27 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Tue, 7 May 2002 22:27:42 +0000 (22:27 +0000)
Fixed the command line for popen.

svn path=/trunk/; revision=2926

reactos/lib/msvcrt/stdio/popen.c

index 83c1282..1cc1c87 100644 (file)
@@ -1,4 +1,4 @@
-
+/* $Id: popen.c,v 1.2 2002/05/07 22:27:42 hbirr Exp $ */
 #include <windows.h>
 #include <msvcrt/io.h>
 #include <msvcrt/errno.h>
 #include <msvcrt/stdlib.h>
 #include <msvcrt/string.h>
 #include <msvcrt/internal/file.h>
+#define NDEBUG
+#include <msvcrt/msvcrtdbg.h>
 
 
 FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */
 {
+  char *szCmdLine=NULL;
+  char *szComSpec=NULL;
+  char *s;
   FILE *pf;
   HANDLE hReadPipe, hWritePipe;
+  BOOL result;
   STARTUPINFOA StartupInfo;
   PROCESS_INFORMATION ProcessInformation;
+  SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+
+  DPRINT("_popen('%s', '%s')\n", cm, md);
+
+  if (cm == NULL)
+    return NULL;
+
+  szComSpec = getenv("COMSPEC");
 
-  // fixme CreatePipe
+  if (szComSpec == NULL)
+  {
+    szComSpec = strdup("cmd.exe");
+    if (szComSpec == NULL)
+      return NULL;
+  }
 
-//  if ( !CreatePipe(&hReadPipe,&hWritePipe,NULL,1024))
-//             return NULL;    
+  s = max(strrchr(szComSpec, '\\'), strrchr(szComSpec, '/'));
+  if (s == NULL)
+    s = szComSpec;
+  else
+    s++;
+
+  szCmdLine = malloc(strlen(s) + 4 + strlen(cm) + 1);
+  if (szCmdLine == NULL)
+  {
+    free (szComSpec);
+    return NULL;
+  }
+  
+  strcpy(szCmdLine, s);
+  s = strrchr(szCmdLine, '.');
+  if (s)
+    *s = 0;
+  strcat(szCmdLine, " /C ");
+  strcat(szCmdLine, cm);
+
+  if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
+  {
+    free (szComSpec);
+    free (szCmdLine);
+    return NULL;
+  }
 
+  memset(&StartupInfo, 0, sizeof(STARTUPINFOA));
   StartupInfo.cb = sizeof(STARTUPINFOA);
-  if ( md == "r" ) {
+
+  if (*md == 'r' ) {
        StartupInfo.hStdOutput = hWritePipe;
+       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
   }
-  else if ( md == "w" ) {
+  else if ( *md == 'w' ) {
        StartupInfo.hStdInput = hReadPipe;
+       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
   }
        
-  if (CreateProcessA("cmd.exe",(char *)cm,NULL,NULL,TRUE,
-                     CREATE_NEW_CONSOLE,NULL,NULL,
-                     &StartupInfo,
-                     &ProcessInformation) == FALSE)
+  result = CreateProcessA(szComSpec,
+                         szCmdLine,
+                         NULL,
+                         NULL,
+                         TRUE,
+                         0,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+  free (szComSpec);
+  free (szCmdLine);
+
+  if (result == FALSE)
+  {
+    CloseHandle(hReadPipe);
+    CloseHandle(hWritePipe);
     return NULL;
+  }
+
+  CloseHandle(ProcessInformation.hThread);
 
   if ( *md == 'r' )
     {
       pf = _fdopen(__fileno_alloc(hReadPipe,  _fmode) , "r");
+      CloseHandle(hWritePipe);
     }
   else
     {
       pf = _fdopen( __fileno_alloc(hWritePipe, _fmode) , "w");
+      CloseHandle(hReadPipe);
     }
 
   pf->_name_to_remove = ProcessInformation.hProcess;
@@ -52,48 +117,108 @@ FILE *_popen (const char *cm, const char *md) /* program name, pipe mode */
 int _pclose (FILE *pp)
 {
   fclose(pp);
-  printf("Terminate Process\n");
-//  if (!TerminateProcess(pp->_name_to_remove,0))
-//    return -1;
+  if (!TerminateProcess(pp->_name_to_remove,0))
+    return -1;
   return 0;
 }
 
 
 FILE *_wpopen (const wchar_t *cm, const wchar_t *md) /* program name, pipe mode */
 {
+  wchar_t *szCmdLine=NULL;
+  wchar_t *szComSpec=NULL;
+  wchar_t *s;
   FILE *pf;
   HANDLE hReadPipe, hWritePipe;
+  BOOL result;
   STARTUPINFOW StartupInfo;
   PROCESS_INFORMATION ProcessInformation;
+  SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
 
-  // fixme CreatePipe
+  DPRINT("_wpopen('%S', '%S')\n", cm, md);
 
-//  if ( !CreatePipe(&hReadPipe,&hWritePipe,NULL,1024))
-//             return NULL;    
+  if (cm == NULL)
+    return NULL;
 
-  StartupInfo.cb = sizeof(STARTUPINFOW);
-  if (*md == L'r')
+  szComSpec = _wgetenv(L"COMSPEC");
+
+  if (szComSpec == NULL)
   {
-       StartupInfo.hStdOutput = hWritePipe;
+    szComSpec = _wcsdup(L"cmd.exe");
+    if (szComSpec == NULL)
+      return NULL;
+  }
+
+  s = max(wcsrchr(szComSpec, L'\\'), wcsrchr(szComSpec, L'/'));
+  if (s == NULL)
+    s = szComSpec;
+  else
+    s++;
+
+  szCmdLine = malloc((wcslen(s) + 4 + wcslen(cm) + 1) * sizeof(wchar_t));
+  if (szCmdLine == NULL)
+  {
+    free (szComSpec);
+    return NULL;
   }
-  else if (*md == L'w')
+  
+  wcscpy(szCmdLine, s);
+  s = wcsrchr(szCmdLine, L'.');
+  if (s)
+    *s = 0;
+  wcscat(szCmdLine, L" /C ");
+  wcscat(szCmdLine, cm);
+
+  if ( !CreatePipe(&hReadPipe,&hWritePipe,&sa,1024))
   {
+    free (szComSpec);
+    free (szCmdLine);
+    return NULL;
+  }
+
+  memset(&StartupInfo, 0, sizeof(STARTUPINFOW));
+  StartupInfo.cb = sizeof(STARTUPINFOW);
+
+  if (*md == L'r' ) {
+       StartupInfo.hStdOutput = hWritePipe;
+       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+  }
+  else if ( *md == L'w' ) {
        StartupInfo.hStdInput = hReadPipe;
+       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
   }
        
-  if (CreateProcessW(L"cmd.exe",(wchar_t *)cm,NULL,NULL,TRUE,
-                     CREATE_NEW_CONSOLE,NULL,NULL,
-                     &StartupInfo,
-                     &ProcessInformation) == FALSE)
+  result = CreateProcessW(szComSpec,
+                         szCmdLine,
+                         NULL,
+                         NULL,
+                         TRUE,
+                         0,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+  free (szComSpec);
+  free (szCmdLine);
+
+  if (result == FALSE)
+  {
+    CloseHandle(hReadPipe);
+    CloseHandle(hWritePipe);
     return NULL;
+  }
+
+  CloseHandle(ProcessInformation.hThread);
 
-  if (*md == L'r')
+  if ( *md == L'r' )
     {
       pf = _wfdopen(__fileno_alloc(hReadPipe,  _fmode) , L"r");
+      CloseHandle(hWritePipe);
     }
   else
     {
       pf = _wfdopen( __fileno_alloc(hWritePipe, _fmode) , L"w");
+      CloseHandle(hReadPipe);
     }
 
   pf->_name_to_remove = ProcessInformation.hProcess;