소스 검색

* unicode executeprocess from work during Lazarus convention in IJsselstein

git-svn-id: trunk@33290 -
marco 9 년 전
부모
커밋
66608fec02
10개의 변경된 파일158개의 추가작업 그리고 79개의 파일을 삭제
  1. 10 10
      rtl/amicommon/sysutils.pp
  2. 4 2
      rtl/objpas/sysutils/osutilsh.inc
  3. 18 0
      rtl/objpas/sysutils/sysutils.inc
  4. 2 2
      rtl/unix/dos.pp
  5. 1 1
      rtl/unix/genfunch.inc
  6. 1 1
      rtl/unix/genfuncs.inc
  7. 18 11
      rtl/unix/sysutils.pp
  8. 69 40
      rtl/unix/unix.pp
  9. 4 4
      rtl/unix/unixutil.pp
  10. 31 8
      rtl/win/sysutils.pp

+ 10 - 10
rtl/amicommon/sysutils.pp

@@ -837,11 +837,11 @@ begin
   Result:=Dos.EnvStr(Index);
 end;
 
-function ExecuteProcess (const Path: AnsiString; const ComLine: AnsiString;Flags:TExecuteFlags=[]):
+function ExecuteProcess (const Path: RawByteString; const ComLine: RawByteString;Flags:TExecuteFlags=[]):
                                                                        integer;
 var
-  tmpPath: AnsiString;
-  convPath: AnsiString;
+  tmpPath,
+  convPath: RawByteString;
   CommandLine: AnsiString;
   tmpLock: longint;
 
@@ -849,8 +849,8 @@ var
 begin
   DosError:= 0;
   
