Fix for executing external apps on win32 with a space in the filename path.

Blaine Whittle <>
Wed Jun 10 23:33:05 CEST 2009


This is a resubmission of a patch I made last year, it's been applied and tested against R13B.
Original submission http://www.erlang.org/cgi-bin/ezmlm-cgi?3:mss:268:200808:lkalfgpohefpiajoncnd
After reviewing my original post, it appears that the test case I listed is incorrect.   Passing a command line wrapped with double quotes to os:cmd works as expected, for example this command should work in R13B (assuming Visual Studio 2005 installed on the machine)
os:cmd("\"C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\IDE\\devenv.com\" /?").
The real issue is with open_port.   For example, passing the same double-quote-delimited command line to open_port on R13B results in an einval exception
open_port({spawn, "\"C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\IDE\\devenv.com\" /?"},[{line, 60}, exit_status, hide, stderr_to_stdout]).

** exception error: einval
     in function  open_port/2
        called as open_port({spawn,"\"C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\IDE\\devenv.com\" /?"},
                            [{line,60},exit_status,hide,stderr_to_stdout])
The following patch fixes the open_port case
$ diff -u erts/emulator/sys/win32/sys.c $ERL_TOP/erts/emulator/sys/win32/sys.c
--- erts/emulator/sys/win32/sys.c       2009-03-12 04:16:34.000000000 -0800
+++ /cygdrive/c/dev/otp_src_R13B/erts/emulator/sys/win32/sys.c  2009-06-09 17:13:20.489037600 -0700
@@ -1237,6 +1237,8 @@
     char execPath[MAX_PATH];
     int cmdlength;
     char* thecommand;
+       char* fixedcommand;
+       char* pch;
     HANDLE hProcess = GetCurrentProcess();

     siStartInfo.cb = sizeof(STARTUPINFO);
@@ -1254,10 +1256,25 @@
     strncpy(thecommand, origcmd, cmdlength);
     thecommand[cmdlength] = '\0';
     DEBUGF(("spawn command: %s\n", thecommand));
-
-    applType = ApplicationType(thecommand, execPath);
-    DEBUGF(("ApplicationType returned for (%s) is %d\n", thecommand, applType));
+
+       fixedcommand = (char *) erts_alloc(ERTS_ALC_T_TMP, cmdlength+1);
+       fixedcommand[0] = '\0';
+       pch = strtok(thecommand,"\"");
+       if (pch == NULL) {
+               strncpy(fixedcommand, origcmd, cmdlength);
+               fixedcommand[cmdlength] = '\0';
+       }
+       else {
+               while (pch != NULL) {
+                       strncat(fixedcommand, pch, strlen(pch));
+                       pch = strtok(NULL, "\"");
+               }
+       }
+
+    applType = ApplicationType(fixedcommand, execPath);
+    DEBUGF(("ApplicationType returned for (%s) is %d\n", fixedcommand, applType));
     erts_free(ERTS_ALC_T_TMP, (void *) thecommand);
+    erts_free(ERTS_ALC_T_TMP, (void *) fixedcommand);
     if (applType == APPL_NONE) {
        return FALSE;
     }



More information about the erlang-patches mailing list