UnixOperatingSystem.st
changeset 17519 bb0912972d6b
parent 17499 935651e16975
child 17530 267a6722ddfb
--- a/UnixOperatingSystem.st	Fri Feb 20 15:21:31 2015 +0100
+++ b/UnixOperatingSystem.st	Fri Feb 20 15:22:22 2015 +0100
@@ -3398,8 +3398,10 @@
 
     "start executing the OS command as specified by the argument, aCommandString
      as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+     If aCommandString is a String, the commandString is passed to a shell for execution
+     - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+     If aCommandString is an Array, the first element is the command to be executed,
+     and the other elements are the arguments to the command. No shell is invoked in this case.
      The command gets stdIn, stdOut and stdErr assigned from the arguments;
      each may be nil.
      Return the processId if successful, nil otherwise.
@@ -3411,36 +3413,36 @@
     aCommandString isNil ifTrue:[^ nil].
 
     (in := anExternalInStream) isNil ifTrue:[
-	nullStream := Filename nullDevice readWriteStream.
-	in := nullStream.
+        nullStream := Filename nullDevice readWriteStream.
+        in := nullStream.
     ].
     (out := anExternalOutStream) isNil ifTrue:[
-	nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
-	out := nullStream.
+        nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
+        out := nullStream.
     ].
     (err := anExternalErrStream) isNil ifTrue:[
-	err := out
+        err := out
     ].
     anAuxiliaryStream notNil ifTrue:[
-	auxFd := anAuxiliaryStream fileDescriptor
+        auxFd := anAuxiliaryStream fileDescriptor
     ].
 
     shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
 
     rslt := self
-	exec:(shellAndArgs at:1)
-	withArguments:(shellAndArgs at:2)
-	environment:anEvironmentDictionary
-	fileDescriptors:(Array with:in fileDescriptor
-			       with:out fileDescriptor
-			       with:err fileDescriptor
-			       with:auxFd)
-	fork:true
-	newPgrp:true "/ false
-	inDirectory:dir.
+        exec:(shellAndArgs at:1)
+        withArguments:(shellAndArgs at:2)
+        environment:anEvironmentDictionary
+        fileDescriptors:(Array with:in fileDescriptor
+                               with:out fileDescriptor
+                               with:err fileDescriptor
+                               with:auxFd)
+        fork:true
+        newPgrp:true "/ false
+        inDirectory:dir.
 
     nullStream notNil ifTrue:[
-	nullStream close.
+        nullStream close.
     ].
 
     ^ rslt
@@ -3448,6 +3450,7 @@
     "blocking at current prio (i.e. only higher prio threads execute):
 
      OperatingSystem executeCommand:'ls -l > out'.
+     OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
     "
 
     "non-blocking (lower prio threads continue):
@@ -3464,7 +3467,7 @@
      The following will no longer work. monitorPid has disappeared
 
      pid notNil ifTrue:[
-	 Processor monitorPid:pid action:[:OSstatus | sema signal ].
+         Processor monitorPid:pid action:[:OSstatus | sema signal ].
      ].
      in close.
      out close.
@@ -3481,17 +3484,23 @@
 
 !UnixOperatingSystem class methodsFor:'executing OS commands-queries'!
 
-commandAndArgsForOSCommand:aCommandString
-    "get a shell and shell arguments for command execution"
-
-    |shell args|
+commandAndArgsForOSCommand:aCommandStringOrArray
+    "get a shell and shell arguments for command execution.
+     If aCommandString is a String, the commandString is passed to a shell for execution
+     - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+     If aCommandString is an Array, the first element is the command to be executed,
+     and the other elements are the arguments to the command. No shell is invoked in this case."
+
+    aCommandStringOrArray isNonByteCollection ifTrue:[
+        "if an array is passed, the command string has already been parsed an no shell is invoked"
+        ^ Array with:aCommandStringOrArray first with:aCommandStringOrArray.
+    ].
 
     "/
     "/ '/bin/sh -c <command>'
     "/
-    shell := '/bin/sh'.
-    args := Array with:'sh' with:'-c' with:aCommandString.
-    ^ Array with:shell with:args
+
+    ^ Array with:'/bin/sh' with:(Array with:'sh' with:'-c' with:aCommandStringOrArray)
 
     "Modified: / 20.1.1998 / 16:57:19 / md"
     "Modified: / 5.6.1998 / 17:40:48 / cg"
@@ -3903,7 +3912,12 @@
     "copy the directory named 'sourcePathName' and all contained files/directories to 'destination'.
      Return true if successful."
 
-    ^ self executeCommand:('/bin/cp -af ''' , sourcePathName, ''' ''', destination , '''')
+    ^ self executeCommand:(Array with:'/bin/cp' with:'-af' with:sourcePathName with:destination)
+
+    "
+        self recursiveCopyDirectory:'packages' to:'foo'.
+        self recursiveRemoveDirectory:'foo'.
+    "
 
     "Modified: / 5.6.1998 / 18:33:57 / cg"
 !
@@ -3912,7 +3926,7 @@
     "remove the directory named 'fullPathName' and all contained files/directories.
      Return true if successful."
 
-    ^ self executeCommand:('/bin/rm -rf ''' , fullPathName , '''')
+    ^ self executeCommand:(Array with:'/bin/rm' with:'-rf' with:fullPathName)
 
     "
      OperatingSystem recursiveCreateDirectory:'foo/bar/baz'
@@ -13820,11 +13834,11 @@
 !UnixOperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.419 2015-02-18 17:58:04 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.420 2015-02-20 14:22:22 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.419 2015-02-18 17:58:04 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.420 2015-02-20 14:22:22 stefan Exp $'
 ! !