-  convPath:=PathConv(Path);
-  tmpPath:=convPath+' '+ComLine;
+  convPath:=PathConv((ToSingleByteFileSystemEncodedFileName(Path));
+  tmpPath:=convPath+' '+ToSingleByteFileSystemEncodedFileName(ComLine);
   
   { Here we must first check if the command we wish to execute }
   { actually exists, because this is NOT handled by the        }
@@ -883,19 +883,19 @@ begin
   end;
 end;
 
-function ExecuteProcess (const Path: AnsiString;
-                                  const ComLine: array of AnsiString;Flags:TExecuteFlags=[]): integer;
+function ExecuteProcess (const Path: RawByteString;
+                                  const ComLine: array of RawByteString;Flags:TExecuteFlags=[]): integer;
 var
-  CommandLine: AnsiString;
+  CommandLine: RawByteString;
   I: integer;
 
 begin
   Commandline := '';
   for I := 0 to High (ComLine) do
    if Pos (' ', ComLine [I]) <> 0 then
-    CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
+    CommandLine := CommandLine + ' ' + '"' + ToSingleByteFileSystemEncodedFileName(ComLine [I]) + '"'
    else
-    CommandLine := CommandLine + ' ' + Comline [I];
+    CommandLine := CommandLine + ' ' + ToSingleByteFileSystemEncodedFileName(Comline [I]);
   ExecuteProcess := ExecuteProcess (Path, CommandLine);
 end;
 

+ 4 - 2
rtl/objpas/sysutils/osutilsh.inc

@@ -29,8 +29,10 @@ Function GetEnvironmentVariableCount : Integer;
 {$IFDEF HAS_SLEEP}
 procedure Sleep(milliseconds: Cardinal);
 {$ENDIF}
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array of AnsiString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array of RawByteString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
 
 Function GetTempDir(Global : Boolean) : String;
 Function GetTempDir : String;

+ 18 - 0
rtl/objpas/sysutils/sysutils.inc

@@ -751,3 +751,21 @@ begin
     OnBeep;
 end;
 
+// OSes that only provide 1 byte versions can enable the following define
+{$ifdef executeprocuni}
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
+begin
+  result:=ExecuteProcess(ToSingleByteFileSystemEncodedFileName(Path),ToSingleByteFileSystemEncodedFileName(ComLine));
+end;
+
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
+var 
+  ComLineA : array of RawByteString;
+  I        : Integer;
+begin
+  SetLength(ComLineA,high(comline)-low(comline)+1);
+  For I:=0 to length(ComLineA)-1 Do
+    ComLineA[i]:=ToSingleByteFileSystemEncodedFileName(ComLine[I]);
+  result:=ExecuteProcess(ToSingleByteFileSystemEncodedFileName(Path),ComLineA);
+end;
+{$endif}

+ 2 - 2
rtl/unix/dos.pp

@@ -312,7 +312,7 @@ Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
 var
   pid      : longint; // pid_t?
   cmdline2 : ppchar;
-  commandline : ansistring;
+  commandline : RawByteString;
   realpath : ansistring;
 
 // The Error-Checking in the previous Version failed, since halt($7F) gives an WaitPid-status of $7F00
@@ -330,7 +330,7 @@ Begin
      realpath:=path;
      if Comline<>'' Then
        begin
-         CommandLine:=ComLine;  // conversion must live till after fpexec!
+         CommandLine:=ToSingleByteFileSystemEncodedFileName(ComLine);  // conversion must live till after fpexec!
          cmdline2:=StringtoPPChar(CommandLine,1);
          cmdline2^:=pchar(realPath);
        end

+ 1 - 1
rtl/unix/genfunch.inc

@@ -16,6 +16,6 @@
 
 function CreateShellArgV(const prog:string):ppchar; deprecated;
 
-function CreateShellArgV(const prog:Ansistring):ppchar; deprecated;
+function CreateShellArgV(const prog:RawByteString):ppchar; deprecated;
 
 procedure FreeShellArgV(p:ppchar); deprecated;

+ 1 - 1
rtl/unix/genfuncs.inc

@@ -42,7 +42,7 @@ begin
   CreateShellArgV:=InternalCreateShellArgV(@prog[1],length(prog));
 end;
 
-function CreateShellArgV(const prog:Ansistring):ppchar;
+function CreateShellArgV(const prog:RawByteString):ppchar;
 {
   Create an argv which executes a command in a shell using /bin/sh -c
   using a AnsiString;

+ 18 - 11
rtl/unix/sysutils.pp

@@ -280,6 +280,8 @@ procedure UnhookSignal(RtlSigNum: Integer; OnlyIfHooked: Boolean = True);
 {$DEFINE FPC_FEXPAND_GETENVPCHAR} { GetEnv result is a PChar }
 
 { Include platform independent implementation part }
+
+{$define executeprocuni}
 {$i sysutils.inc}
 
 { Include SysCreateGUID function }
@@ -1291,11 +1293,12 @@ begin
 end;
 
 
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
 var
   pid    : longint;
   e      : EOSError;
-  CommandLine: AnsiString;
+  CommandLine: RawByteString;
+  LPath  : RawByteString;
   cmdline2 : ppchar;
 
 Begin
@@ -1306,19 +1309,24 @@ Begin
 
    // Only place we still parse
    cmdline2:=nil;
+   LPath:=Path;
+   UniqueString(LPath);
+   SetCodePage(LPath,DefaultFileSystemCodePage,true);
    if Comline<>'' Then
      begin
        CommandLine:=ComLine;
+
        { Make an unique copy because stringtoppchar modifies the
-         string }
+         string, and force conversion to intended fscp }
        UniqueString(CommandLine);
+       SetCodePage(CommandLine,DefaultFileSystemCodePage,true);
        cmdline2:=StringtoPPChar(CommandLine,1);
-       cmdline2^:=pchar(pointer(Path));
+       cmdline2^:=pchar(pointer(LPath));
      end
    else
      begin
        getmem(cmdline2,2*sizeof(pchar));
-       cmdline2^:=pchar(Path);
+       cmdline2^:=pchar(LPath);
        cmdline2[1]:=nil;
      end;
 
@@ -1330,14 +1338,14 @@ Begin
   if pid=0 then
    begin
    {The child does the actual exec, and then exits}
-      fpexecv(pchar(pointer(Path)),Cmdline2);
+      fpexecv(pchar(pointer(LPath)),Cmdline2);
      { If the execve fails, we return an exitvalue of 127, to let it be known}
      fpExit(127);
    end
   else
    if pid=-1 then         {Fork failed}
     begin
-      e:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,-1]);
+      e:=EOSError.CreateFmt(SExecuteProcessFailed,[LPath,-1]);
       e.ErrorCode:=-1;
       raise e;
     end;
@@ -1350,18 +1358,17 @@ Begin
 
   if (result<0) or (result=127) then
     begin
-    E:=EOSError.CreateFmt(SExecuteProcessFailed,[Path,result]);
+    E:=EOSError.CreateFmt(SExecuteProcessFailed,[LPath,result]);
     E.ErrorCode:=result;
     Raise E;
     end;
 End;
 
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array Of AnsiString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array Of RawByteString;Flags:TExecuteFlags=[]):integer;
 
 var
   pid    : longint;
