AbstractOperatingSystem.st
changeset 7110 808437ea66af
parent 7106 27bc6fd8067d
child 7119 75dea3234f70
equal deleted inserted replaced
7109:0c5c8be61083 7110:808437ea66af
   957         errorTo:nil 
   957         errorTo:nil 
   958         inDirectory:aDirectory
   958         inDirectory:aDirectory
   959         onError:aBlock
   959         onError:aBlock
   960 
   960 
   961     "Modified: / 10.11.1998 / 20:54:37 / cg"
   961     "Modified: / 10.11.1998 / 20:54:37 / cg"
       
   962 !
       
   963 
       
   964 executeCommand:aCommandString inputFrom:anInStream outputTo:anOutStream errorTo:anErrStream auxFrom:anAuxStream inDirectory:dirOrNil lineWise:lineWise onError:aBlock 
       
   965     "execute the unix command specified by the argument, aCommandString.
       
   966      The commandString is passed to a shell for execution - see the description of
       
   967      'sh -c' in your UNIX manual.
       
   968      Return true if successful.
       
   969      If not successfull, aBlock is called with an OsProcessStatus
       
   970      (containing the exit status) as argument.
       
   971      The given in, out and err streams may be arbitrary (Smalltalk-) streams;
       
   972      if any is not an external stream (which is required by the command),
       
   973      extra pipes and shuffler processes are created, which stuff the data into
       
   974      those internal stream(s).
       
   975      Nil stream args will execute the command connected to ST/X's standard input, output or
       
   976      error resp. - i.e. usually, i/o will be from/to the terminal"
       
   977 
       
   978     |pid exitStatus sema pIn pOut pErr pAux externalInStream externalOutStream externalErrStream externalAuxStream 
       
   979      shuffledInStream shuffledOutStream shuffledErrStream shuffledAuxStream
       
   980      inputShufflerProcess outputShufflerProcess errorShufflerProcess auxShufflerProcess stopShufflers
       
   981      inStreamToClose outStreamToClose errStreamToClose auxStreamToClose terminateLock|
       
   982 
       
   983     terminateLock := Semaphore forMutualExclusion.
       
   984     ((externalInStream := anInStream) notNil 
       
   985      and:[externalInStream isExternalStream not]) ifTrue:[
       
   986         pIn := ExternalStream makePipe.
       
   987         inStreamToClose := externalInStream := pIn at:1.
       
   988         shuffledInStream := pIn at:2.
       
   989         lineWise ifTrue:[shuffledInStream buffered:false].
       
   990 
       
   991         "/ start a reader process, shuffling data from the given
       
   992         "/ inStream to the pipe (which is connected to the commands input)
       
   993         inputShufflerProcess := [
       
   994                     [
       
   995                         [anInStream atEnd] whileFalse:[
       
   996                             self shuffleFrom:anInStream to:shuffledInStream lineWise:lineWise.
       
   997                             shuffledInStream flush
       
   998                         ]
       
   999                     ] ensure:[
       
  1000                         shuffledInStream close
       
  1001                     ]
       
  1002                 ] forkNamed:'cmd input shuffler'.
       
  1003     ].
       
  1004     ((externalOutStream := anOutStream) notNil 
       
  1005      and:[externalOutStream isExternalStream not]) ifTrue:[
       
  1006         pOut := ExternalStream makePipe.
       
  1007         shuffledOutStream := (pOut at:1).
       
  1008         outStreamToClose := externalOutStream := pOut at:2.
       
  1009         lineWise ifTrue:[shuffledOutStream buffered:false].
       
  1010         outputShufflerProcess := 
       
  1011                     [
       
  1012                         self shuffleAllFrom:shuffledOutStream to:anOutStream lineWise:lineWise lockWith:terminateLock.    
       
  1013                     ] forkNamed:'cmd output shuffler'.
       
  1014     ].
       
  1015     (externalErrStream := anErrStream) notNil ifTrue:[
       
  1016         anErrStream == anOutStream ifTrue:[
       
  1017             externalErrStream := externalOutStream
       
  1018         ] ifFalse:[
       
  1019             anErrStream isExternalStream ifFalse:[
       
  1020                 pErr := ExternalStream makePipe.
       
  1021                 shuffledErrStream := (pErr at:1).
       
  1022                 errStreamToClose := externalErrStream := pErr at:2.
       
  1023 
       
  1024                 lineWise ifTrue:[shuffledErrStream buffered:false].
       
  1025                 errorShufflerProcess := 
       
  1026                         [
       
  1027                             self shuffleAllFrom:shuffledErrStream to:anErrStream lineWise:lineWise lockWith:terminateLock.    
       
  1028                         ] forkNamed:'cmd err-output shuffler'.
       
  1029             ]
       
  1030         ]
       
  1031     ].
       
  1032     ((externalAuxStream := anAuxStream) notNil 
       
  1033      and:[externalAuxStream isExternalStream not]) ifTrue:[
       
  1034         pAux := ExternalStream makePipe.
       
  1035         auxStreamToClose := externalAuxStream := pAux at:1.
       
  1036         shuffledAuxStream := pAux at:2.
       
  1037 
       
  1038         "/ start a reader process, shuffling data from the given
       
  1039         "/ auxStream to the pipe (which is connected to the commands aux)
       
  1040         auxShufflerProcess := [
       
  1041                     [
       
  1042                         [anAuxStream atEnd] whileFalse:[
       
  1043                             self shuffleFrom:anAuxStream to:shuffledAuxStream lineWise:false.
       
  1044                             shuffledAuxStream flush
       
  1045                         ]
       
  1046                     ] ensure:[
       
  1047                         shuffledAuxStream close
       
  1048                     ]
       
  1049                 ] forkNamed:'cmd aux shuffler'.
       
  1050     ].
       
  1051 
       
  1052     sema := Semaphore new name:'OS command wait'.
       
  1053     pid := Processor 
       
  1054                 monitor:[
       
  1055                     self 
       
  1056                         startProcess:aCommandString
       
  1057                         inputFrom:externalInStream
       
  1058                         outputTo:externalOutStream
       
  1059                         errorTo:externalErrStream
       
  1060                         auxFrom:externalAuxStream
       
  1061                         inDirectory:dirOrNil
       
  1062                 ]
       
  1063                 action:[:status | 
       
  1064                     status stillAlive ifFalse:[
       
  1065                         exitStatus := status.
       
  1066                         sema signal.
       
  1067                         self closePid:pid
       
  1068                     ]
       
  1069                 ].
       
  1070 
       
  1071     inStreamToClose notNil ifTrue:[
       
  1072         inStreamToClose close
       
  1073     ].
       
  1074     errStreamToClose notNil ifTrue:[
       
  1075         errStreamToClose close
       
  1076     ].
       
  1077     outStreamToClose notNil ifTrue:[
       
  1078         outStreamToClose close
       
  1079     ].
       
  1080     auxStreamToClose notNil ifTrue:[
       
  1081         auxStreamToClose close
       
  1082     ].
       
  1083 
       
  1084     stopShufflers := [
       
  1085             inputShufflerProcess notNil ifTrue:[
       
  1086                 terminateLock critical:[inputShufflerProcess terminate].
       
  1087                 inputShufflerProcess waitUntilTerminated
       
  1088             ].
       
  1089             auxShufflerProcess notNil ifTrue:[
       
  1090                 terminateLock critical:[auxShufflerProcess terminate].
       
  1091                 auxShufflerProcess waitUntilTerminated
       
  1092             ].
       
  1093             outputShufflerProcess notNil ifTrue:[
       
  1094                 terminateLock critical:[outputShufflerProcess terminate].
       
  1095                 outputShufflerProcess waitUntilTerminated.
       
  1096                 self shuffleRestFrom:shuffledOutStream to:anOutStream lineWise:lineWise.
       
  1097                 shuffledOutStream close.
       
  1098             ].
       
  1099             errorShufflerProcess notNil ifTrue:[
       
  1100                 terminateLock critical:[errorShufflerProcess terminate].
       
  1101                 errorShufflerProcess waitUntilTerminated.
       
  1102                 self shuffleRestFrom:shuffledErrStream to:anErrStream lineWise:lineWise.
       
  1103                 shuffledErrStream close.
       
  1104             ].
       
  1105         ].
       
  1106 
       
  1107     pid notNil ifTrue:[
       
  1108         [
       
  1109             sema wait.
       
  1110         ] ifCurtailed:[
       
  1111             "/ terminate the os-command (and all of its forked commands)
       
  1112             self terminateProcessGroup:pid.
       
  1113             self terminateProcess:pid.
       
  1114             self closePid:pid.
       
  1115             stopShufflers value.    
       
  1116         ]
       
  1117     ] ifFalse:[
       
  1118         exitStatus := self osProcessStatusClass processCreationFailure
       
  1119     ].
       
  1120     stopShufflers value.
       
  1121     exitStatus success ifFalse:[
       
  1122         ^ aBlock value:exitStatus
       
  1123     ].
       
  1124     ^ true
       
  1125 
       
  1126     "
       
  1127         |outStream errStream|
       
  1128 
       
  1129         outStream := '' writeStream.
       
  1130 
       
  1131         OperatingSystem executeCommand:'ls -l'
       
  1132                         inputFrom:'abc' readStream
       
  1133                         outputTo:outStream
       
  1134                         errorTo:nil
       
  1135                         inDirectory:nil
       
  1136                         lineWise:true
       
  1137                         onError:[:exitStatus | ^ false].
       
  1138         outStream contents
       
  1139     "
       
  1140 
       
  1141     "
       
  1142         |outStream errStream|
       
  1143 
       
  1144         outStream := '' writeStream.
       
  1145 
       
  1146         OperatingSystem executeCommand:'gpg -s --batch --no-tty --passphrase-fd 0 /tmp/passwd'
       
  1147                         inputFrom:'bla' readStream
       
  1148                         outputTo:outStream
       
  1149                         errorTo:nil
       
  1150                         inDirectory:nil
       
  1151                         lineWise:true
       
  1152                         onError:[:exitStatus |  false].
       
  1153         outStream contents
       
  1154     "
   962 !
  1155 !
   963 
  1156 
   964 executeCommand:aCommandString inputFrom:anInStream outputTo:anOutStream errorTo:anErrStream inDirectory:dirOrNil lineWise:lineWise onError:aBlock 
  1157 executeCommand:aCommandString inputFrom:anInStream outputTo:anOutStream errorTo:anErrStream inDirectory:dirOrNil lineWise:lineWise onError:aBlock 
   965     "execute the unix command specified by the argument, aCommandString.
  1158     "execute the unix command specified by the argument, aCommandString.
   966      The commandString is passed to a shell for execution - see the description of
  1159      The commandString is passed to a shell for execution - see the description of
  4281 ! !
  4474 ! !
  4282 
  4475 
  4283 !AbstractOperatingSystem class methodsFor:'documentation'!
  4476 !AbstractOperatingSystem class methodsFor:'documentation'!
  4284 
  4477 
  4285 version
  4478 version
  4286     ^ '$Header: /cvs/stx/stx/libbasic/AbstractOperatingSystem.st,v 1.86 2003-03-03 20:09:17 stefan Exp $'
  4479     ^ '$Header: /cvs/stx/stx/libbasic/AbstractOperatingSystem.st,v 1.87 2003-03-04 08:00:26 ca Exp $'
  4287 ! !
  4480 ! !
  4288 
  4481 
  4289 AbstractOperatingSystem initialize!
  4482 AbstractOperatingSystem initialize!