Win32OS.st
changeset 3927 028ca7c70ac9
parent 3902 39c11e93056a
child 3946 bdb1c55980c1
equal deleted inserted replaced
3926:4cc33691696a 3927:028ca7c70ac9
  2394 
  2394 
  2395     "Modified: / 20.1.1998 / 16:57:19 / md"
  2395     "Modified: / 20.1.1998 / 16:57:19 / md"
  2396     "Modified: / 11.9.1998 / 19:03:55 / cg"
  2396     "Modified: / 11.9.1998 / 19:03:55 / cg"
  2397 !
  2397 !
  2398 
  2398 
  2399 exec:aCommandPath withArguments:argArray fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp
  2399 exec:aCommandPath withArguments:argArray fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory
  2400     "Internal lowLevel entry for combined fork & exec;
  2400     "Internal lowLevel entry for combined fork & exec for WIN32
       
  2401 
  2401      If fork is false (chain a command):
  2402      If fork is false (chain a command):
  2402 	 execute the OS command specified by the argument, aCommandPath, with
  2403          execute the OS command specified by the argument, aCommandPath, with
  2403 	 arguments in argArray (no arguments, if nil).
  2404          arguments in argArray (no arguments, if nil).
  2404 	 If successful, this method does not return and smalltalk is gone.
  2405          If successful, this method does not return and smalltalk is gone.
  2405 	 If not successful, it does return.
  2406          If not successful, it does return.
  2406 	 Normal use is with forkForCommand.
  2407          Normal use is with forkForCommand.
  2407 
  2408 
  2408      If fork is true (subprocess command execution):
  2409      If fork is true (subprocess command execution):
  2409 	fork a child to do the above.
  2410         fork a child to do the above.
  2410 	The process id of the child process is returned; nil if the fork failed.
  2411         The process id of the child process is returned; nil if the fork failed.
  2411 
  2412 
  2412      fdArray contains the filedescriptors, to be used for the child (if fork is true).
  2413      fdArray contains the filedescriptors, to be used for the child (if fork is true).
  2413 	fdArray[1] = 15 -> use fd 15 as stdin.
  2414         fdArray[1] = 15 -> use fd 15 as stdin.
  2414 	If an element of the array is set to nil, the corresponding filedescriptor
  2415         If an element of the array is set to nil, the corresponding filedescriptor
  2415 	will be closed for the child.
  2416         will be closed for the child.
  2416 	fdArray[0] == StdIn for child
  2417         fdArray[0] == StdIn for child
  2417 	fdArray[1] == StdOut for child
  2418         fdArray[1] == StdOut for child
  2418 	fdArray[2] == StdErr for child
  2419         fdArray[2] == StdErr for child
  2419 	on VMS, these must be channels as returned by createMailBox.
  2420         on VMS, these must be channels as returned by createMailBox.
  2420 
  2421 
  2421      closeFdArray contains descriptors that will be closed in the subprocess.
  2422      closeFdArray contains descriptors that will be closed in the subprocess.
  2422 	closeDescriptors are ignored in the WIN32 & VMS versions.
  2423         closeDescriptors are ignored in the WIN32 & VMS versions.
  2423 
  2424 
  2424      NOTE that in WIN32 the fds are HANDLES!!
  2425      NOTE that in WIN32 the fds are HANDLES!!
  2425 
  2426 
  2426      If newPgrp is true, the subprocess will be established in a new process group.
  2427      If newPgrp is true, the subprocess will be established in a new process group.
  2427 	The processgroup will be equal to id.
  2428         The processgroup will be equal to id.
  2428 	newPgrp is not used on WIN32 and VMS systems.
  2429         newPgrp is not used on WIN32 and VMS systems."
  2429 
  2430 
  2430      Notice: this used to be two separate ST-methods; however, in order to use
  2431     |path|
  2431 	    vfork on some machines, it had to be merged into one, to avoid write
  2432 
  2432 	    accesses to ST/X memory from the vforked-child.
  2433     aDirectory notNil ifTrue:[
  2433 	    The code below only does read accesses."
  2434         path := aDirectory asFilename asAbsoluteFilename osNameForDirectory.
       
  2435         (path endsWith:':') ifTrue:[
       
  2436             path := path , '\'.
       
  2437         ].
       
  2438     ].
  2434 
  2439 
  2435     ^ self 
  2440     ^ self 
  2436 	exec:aCommandPath 
  2441         primExec:aCommandPath 
  2437 	withArguments:argArray 
  2442         withArguments:argArray 
  2438 	fileDescriptors:fdArray
  2443         fileDescriptors:fdArray 
  2439 	closeDescriptors:closeFdArray 
  2444         closeDescriptors:closeFdArray 
  2440 	fork:doFork 
  2445         fork:doFork 
  2441 	newPgrp:newPgrp 
  2446         newPgrp:newPgrp 
  2442 	inDirectory:nil.
  2447         inPath:path
  2443 !
  2448 
  2444 
  2449     "Modified: / 31.1.1998 / 10:54:24 / md"
  2445 exec:aCommandPath withArguments:argArray fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory
  2450     "Modified: / 10.11.1998 / 20:44:24 / cg"
  2446     "Internal lowLevel entry for combined fork & exec for WIN32"
       
  2447 
       
  2448     |path|
       
  2449     aDirectory isNil ifTrue:[
       
  2450       path := nil.
       
  2451     ] ifFalse:[
       
  2452       path := aDirectory asFilename pathName asFilename osNameForDirectory.
       
  2453       (path endsWith:':') ifTrue:[
       
  2454 	 path := path , '\'.
       
  2455       ].
       
  2456     ].
       
  2457     ^ self 
       
  2458 	primExec:aCommandPath 
       
  2459 	withArguments:argArray 
       
  2460 	fileDescriptors:fdArray 
       
  2461 	closeDescriptors:closeFdArray 
       
  2462 	fork:doFork 
       
  2463 	newPgrp:newPgrp 
       
  2464 	inPath:path
       
  2465 
       
  2466     "Modified: 31.1.1998 / 10:54:24 / md"
       
  2467 !
       
  2468 
       
  2469 executeCommand:aCommandString inDirectory:aDirectory
       
  2470     "much like #executeCommand:, but changes the current directory
       
  2471      for the command. Since this is OS specific, use this instead of
       
  2472      hardwiring any 'cd ..' command strings into your applictions."
       
  2473 
       
  2474      ^ self
       
  2475 	executeCommand:aCommandString
       
  2476 	onError:[:status| false]
       
  2477 	inDirectory:aDirectory
       
  2478 
       
  2479     "
       
  2480      OperatingSystem executeCommand:'tdump date.obj' inDirectory:'c:\winstx\stx\libbasic\objbc'. 
       
  2481      OperatingSystem executeCommand:'xxdir date.obj' inDirectory:'c:\winstx\stx\libbasic\objbc'. 
       
  2482     "
       
  2483 
       
  2484     "Modified: / 20.1.1998 / 17:03:03 / md"
       
  2485     "Modified: / 11.9.1998 / 18:52:36 / cg"
       
  2486 !
       
  2487 
       
  2488 executeCommand:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream onError:aBlock
       
  2489     "execute the unix command specified by the argument, aCommandString.
       
  2490      The commandString is passed to a shell for execution - see the description of
       
  2491      'sh -c' in your UNIX manual.
       
  2492      Return true if successful.
       
  2493      If not successfull, aBlock is called with an OsProcessStatus
       
  2494      (containing the exit status) as argument."
       
  2495 
       
  2496     |pid exitStatus sema|
       
  2497 
       
  2498     sema := Semaphore new name:'Unix command wait'.
       
  2499 
       
  2500     pid := Processor 
       
  2501 		monitor:[
       
  2502 		    self 
       
  2503 			startProcess:aCommandString
       
  2504 			inputFrom:anExternalInStream 
       
  2505 			outputTo:anExternalOutStream 
       
  2506 			errorTo:anExternalErrStream.
       
  2507 		] 
       
  2508 		action:[:status |
       
  2509 		    status stillAlive ifFalse:[
       
  2510 			exitStatus := status.
       
  2511 			self closePid:pid.
       
  2512 			sema signal
       
  2513 		    ].
       
  2514 		].
       
  2515     pid notNil ifTrue:[
       
  2516 	sema wait.
       
  2517     ] ifFalse:[
       
  2518 	exitStatus := OSProcessStatus processCreationFailure.
       
  2519     ].
       
  2520 
       
  2521     exitStatus success ifFalse:[
       
  2522 	^ aBlock value:exitStatus
       
  2523     ].
       
  2524     ^ true.
       
  2525 
       
  2526     "Modified: 25.3.1997 / 11:02:02 / stefan"
       
  2527     "Modified: 19.4.1997 / 18:15:04 / cg"
       
  2528     "Modified: 28.1.1998 / 14:46:36 / md"
       
  2529 !
       
  2530 
       
  2531 executeCommand:aCommandString onError:aBlock
       
  2532     "execute the unix command specified by the argument, aCommandString.
       
  2533      The commandString is passed to a shell for execution - see the description of
       
  2534      'sh -c' in your UNIX manual.
       
  2535      Return true if successful.
       
  2536      If not successfull, aBlock is called with an OsProcessStatus
       
  2537      (containing the exit status) as argument."
       
  2538 
       
  2539     |pid exitStatus sema|
       
  2540 
       
  2541     sema := Semaphore new name:'OS command wait'.
       
  2542 
       
  2543     pid := Processor 
       
  2544 		monitor:[self startProcess:aCommandString] 
       
  2545 		action:[:status |
       
  2546 			status stillAlive ifFalse:[
       
  2547 			    exitStatus := status.
       
  2548 			    self closePid:pid.
       
  2549 			    sema signal
       
  2550 			].
       
  2551 		].
       
  2552     pid notNil ifTrue:[
       
  2553 	sema wait.
       
  2554     ] ifFalse:[
       
  2555 	exitStatus := OSProcessStatus processCreationFailure.
       
  2556     ].
       
  2557 
       
  2558     exitStatus success ifFalse:[
       
  2559 	^ aBlock value:exitStatus
       
  2560     ].
       
  2561     ^ true.
       
  2562 
       
  2563 
       
  2564     "
       
  2565      OperatingSystem executeCommand:'sleep 30' onError:[]. 
       
  2566      OperatingSystem executeCommand:'pwd' onError:[:status|status inspect]. 
       
  2567      OperatingSystem executeCommand:'ls -l' onError:[]. 
       
  2568      OperatingSystem executeCommand:'invalidCommand' onError:[:status| status inspect]. 
       
  2569      OperatingSystem executeCommand:'rm /tmp/foofoofoofoo'onError:[:status | status inspect]. 
       
  2570     "
       
  2571 
       
  2572     "Created: 22.12.1995 / 14:49:59 / stefan"
       
  2573     "Modified: 25.3.1997 / 11:06:43 / stefan"
       
  2574     "Modified: 19.4.1997 / 18:14:41 / cg"
       
  2575     "Modified: 28.1.1998 / 14:46:56 / md"
       
  2576 !
       
  2577 
       
  2578 executeCommand:aCommandString onError:aBlock inDirectory:aDirectory
       
  2579     "execute the unix command specified by the argument, aCommandString.
       
  2580      The commandString is passed to a shell for execution - see the description of
       
  2581      'sh -c' in your UNIX manual.
       
  2582      Return true if successful.
       
  2583      If not successfull, aBlock is called with an OsProcessStatus
       
  2584      (containing the exit status) as argument."
       
  2585 
       
  2586     |pid exitStatus sema|
       
  2587 
       
  2588     sema := Semaphore new name:'OS command wait'.
       
  2589 
       
  2590     pid := Processor
       
  2591 		monitor:[self startProcess:aCommandString inDirectory:aDirectory]
       
  2592 		action:[:status |
       
  2593 			status stillAlive ifFalse:[
       
  2594 			    exitStatus := status.
       
  2595 			    self closePid:pid.
       
  2596 			    sema signal
       
  2597 			].
       
  2598 		].
       
  2599     pid notNil ifTrue:[
       
  2600 	sema wait.
       
  2601     ] ifFalse:[
       
  2602 	exitStatus := OSProcessStatus processCreationFailure.
       
  2603     ].
       
  2604 
       
  2605     exitStatus success ifFalse:[
       
  2606 	^ aBlock value:exitStatus
       
  2607     ].
       
  2608     ^ true.
       
  2609 
       
  2610 
       
  2611     "
       
  2612      OperatingSystem executeCommand:'sleep 30' onError:[]. 
       
  2613      OperatingSystem executeCommand:'pwd' onError:[:status|status inspect]. 
       
  2614      OperatingSystem executeCommand:'ls -l' onError:[]. 
       
  2615      OperatingSystem executeCommand:'invalidCommand' onError:[:status| status inspect]. 
       
  2616      OperatingSystem executeCommand:'rm /tmp/foofoofoofoo'onError:[:status | status inspect]. 
       
  2617     "
       
  2618 
       
  2619     "Created: 28.1.1998 / 14:12:15 / md"
       
  2620 !
  2451 !
  2621 
  2452 
  2622 getStatusOfProcess:aProcessId
  2453 getStatusOfProcess:aProcessId
  2623     "wait for a process to terminate and fetch its exit status.
  2454     "wait for a process to terminate and fetch its exit status.
  2624      This is required to avoid zombie processes."
  2455      This is required to avoid zombie processes."
  2868      or not supported by OS
  2699      or not supported by OS
  2869     "
  2700     "
  2870     ^ self primitiveFailed
  2701     ^ self primitiveFailed
  2871 !
  2702 !
  2872 
  2703 
  2873 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream
  2704 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream inDirectory:dirOrNil
  2874     "start executing the OS command as specified by the argument, aCommandString
  2705     "start executing the OS command as specified by the argument, aCommandString
  2875      as a separate process; do not wait for the command to finish.
  2706      as a separate process; do not wait for the command to finish.
  2876      The commandString is passed to a shell for execution - see the description of
  2707      The commandString is passed to a shell for execution - see the description of
  2877      'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
  2708      'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
  2878      The command gets stdIn, stdOut and stdErr assigned from the arguments;
  2709      The command gets stdIn, stdOut and stdErr assigned from the arguments;
  2882      or #killProcess: to stop it."
  2713      or #killProcess: to stop it."
  2883 
  2714 
  2884     |in out err shellAndArgs|
  2715     |in out err shellAndArgs|
  2885 
  2716 
  2886     anExternalInStream notNil ifTrue:[
  2717     anExternalInStream notNil ifTrue:[
  2887 	in := anExternalInStream fileDescriptor.
  2718         in := anExternalInStream fileDescriptor.
  2888     ].
  2719     ].
  2889     anExternalOutStream notNil ifTrue:[
  2720     anExternalOutStream notNil ifTrue:[
  2890 	out := anExternalOutStream fileDescriptor.
  2721         out := anExternalOutStream fileDescriptor.
  2891     ].
  2722     ].
  2892     anExternalErrStream notNil ifTrue:[
  2723     anExternalErrStream notNil ifTrue:[
  2893 	err := anExternalErrStream fileDescriptor.
  2724         err := anExternalErrStream fileDescriptor.
  2894     ].
  2725     ].
  2895 
  2726 
  2896     shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
  2727     shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
  2897     ^ self
  2728     ^ self
  2898 	exec:(shellAndArgs at:1)
  2729         exec:(shellAndArgs at:1)
  2899 	withArguments:(shellAndArgs at:2)
  2730         withArguments:(shellAndArgs at:2)
  2900 	fileDescriptors:(Array with:in with:out with:err)
  2731         fileDescriptors:(Array with:in with:out with:err)
  2901 	closeDescriptors:nil
  2732         closeDescriptors:nil
  2902 	fork:true
  2733         fork:true
  2903 	newPgrp:false.
  2734         newPgrp:false
  2904 
  2735         inDirectory:dirOrNil
  2905     "blocking at current prio (i.e. only higher prio threads execute):
  2736 
  2906 
  2737     "Modified: / 10.11.1998 / 20:43:12 / cg"
  2907      OperatingSystem executeCommand:'dir'.
  2738     "Created: / 10.11.1998 / 20:48:35 / cg"
  2908     "
       
  2909 
       
  2910     "non-blocking (lower prio threads continue):
       
  2911 
       
  2912      |in out err pid sema|
       
  2913 
       
  2914      in := 'out' asFilename readStream.
       
  2915      out := 'out2' asFilename writeStream.
       
  2916      err := 'err' asFilename writeStream.
       
  2917 
       
  2918      sema := Semaphore new.
       
  2919      pid := OperatingSystem startProcess:'grep drw' inputFrom:in outputTo:out errorTo:err.
       
  2920 
       
  2921      The following will no longer work. monitorPid has disappeared 
       
  2922 
       
  2923      pid notNil ifTrue:[
       
  2924 	 Processor monitorPid:pid action:[:OSstatus | sema signal ].
       
  2925      ].
       
  2926      in close.
       
  2927      out close.
       
  2928      err close.
       
  2929      sema wait.
       
  2930      Transcript showCR:'finished'
       
  2931     "
       
  2932 
       
  2933     "Created: 29.2.1996 / 12:31:29 / cg"
       
  2934     "Modified: 21.3.1997 / 10:04:35 / dq"
       
  2935     "Modified: 2.5.1997 / 12:18:20 / cg"
       
  2936     "Modified: 15.7.1997 / 16:03:51 / stefan"
       
  2937 ! !
  2739 ! !
  2938 
  2740 
  2939 !Win32OperatingSystem class methodsFor:'file access'!
  2741 !Win32OperatingSystem class methodsFor:'file access'!
  2940 
  2742 
  2941 closeFd:anInteger
  2743 closeFd:anInteger
  6849 ! !
  6651 ! !
  6850 
  6652 
  6851 !Win32OperatingSystem class methodsFor:'documentation'!
  6653 !Win32OperatingSystem class methodsFor:'documentation'!
  6852 
  6654 
  6853 version
  6655 version
  6854     ^ '$Header: /cvs/stx/stx/libbasic/Attic/Win32OS.st,v 1.34 1998-10-29 12:27:26 cg Exp $'
  6656     ^ '$Header: /cvs/stx/stx/libbasic/Attic/Win32OS.st,v 1.35 1998-11-11 15:09:11 cg Exp $'
  6855 ! !
  6657 ! !
  6856 Win32OperatingSystem initialize!
  6658 Win32OperatingSystem initialize!