-  e : EOSError;
-
+  e      : EOSError;
 Begin
   pid:=fpFork;
   if pid=0 then

+ 69 - 40
rtl/unix/unix.pp

@@ -70,15 +70,15 @@ Procedure ReReadLocalTime;
 
 {**  Process Handling  **}
 
-function FpExecLE (Const PathName:AnsiString;const S:Array Of AnsiString;MyEnv:ppchar):cint;
-function FpExecL  (Const PathName:AnsiString;const S:Array Of AnsiString):cint;
-function FpExecLP (Const PathName:AnsiString;const S:Array Of AnsiString):cint;
-function FpExecLPE(Const PathName:AnsiString;const S:Array Of AnsiString;env:ppchar):cint;
-function FpExecV  (Const PathName:AnsiString;args:ppchar):cint;
-function FpExecVP (Const PathName:AnsiString;args:ppchar):cint;
-function FpExecVPE(Const PathName:AnsiString;args,env:ppchar):cint;
+function FpExecLE (Const PathName:RawByteString;const S:Array Of RawByteString;MyEnv:ppchar):cint;
+function FpExecL  (Const PathName:RawByteString;const S:Array Of RawByteString):cint;
+function FpExecLP (Const PathName:RawByteString;const S:Array Of RawByteString):cint;
+function FpExecLPE(Const PathName:RawByteString;const S:Array Of RawByteString;env:ppchar):cint;
+function FpExecV  (Const PathName:RawByteString;args:ppchar):cint;
+function FpExecVP (Const PathName:RawByteString;args:ppchar):cint;
+function FpExecVPE(Const PathName:RawByteString;args,env:ppchar):cint;
 
-Function fpSystem(const Command:AnsiString):cint;
+Function fpSystem(const Command:RawByteString):cint;
 
 Function WaitProcess (Pid:cint):cint; 
 
@@ -116,8 +116,10 @@ Type
                            CurrentDirectoryFirst,
                            CurrentDirectoryLast);
 
-Function  FSearch  (const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
-Function  FSearch  (const path:AnsiString;dirlist:AnsiString):AnsiString;
+Function  FSearch  (const path:RawByteString;dirlist:RawByteString;CurrentDirStrategy:TFSearchOption):RawByteString;
+Function  FSearch  (const path:RawByteString;dirlist:RawByteString):RawByteString;
+Function  FSearch  (const path:UnicodeString;dirlist:UnicodeString;CurrentDirStrategy:TFSearchOption):UnicodeString;
+Function  FSearch  (const path:UnicodeString;dirlist:UnicodeString):UnicodeString;
 
 {$ifdef FPC_USE_LIBC}
   const clib = 'c';
@@ -179,14 +181,14 @@ begin
    end;
 end;
 
-function intFpExecVEMaybeP (Const PathName:AnsiString;Args,MyEnv:ppchar;SearchPath:Boolean):cint;
+function intFpExecVEMaybeP (Const PathName:RawByteString;Args,MyEnv:ppchar;SearchPath:Boolean):cint;
 // does an ExecVE, but still has to handle P
 // execv variants call this directly, execl variants indirectly via
 //     intfpexecl
 
 Var
-  NewCmd  : ansistring;
-  ThePath : AnsiString;
+  NewCmd  : RawByteString;
+  ThePath : RawByteString;
 
 Begin
   If SearchPath and (pos('/',pathname)=0) Then
@@ -196,19 +198,21 @@ Begin
       // Stevens says only search if newcmd contains no '/'
       // fsearch is not ansistring clean yet.
       ThePath:=fpgetenv('PATH');
+      SetCodePage(ThePath,DefaultSystemCodePage,false);
+      SetCodePage(ThePath,DefaultFileSystemCodePage,true);
       if thepath='' then
         thepath:='.';     // FreeBSD uses _PATH_DEFPATH = /usr/bin:/bin
                           // but a quick check showed that _PATH_DEFPATH
                           // varied from OS to OS
 
-      newcmd:=FSearch(pathname,thepath,NoCurrentDirectory);
+      newcmd:=ToSingleByteFileSystemEncodedFileName(FSearch(pathname,thepath,NoCurrentDirectory));
       // FreeBSD libc keeps on trying till a file is successfully run.
       // Stevens says "try each path prefix"
 
       // execp puts newcmd here.
         args^:=pchar(newcmd);
    End else
-      newcmd:=pathname;
+      newcmd:=ToSingleByteFileSystemEncodedFileName(pathname);
  // repeat
 //      if searchpath then args^:=pchar(commandtorun)
 
@@ -218,10 +222,9 @@ Begin
 // Should we deallocate p on fail? -> no fpexit is run no matter what
 //
 }
