[erlang-questions] how to open_port with spaces in path - patch for emulator to accept quoted commands

Denis Bilenko denis.bilenko@REDACTED
Tue Feb 13 13:37:06 CET 2007


Hello,

Thank you all for answers, altname does provide workaround for the problem
(it's a pity though, that file:altname is undocumented).

Still, it is an inconvenience.

Windows' CreateProcess accepts quoted arguments happily, so I've
debugged CreateChildProcess (erts\emulator\sys\win32\sys.c) and found
out that problem originates from call to GetFileAttributes which does
not understand quoted arguments.
CreateChildProcess("\"D:/a a/my.exe\" some args") calls
GetFileAttributes("\"D:/a a/my.exe\"") which fails.

Following patch strips the quotes out of GetFileAttributes'
argument (ApplicationType calls GetFileAttributes).
With this information, any chance this will be fixed in the next release?

--- otp_src_R11B-3-original\erts\emulator\sys\win32\sys.c       Mon
Jan 29 18:52:58 2007
+++ otp_src_R11B-3\erts\emulator\sys\win32\sys.c        Tue Feb 13 17:47:59 2007
@@ -1104,6 +1104,9 @@
     int cmdlength;
     char* thecommand;
     HANDLE hProcess = GetCurrentProcess();
+
+    char* thecommand_start = origcmd;
+    int thecommand_length;

     siStartInfo.cb = sizeof(STARTUPINFO);
     siStartInfo.dwFlags = STARTF_USESTDHANDLES;
@@ -1116,9 +1119,26 @@
      * contain spaces).
      */
     cmdlength = parse_command(origcmd);
-    thecommand = (char *) erts_alloc(ERTS_ALC_T_TMP, cmdlength+1);
-    strncpy(thecommand, origcmd, cmdlength);
-    thecommand[cmdlength] = '\0';
+
+    /*
+     * for quoted argument, parse_command will return quoted result, i.e.
+     * "\"C:/Program Files/abc.exe\" arg1" -> "\"C:/Program Files/abc.exe\""
+     * Such an argument will cause GetFileAttributes to return
+     * INVALID_FILE_ATTRIBUTES, which will cause ApplicationType to
+     * return APPL_NONE.
+     *
+     * Cut the quotes out of command.
+     */
+    if (cmdlength > 1 && origcmd[0]=='\"' && origcmd[cmdlength-1]=='\"')
+    {
+      thecommand_start = origcmd + 1;
+      thecommand_length = cmdlength - 2;
+    }
+    else thecommand_length = cmdlength;
+
+    thecommand = (char *) erts_alloc(ERTS_ALC_T_TMP, thecommand_length+1);
+    strncpy(thecommand, thecommand_start, thecommand_length);
+    thecommand[thecommand_length] = '\0';
     DEBUGF(("spawn command: %s\n", thecommand));

     applType = ApplicationType(thecommand, execPath);

/Denis

On 2/13/07, Eric P. Melbardis <eric.melbardis@REDACTED> wrote:
> Need to use 'unix style' or erlang internal format.
>
>
> filename:split("c:/a b/cc").
> ["c:/","a b","cc"]
>
> I just pass the 'unix' style name to altname and use the result as the
> command when doing a spawn. Spaces are no longer an issue.
>
> Regards
>
>
>
> -----Original Message-----
> From: Serge Aleynikov [mailto:serge@REDACTED]
> Sent: Monday, February 12, 2007 10:50 AM
> To: Eric P. Melbardis
> Cc: Denis Bilenko; erlang-questions@REDACTED
> Subject: Re: [erlang-questions] how to open_port with spaces in path?
>
> Actually the code below won't work, because filename:split/1 is bound to
>
> the same problem of dealing with spaces as the one mentioned in the
> beginning of the thread:
>
> 1> filename:split("c:\temp\a a\my.exe").
> ["c:","\tempa amy.exe"]
>
> The main point about having file:altname/1 is quite useful though.  Yet,
>
> it is somewhat counter intuitive on Windows (I would think that the
> results of the two cases below would be reversed):
>
> 2> file:altname("c:\temp\a a").
> {error,eio}
> 3> file:altname("c:/temp/a a").
> {ok,"AA0919~1"}
>
> Serge
>



More information about the erlang-questions mailing list