2585 "/ |
2585 "/ |
2586 "/ I know: this is a kludge but should work for now... |
2586 "/ I know: this is a kludge but should work for now... |
2587 "/ ...this will change in an upcoming version to include |
2587 "/ ...this will change in an upcoming version to include |
2588 "/ command.com command-line parsing here (sigh). |
2588 "/ command.com command-line parsing here (sigh). |
2589 |
2589 |
2590 self isMSWINDOWSNTlike ifTrue:[ |
2590 self isMSWINDOWSNTlike ifTrue:[ |
|
2591 shell := self getEnvironment:'COMSPEC'. |
|
2592 shell isNil ifTrue:[ |
|
2593 wDir := self getWindowsSystemDirectory asFilename. |
|
2594 shell := (wDir construct:'cmd.exe'). |
|
2595 shell exists ifFalse:[ |
|
2596 shell := (wDir construct:'command.com'). |
|
2597 shell exists ifFalse:[ |
|
2598 self error:'no command.com available'. |
|
2599 ] |
|
2600 ]. |
|
2601 shell := shell pathName. |
|
2602 ]. |
|
2603 aCommandString isNil ifTrue:[ |
|
2604 ^ Array with:nil with:shell |
|
2605 ]. |
|
2606 ^ Array with:nil with:(shell , ' /c ' , aCommandString) |
|
2607 ]. |
|
2608 |
|
2609 hasRedirection := false. |
|
2610 (aCommandString isNil or:[aCommandString includesAny:'<>|']) ifTrue:[ |
|
2611 hasRedirection := true |
|
2612 ] ifFalse:[ |
|
2613 words := aCommandString asCollectionOfSubstringsSeparatedBy:Character space. |
|
2614 args := ' '. |
|
2615 words from:2 to:(words size) do:[:s | |
|
2616 args := args , (s , ' '). |
|
2617 ]. |
|
2618 ]. |
|
2619 |
|
2620 "/ I/O redirection is not yet handled directly |
|
2621 "/ fallBack to command.com (below) to do it. |
|
2622 |
|
2623 hasRedirection ifFalse:[ |
|
2624 path := self pathOfCommand:(words at:1). |
|
2625 path notNil ifTrue:[ |
|
2626 "/ execute the command directly - |
|
2627 "/ without going through command.com |
|
2628 |
|
2629 self isMSWINDOWSNTlike ifTrue:[ |
|
2630 args := path , args. |
|
2631 ]. |
|
2632 |
|
2633 ^ Array with:path with:args |
|
2634 ]. |
|
2635 ]. |
|
2636 |
|
2637 "/ windows-NT (where command.com works) |
|
2638 "/ or I/O redirection or no executable was found |
|
2639 |
2591 shell := self getEnvironment:'COMSPEC'. |
2640 shell := self getEnvironment:'COMSPEC'. |
2592 shell isNil ifTrue:[ |
2641 shell isNil ifTrue:[ |
2593 wDir := self getWindowsSystemDirectory asFilename. |
2642 wDir := self getWindowsSystemDirectory asFilename. |
2594 shell := (wDir construct:'cmd.exe'). |
2643 shell := (wDir construct:'cmd.exe'). |
2595 shell exists ifFalse:[ |
2644 shell exists ifFalse:[ |
2596 shell := (wDir construct:'command.com'). |
2645 shell := (wDir construct:'command.com'). |
2597 shell exists ifFalse:[ |
2646 shell exists ifFalse:[ |
2598 self error:'no command.com available'. |
2647 self error:'no command.com available'. |
2599 ] |
2648 ] |
2600 ]. |
2649 ]. |
2601 shell := shell pathName. |
2650 shell := shell pathName. |
2602 ]. |
2651 ]. |
2603 aCommandString isNil ifTrue:[ |
2652 aCommandString isNil ifTrue:[ |
2604 ^ Array with:nil with:shell |
2653 ^ Array with:shell with:shell |
2605 ]. |
|
2606 ^ Array with:nil with:(shell , ' /c ' , aCommandString) |
|
2607 ]. |
|
2608 |
|
2609 hasRedirection := false. |
|
2610 (aCommandString isNil or:[aCommandString includesAny:'<>|']) ifTrue:[ |
|
2611 hasRedirection := true |
|
2612 ] ifFalse:[ |
|
2613 words := aCommandString asCollectionOfSubstringsSeparatedBy:Character space. |
|
2614 args := ' '. |
|
2615 words from:2 to:(words size) do:[:s | |
|
2616 args := args , (s , ' '). |
|
2617 ]. |
|
2618 ]. |
|
2619 |
|
2620 "/ I/O redirection is not yet handled directly |
|
2621 "/ fallBack to command.com (below) to do it. |
|
2622 |
|
2623 hasRedirection ifFalse:[ |
|
2624 path := self pathOfCommand:(words at:1). |
|
2625 path notNil ifTrue:[ |
|
2626 "/ execute the command directly - |
|
2627 "/ without going through command.com |
|
2628 |
|
2629 self isMSWINDOWSNTlike ifTrue:[ |
|
2630 args := path , args. |
|
2631 ]. |
|
2632 |
|
2633 ^ Array with:path with:args |
|
2634 ]. |
|
2635 ]. |
|
2636 |
|
2637 "/ windows-NT (where command.com works) |
|
2638 "/ or I/O redirection or no executable was found |
|
2639 |
|
2640 shell := self getEnvironment:'COMSPEC'. |
|
2641 shell isNil ifTrue:[ |
|
2642 wDir := self getWindowsSystemDirectory asFilename. |
|
2643 shell := (wDir construct:'cmd.exe'). |
|
2644 shell exists ifFalse:[ |
|
2645 shell := (wDir construct:'command.com'). |
|
2646 shell exists ifFalse:[ |
|
2647 self error:'no command.com available'. |
|
2648 ] |
|
2649 ]. |
|
2650 shell := shell pathName. |
|
2651 ]. |
|
2652 aCommandString isNil ifTrue:[ |
|
2653 ^ Array with:shell with:shell |
|
2654 ]. |
2654 ]. |
2655 ^ Array with:shell with:(shell , ' /c ' , aCommandString) |
2655 ^ Array with:shell with:(shell , ' /c ' , aCommandString) |
2656 |
2656 |
2657 "Modified: / 20.1.1998 / 16:57:19 / md" |
2657 "Modified: / 20.1.1998 / 16:57:19 / md" |
2658 "Modified: / 19.5.1999 / 10:01:24 / cg" |
2658 "Modified: / 19.5.1999 / 10:01:24 / cg" |
|
2659 ! |
|
2660 |
|
2661 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory |
|
2662 "Internal lowLevel entry for combined fork & exec for WIN32 |
|
2663 |
|
2664 If fork is false (chain a command): |
|
2665 execute the OS command specified by the argument, aCommandPath, with |
|
2666 arguments in argArray (no arguments, if nil). |
|
2667 If successful, this method does not return and smalltalk is gone. |
|
2668 If not successful, it does return. |
|
2669 Normal use is with forkForCommand. |
|
2670 |
|
2671 If fork is true (subprocess command execution): |
|
2672 fork a child to do the above. |
|
2673 The process id of the child process is returned; nil if the fork failed. |
|
2674 |
|
2675 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
|
2676 fdArray[1] = 15 -> use fd 15 as stdin. |
|
2677 If an element of the array is set to nil, the corresponding filedescriptor |
|
2678 will be closed for the child. |
|
2679 fdArray[0] == StdIn for child |
|
2680 fdArray[1] == StdOut for child |
|
2681 fdArray[2] == StdErr for child |
|
2682 on VMS, these must be channels as returned by createMailBox. |
|
2683 |
|
2684 closeFdArray contains descriptors that will be closed in the subprocess. |
|
2685 closeDescriptors are ignored in the WIN32 & VMS versions. |
|
2686 |
|
2687 NOTE that in WIN32 the fds are HANDLES. |
|
2688 |
|
2689 If newPgrp is true, the subprocess will be established in a new process group. |
|
2690 The processgroup will be equal to id. |
|
2691 newPgrp is not used on WIN32 and VMS systems." |
|
2692 |
|
2693 |dirPath cmdPath cmdLine| |
|
2694 |
|
2695 aDirectory notNil ifTrue:[ |
|
2696 dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory. |
|
2697 (dirPath endsWith:':') ifTrue:[ |
|
2698 dirPath := dirPath , '\'. |
|
2699 ]. |
|
2700 ]. |
|
2701 |
|
2702 self isMSWINDOWSNTlike ifTrue:[ |
|
2703 cmdPath := aCommandPath. |
|
2704 cmdLine := argString |
|
2705 ] ifFalse:[ |
|
2706 cmdPath := 'stxspawn.exe'. |
|
2707 cmdLine := 'stxspawn.exe ' , aCommandPath , ' ' , argString |
|
2708 ]. |
|
2709 |
|
2710 ^ self |
|
2711 primExec:cmdPath |
|
2712 commandLine:cmdLine |
|
2713 fileDescriptors:fdArray |
|
2714 closeDescriptors:closeFdArray |
|
2715 fork:doFork |
|
2716 newPgrp:newPgrp |
|
2717 inPath:dirPath |
|
2718 createFlags:nil |
|
2719 |
|
2720 "Modified: / 31.1.1998 / 10:54:24 / md" |
|
2721 "Modified: / 15.5.1999 / 18:07:51 / cg" |
2659 ! |
2722 ! |
2660 |
2723 |
2661 exec:aCommandPath withArguments:argString fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory |
2724 exec:aCommandPath withArguments:argString fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory |
2662 "Internal lowLevel entry for combined fork & exec for WIN32 |
2725 "Internal lowLevel entry for combined fork & exec for WIN32 |
2663 |
2726 |
3014 |ret in out err shellAndArgs errStream outStream inStream| |
3077 |ret in out err shellAndArgs errStream outStream inStream| |
3015 |
3078 |
3016 aCommandString isNil ifTrue:[^ nil]. |
3079 aCommandString isNil ifTrue:[^ nil]. |
3017 |
3080 |
3018 anExternalInStream notNil ifTrue:[ |
3081 anExternalInStream notNil ifTrue:[ |
3019 in := anExternalInStream fileDescriptor. |
3082 in := anExternalInStream fileDescriptor. |
3020 ] ifFalse:[ |
3083 ] ifFalse:[ |
3021 self isMSWINDOWSNTlike ifTrue:[ |
3084 self isMSWINDOWSNTlike ifTrue:[ |
3022 inStream := 'nul' asFilename readStream. |
3085 inStream := 'nul' asFilename readStream. |
3023 inStream notNil ifTrue:[ |
3086 inStream notNil ifTrue:[ |
3024 in := inStream fileDescriptor. |
3087 in := inStream fileDescriptor. |
3025 ] |
3088 ] |
3026 ] |
3089 ] |
3027 ]. |
3090 ]. |
3028 anExternalOutStream notNil ifTrue:[ |
3091 anExternalOutStream notNil ifTrue:[ |
3029 out := anExternalOutStream fileDescriptor. |
3092 out := anExternalOutStream fileDescriptor. |
3030 ] ifFalse:[ |
3093 ] ifFalse:[ |
3031 self isMSWINDOWSNTlike ifTrue:[ |
3094 self isMSWINDOWSNTlike ifTrue:[ |
3032 outStream := 'nul' asFilename writeStream. |
3095 outStream := 'nul' asFilename writeStream. |
3033 outStream notNil ifTrue:[ |
3096 outStream notNil ifTrue:[ |
3034 out := outStream fileDescriptor. |
3097 out := outStream fileDescriptor. |
3035 ] |
3098 ] |
3036 ] |
3099 ] |
3037 ]. |
3100 ]. |
3038 anExternalErrStream notNil ifTrue:[ |
3101 anExternalErrStream notNil ifTrue:[ |
3039 err := anExternalErrStream fileDescriptor. |
3102 err := anExternalErrStream fileDescriptor. |
3040 ] ifFalse:[ |
3103 ] ifFalse:[ |
3041 self isMSWINDOWSNTlike ifTrue:[ |
3104 self isMSWINDOWSNTlike ifTrue:[ |
3042 errStream := 'nul' asFilename writeStream. |
3105 errStream := 'nul' asFilename writeStream. |
3043 errStream notNil ifTrue:[ |
3106 errStream notNil ifTrue:[ |
3044 err := errStream fileDescriptor. |
3107 err := errStream fileDescriptor. |
3045 ] |
3108 ] |
3046 ] |
3109 ] |
3047 ]. |
3110 ]. |
3048 |
3111 |
3049 shellAndArgs := self commandAndArgsForOSCommand:aCommandString. |
3112 shellAndArgs := self commandAndArgsForOSCommand:aCommandString. |
3050 ret := self |
3113 ret := self |
3051 exec:(shellAndArgs at:1) |
3114 exec:(shellAndArgs at:1) |
3052 withArguments:(shellAndArgs at:2) |
3115 withArguments:(shellAndArgs at:2) |
3053 fileDescriptors:(Array with:in with:out with:err) |
3116 environment:nil |
3054 closeDescriptors:nil |
3117 fileDescriptors:(Array with:in with:out with:err) |
3055 fork:true |
3118 closeDescriptors:nil |
3056 newPgrp:false |
3119 fork:true |
3057 inDirectory:dirOrNil. |
3120 newPgrp:false |
|
3121 inDirectory:dirOrNil. |
3058 |
3122 |
3059 inStream notNil ifTrue:[ |
3123 inStream notNil ifTrue:[ |
3060 inStream close |
3124 inStream close |
3061 ]. |
3125 ]. |
3062 outStream notNil ifTrue:[ |
3126 outStream notNil ifTrue:[ |
3063 outStream close |
3127 outStream close |
3064 ]. |
3128 ]. |
3065 errStream notNil ifTrue:[ |
3129 errStream notNil ifTrue:[ |
3066 errStream close |
3130 errStream close |
3067 ]. |
3131 ]. |
3068 ^ ret |
3132 ^ ret |
3069 |
3133 |
3070 "Created: / 10.11.1998 / 20:48:35 / cg" |
3134 "Created: / 10.11.1998 / 20:48:35 / cg" |
3071 "Modified: / 19.5.1999 / 10:43:01 / cg" |
3135 "Modified: / 19.5.1999 / 10:43:01 / cg" |