-// if intfpexecvemaybep=-1 then zoekvolgende file.
+// if intfpexecvemaybep=-1 then seach next file.
 // until (Goexit) or SearchExit;
 
-
 {
  If IntFpExec=-1 Then
     Begin
@@ -234,19 +237,23 @@ Begin
 }
 end;
 
-function intFpExecl (Const PathName:AnsiString;const s:array of ansistring;MyEnv:ppchar;SearchPath:Boolean):cint;
+function intFpExecl (Const PathName:RawByteString;const s:array of RawByteString;MyEnv:ppchar;SearchPath:Boolean):cint;
 { Handles the array of ansistring -> ppchar conversion.
   Base for the the "l" variants.
 }
 var p:ppchar;
-
+    i:integer;
+    s2:array of Rawbytestring;
 begin
   If PathName='' Then
     Begin
       fpsetErrno(ESysEnoEnt);
       Exit(-1);                 // Errno?
     End;
-  p:=ArrayStringToPPchar(s,1);
+  setlength(s2,high(s)+1);
+  for i:=low(s) to high(s) do
+    s2[i]:=ToSingleByteFileSystemEncodedFileName(s[i]);
+  p:=ArrayStringToPPchar(s2,1);
   if p=NIL Then
     Begin
       GetMem(p,2*sizeof(pchar));
@@ -266,44 +273,44 @@ begin
   Freemem(p);
 end;
 
-function FpExecLE (Const PathName:AnsiString;const S:Array Of AnsiString;MyEnv:ppchar):cint;
+function FpExecLE (Const PathName:RawByteString;const S:Array Of RawByteString;MyEnv:ppchar):cint;
 
 Begin
   FpExecLE:=intFPExecl(PathName,s,MyEnv,false);
 End;
 
 
-function FpExecL(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
+function FpExecL(Const PathName:RawByteString;const S:Array Of RawByteString):cint;
 
 Begin
   FpExecL:=intFPExecl(PathName,S,EnvP,false);
 End;
 
-function FpExecLP(Const PathName:AnsiString;const S:Array Of AnsiString):cint;
+function FpExecLP(Const PathName:RawByteString;const S:Array Of RawByteString):cint;
 
 Begin
   FpExecLP:=intFPExecl(PathName,S,EnvP,True);
 End;
 
-function FpExecLPE(Const PathName:AnsiString;const S:Array Of AnsiString;env:ppchar):cint;
+function FpExecLPE(Const PathName:RawByteString;const S:Array Of RawByteString;env:ppchar):cint;
 
 Begin
   FpExecLPE:=intFPExecl(PathName,S,Env,True);
 End;
 
-function FpExecV(Const PathName:AnsiString;args:ppchar):cint;
+function FpExecV(Const PathName:RawByteString;args:ppchar):cint;
 
 Begin
  fpexecV:=intFpExecVEMaybeP (PathName,args,envp,false);
 End;
 
-function FpExecVP(Const PathName:AnsiString;args:ppchar):cint;
+function FpExecVP(Const PathName:RawByteString;args:ppchar):cint;
 
 Begin
  fpexecVP:=intFpExecVEMaybeP (PathName,args,envp,true);
 End;
 
-function FpExecVPE(Const PathName:AnsiString;args,env:ppchar):cint;
+function FpExecVPE(Const PathName:RawByteString;args,env:ppchar):cint;
 
 Begin
  fpexecVPE:=intFpExecVEMaybeP (PathName,args,env,true);
@@ -322,13 +329,16 @@ End;
 {$ifdef FPC_USE_LIBC}
 function xfpsystem(p:pchar):cint; cdecl; external clib name 'system';
 
-Function fpSystem(const Command:AnsiString):cint;
+Function fpSystem(const Command:RawByteString):cint;
+var
+  cmd: RawByteString;
 begin
-  fpsystem:=xfpsystem(pchar(command));
+  cmd:=ToSingleByteFileSystemEncodedFileName(Command);
+  fpsystem:=xfpsystem(pchar(cmd));
 end;
 
 {$else}
-Function fpSystem(const Command:AnsiString):cint;
+Function fpSystem(const Command:RawByteString):cint;
 var
   pid,savedpid   : cint;
   pstat          : cint;
@@ -339,8 +349,10 @@ var
  {$ifndef SHELL_USE_FPEXEC}
    p      : ppchar;
  {$endif}
+  cmd     : RawByteString;
 
 begin { Changes as above }
+  { fpexec* take care of converting the command to the right code page }
   if command='' then exit(1);
   {$ifndef SHELL_USE_FPEXEC}
     p:=CreateShellArgv(command);
@@ -1126,7 +1138,7 @@ end;
                              Utility calls
 ******************************************************************************}
 
-Function FSearch(const path:AnsiString;dirlist:Ansistring;CurrentDirStrategy:TFSearchOption):AnsiString;
+Function FSearch(const path:RawByteString;dirlist:RawByteString;CurrentDirStrategy:TFSearchOption):RawByteString;
 {
   Searches for a file 'path' in the list of direcories in 'dirlist'.
   returns an empty string if not found. Wildcards are NOT allowed.
@@ -1137,17 +1149,18 @@ stringhandling overhead at the same time.
 
 }
 Var
-  mydir,NewDir : ansistring;
+  mypath,
+  mydir,NewDir : RawByteString;
   p1     : cint;
   Info   : Stat;
   i,j      : cint;
   p      : pchar;
 Begin
-
+ SetCodePage(dirlist,DefaultFileSystemCodePage);
  if CurrentDirStrategy=CurrentDirectoryFirst Then
-     Dirlist:='.:'+dirlist;             {Make sure current dir is first to be searched.}
- if CurrentDirStrategy=CurrentDirectoryLast Then
-     Dirlist:=dirlist+':.';             {Make sure current dir is last to be searched.}
+     Dirlist:=ToSingleByteFileSystemEncodedFileName('.:')+dirlist             {Make sure current dir is first to be searched.}
+ else if CurrentDirStrategy=CurrentDirectoryLast Then
+     Dirlist:=dirlist+ToSingleByteFileSystemEncodedFileName('.:');             {Make sure current dir is last to be searched.}
 
 {Replace ':' and ';' with #0}
 
@@ -1160,14 +1173,19 @@ Begin
    FSearch:='' {No wildcards allowed in these things.}
   Else
    Begin
+     mypath:=ToSingleByteFileSystemEncodedFileName(path);
      p:=pchar(dirlist);
      i:=length(dirlist);
      j:=1;
      Repeat
-       mydir:=ansistring(p);
+       mydir:=RawByteString(p);
        if (length(mydir)>0) and (mydir[length(mydir)]<>'/') then
-          mydir:=mydir+'/';
-       NewDir:=mydir+Path;
+          begin
+            { concatenate character without influencing code page }
+            setlength(mydir,length(mydir)+1);
+            mydir[length(mydir)]:='/';
+          end;
+       NewDir:=mydir+mypath;
        if (FpStat(NewDir,Info)>=0) and
           (not fpS_ISDIR(Info.st_Mode)) then
         Begin
@@ -1181,15 +1199,26 @@ Begin
        if p^=#0 then inc(p);
      Until (j>=i) or (Length(NewDir) > 0);
      FSearch:=NewDir;
+     SetCodePage(FSearch,DefaultRTLFileSystemCodePage);
    End;
 End;
 
-Function FSearch(const path:AnsiString;dirlist:Ansistring):AnsiString;
 
+Function FSearch(const path:RawByteString;dirlist:RawByteString):RawByteString;
 Begin
  FSearch:=FSearch(path,dirlist,CurrentDirectoryFirst);
 End;
 
+function FSearch(const path: UnicodeString; dirlist: UnicodeString; CurrentDirStrategy: TFSearchOption): UnicodeString;
+begin
+  FSearch:=FSearch(ToSingleByteFileSystemEncodedFileName(path),ToSingleByteFileSystemEncodedFileName(dirlist),CurrentDirStrategy);
+end;
+
+function FSearch(const path: UnicodeString; dirlist: UnicodeString): UnicodeString;
+begin
+  FSearch:=FSearch(ToSingleByteFileSystemEncodedFileName(path),ToSingleByteFileSystemEncodedFileName(dirlist),CurrentDirectoryFirst);
+end;
+
 Initialization
 {$IFNDEF DONT_READ_TIMEZONE}
   InitLocalTime;

+ 4 - 4
rtl/unix/unixutil.pp

@@ -31,8 +31,8 @@ var
   Tzseconds : Longint;
 
 Function StringToPPChar(S: PChar;ReserveEntries:integer):ppchar;
-Function StringToPPChar(Var S:AnsiString;ReserveEntries:integer):ppchar;
-function ArrayStringToPPchar(const S:Array of AnsiString;reserveentries:Longint):ppchar; // const ?
+Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar;
+function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ?
 Function LocalToEpoch(year,month,day,hour,minute,second:Word):Longint; deprecated 'use DateUtils.DateTimeToUnix';
 Procedure EpochToLocal(epoch:longint;var year,month,day,hour,minute,second:Word); deprecated 'use DateUtils.UnixToDateTime';
 Procedure JulianToGregorian(JulianDN:LongInt;Var Year,Month,Day:Word); deprecated 'use DateUtils.DateTimetoJulianDate';
@@ -40,7 +40,7 @@ Function GregorianToJulian(Year,Month,Day:Longint):LongInt; deprecated 'use Date
 
 implementation
 
-function ArrayStringToPPchar(const S:Array of AnsiString;reserveentries:Longint):ppchar; // const ?
+function ArrayStringToPPchar(const S:Array of RawByteString;reserveentries:Longint):ppchar; // const ?
 // Extra allocate reserveentries pchar's at the beginning (default param=0 after 1.0.x ?)
 // Note: for internal use by skilled programmers only
 // if "s" goes out of scope in the parent procedure, the pointer is dangling.
@@ -64,7 +64,7 @@ begin
   ArrayStringToPPchar:=p;
 end;
 
-Function StringToPPChar(Var S:AnsiString;ReserveEntries:integer):ppchar;
+Function StringToPPChar(Var S:RawByteString;ReserveEntries:integer):ppchar;
 {
   Create a PPChar to structure of pchars which are the arguments specified
   in the string S. Especially useful for creating an ArgV for Exec-calls

+ 31 - 8
rtl/win/sysutils.pp

@@ -1,4 +1,4 @@
-{
+         {
 
     This file is part of the Free Pascal run time library.
     Copyright (c) 1999-2000 by Florian Klaempfl
@@ -1110,14 +1110,20 @@ end;
 
 {$pop}
 
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: RawByteString;Flags:TExecuteFlags=[]):integer;
+begin
+  result:=ExecuteProcess(Unicodestring(Path),UnicodeString(ComLine),Flags);
+end;
+
+
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: UnicodeString;Flags:TExecuteFlags=[]):integer;
 // win specific  function
 var
-  SI: TStartupInfo;
+  SI: TStartupInfoW;
   PI: TProcessInformation;
   Proc : THandle;
   l    : DWord;
-  CommandLine : ansistring;
+  CommandLine : unicodestring;
   e : EOSError;
   ExecInherits : longbool;
 begin
@@ -1140,7 +1146,7 @@ begin
 
   ExecInherits:=ExecInheritsHandles in Flags;
 
-  if not CreateProcessA(nil, pchar(CommandLine),
+  if not CreateProcessW(nil, pwidechar(CommandLine),
     Nil, Nil, ExecInherits,$20, Nil, Nil, SI, PI) then
     begin
       e:=EOSError.CreateFmt(SExecuteProcessFailed,[CommandLine,GetLastError]);
@@ -1165,10 +1171,27 @@ begin
     end;
 end;
 
-function ExecuteProcess(Const Path: AnsiString; Const ComLine: Array of AnsiString;Flags:TExecuteFlags=[]):integer;
+
+function ExecuteProcess(Const Path: RawByteString; Const ComLine: Array of RawByteString;Flags:TExecuteFlags=[]):integer;
+
+var
+  CommandLine: UnicodeString;
+  I: integer;
+
+begin
+  Commandline := '';
+  for I := 0 to High (ComLine) do
+   if Pos (' ', ComLine [I]) <> 0 then
+    CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
+   else
+    CommandLine := CommandLine + ' ' + Comline [I];
+  ExecuteProcess := ExecuteProcess (UnicodeString(Path), CommandLine,Flags);
+end;
+
+function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
 
 var
-  CommandLine: AnsiString;
+  CommandLine: UnicodeString;
   I: integer;
 
 begin
@@ -1178,7 +1201,7 @@ begin
     CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
    else
     CommandLine := CommandLine + ' ' + Comline [I];
-  ExecuteProcess := ExecuteProcess (Path, CommandLine,Flags);
+  ExecuteProcess := ExecuteProcess (Path,CommandLine,Flags);
 end;
 
 Procedure Sleep(Milliseconds : Cardinal);