1 " |
1 " |
2 COPYRIGHT (c) 1988 by Claus Gittinger |
2 COPYRIGHT (c) 1988 by Claus Gittinger |
3 All Rights Reserved |
3 All Rights Reserved |
4 |
4 |
5 This software is furnished under a license and may be used |
5 This software is furnished under a license and may be used |
6 only in accordance with the terms of that license and with the |
6 only in accordance with the terms of that license and with the |
7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
12 |
13 Object subclass:#AbstractOperatingSystem |
13 Object subclass:#AbstractOperatingSystem |
14 instanceVariableNames:'' |
14 instanceVariableNames:'' |
15 classVariableNames:'ConcreteClass LastErrorNumber LocaleInfo OSSignals PipeFailed |
15 classVariableNames:'ConcreteClass LastErrorNumber LocaleInfo OSSignals PipeFailed |
16 ErrorSignal AccessDeniedErrorSignal FileNotFoundErrorSignal |
16 ErrorSignal AccessDeniedErrorSignal FileNotFoundErrorSignal |
17 InvalidArgumentsSignal UnsupportedOperationSignal' |
17 InvalidArgumentsSignal UnsupportedOperationSignal' |
18 poolDictionaries:'' |
18 poolDictionaries:'' |
19 category:'System-Support' |
19 category:'System-Support' |
20 ! |
20 ! |
21 |
21 |
22 !AbstractOperatingSystem class methodsFor:'documentation'! |
22 !AbstractOperatingSystem class methodsFor:'documentation'! |
23 |
23 |
24 copyright |
24 copyright |
25 " |
25 " |
26 COPYRIGHT (c) 1988 by Claus Gittinger |
26 COPYRIGHT (c) 1988 by Claus Gittinger |
27 All Rights Reserved |
27 All Rights Reserved |
28 |
28 |
29 This software is furnished under a license and may be used |
29 This software is furnished under a license and may be used |
30 only in accordance with the terms of that license and with the |
30 only in accordance with the terms of that license and with the |
31 inclusion of the above copyright notice. This software may not |
31 inclusion of the above copyright notice. This software may not |
32 be provided or otherwise made available to, or used by, any |
32 be provided or otherwise made available to, or used by, any |
41 typically, services which can be implemented based upon more primitive |
41 typically, services which can be implemented based upon more primitive |
42 functions, or which can be implemented in a portable way (but probably |
42 functions, or which can be implemented in a portable way (but probably |
43 less performant) are implemented here. |
43 less performant) are implemented here. |
44 |
44 |
45 [Class variables:] |
45 [Class variables:] |
46 ConcreteClass <Class> the real OS class |
46 ConcreteClass <Class> the real OS class |
47 |
47 |
48 LocaleInfo <Dictionary> if non nil, that is taken instead of the operating |
48 LocaleInfo <Dictionary> if non nil, that is taken instead of the operating |
49 systems locale definitions (allows for overwriting |
49 systems locale definitions (allows for overwriting |
50 these, or provide a compatible info on systems which do |
50 these, or provide a compatible info on systems which do |
51 not support locales) |
51 not support locales) |
52 |
52 |
53 LastErrorNumber <Integer> the last value of errno |
53 LastErrorNumber <Integer> the last value of errno |
54 |
54 |
55 OSSignals <Array> Array of signals to be raised for corresponding |
55 OSSignals <Array> Array of signals to be raised for corresponding |
56 OperatingSystem signals. |
56 OperatingSystem signals. |
57 |
57 |
58 PipeFailed <Boolean> set if a fork (or popen) has failed; |
58 PipeFailed <Boolean> set if a fork (or popen) has failed; |
59 ST/X will avoid doing more forks/popens |
59 ST/X will avoid doing more forks/popens |
60 if this flag is set, for a slightly |
60 if this flag is set, for a slightly |
61 smoother operation. |
61 smoother operation. |
62 |
62 |
63 ErrorSignal <Signal> Parentsignal of all OS error signals. |
63 ErrorSignal <Signal> Parentsignal of all OS error signals. |
64 not directly raised. |
64 not directly raised. |
65 |
65 |
66 AccessDeniedErrorSignal misc concrete error reporting signals |
66 AccessDeniedErrorSignal misc concrete error reporting signals |
67 FileNotFoundErrorSignal |
67 FileNotFoundErrorSignal |
68 UnsupportedOperationSignal |
68 UnsupportedOperationSignal |
69 InvalidArgumentsSignal |
69 InvalidArgumentsSignal |
70 |
70 |
71 [author:] |
71 [author:] |
72 Claus Gittinger |
72 Claus Gittinger |
73 |
73 |
74 [see also:] |
74 [see also:] |
75 OSProcessStatus |
75 OSProcessStatus |
76 Filename Date Time |
76 Filename Date Time |
77 ExternalStream FileStream PipeStream Socket |
77 ExternalStream FileStream PipeStream Socket |
78 " |
78 " |
79 ! |
79 ! |
80 |
80 |
81 examples |
81 examples |
82 " |
82 " |
83 various queries |
83 various queries |
84 [exBegin] |
84 [exBegin] |
85 Transcript |
85 Transcript |
86 showCR:'hello ' , (OperatingSystem getLoginName) |
86 showCR:'hello ' , (OperatingSystem getLoginName) |
87 [exEnd] |
87 [exEnd] |
88 |
88 |
89 [exBegin] |
89 [exBegin] |
90 OperatingSystem isUNIXlike ifTrue:[ |
90 OperatingSystem isUNIXlike ifTrue:[ |
91 Transcript showCR:'this is some UNIX-like OS' |
91 Transcript showCR:'this is some UNIX-like OS' |
92 ] ifFalse:[ |
92 ] ifFalse:[ |
93 Transcript showCR:'this OS is not UNIX-like' |
93 Transcript showCR:'this OS is not UNIX-like' |
94 ] |
94 ] |
95 [exEnd] |
95 [exEnd] |
96 |
96 |
97 [exBegin] |
97 [exBegin] |
98 Transcript |
98 Transcript |
99 showCR:'this machine is called ' , OperatingSystem getHostName |
99 showCR:'this machine is called ' , OperatingSystem getHostName |
100 [exEnd] |
100 [exEnd] |
101 |
101 |
102 [exBegin] |
102 [exBegin] |
103 Transcript |
103 Transcript |
104 showCR:('this machine is in the ' |
104 showCR:('this machine is in the ' |
105 , OperatingSystem getDomainName |
105 , OperatingSystem getDomainName |
106 , ' domain') |
106 , ' domain') |
107 [exEnd] |
107 [exEnd] |
108 |
108 |
109 [exBegin] |
109 [exBegin] |
110 Transcript |
110 Transcript |
111 showCR:('this machine''s CPU is a ' |
111 showCR:('this machine''s CPU is a ' |
112 , OperatingSystem getCPUType |
112 , OperatingSystem getCPUType |
113 ) |
113 ) |
114 [exEnd] |
114 [exEnd] |
115 |
115 |
116 [exBegin] |
116 [exBegin] |
117 Transcript showCR:'executing ls command ...'. |
117 Transcript showCR:'executing ls command ...'. |
118 OperatingSystem executeCommand:'ls'. |
118 OperatingSystem executeCommand:'ls'. |
119 Transcript showCR:'... done.'. |
119 Transcript showCR:'... done.'. |
120 [exEnd] |
120 [exEnd] |
121 |
121 |
122 locking a file |
122 locking a file |
123 (should be executed on two running smalltalks - not in two threads): |
123 (should be executed on two running smalltalks - not in two threads): |
124 [exBegin] |
124 [exBegin] |
125 |f| |
125 |f| |
126 |
126 |
127 f := 'testFile' asFilename readWriteStream. |
127 f := 'testFile' asFilename readWriteStream. |
128 |
128 |
129 10 timesRepeat:[ |
129 10 timesRepeat:[ |
130 'about to lock ...' printCR. |
130 'about to lock ...' printCR. |
131 [ |
131 [ |
132 OperatingSystem |
132 OperatingSystem |
133 lockFD:(f fileDescriptor) |
133 lockFD:(f fileDescriptor) |
134 shared:false |
134 shared:false |
135 blocking:false |
135 blocking:false |
136 ] whileFalse:[ |
136 ] whileFalse:[ |
137 'process ' print. OperatingSystem getProcessId print. ' is waiting' printCR. |
137 'process ' print. OperatingSystem getProcessId print. ' is waiting' printCR. |
138 Delay waitForSeconds:1 |
138 Delay waitForSeconds:1 |
139 ]. |
139 ]. |
140 'LOCKED ...' printCR. |
140 'LOCKED ...' printCR. |
141 Delay waitForSeconds:10. |
141 Delay waitForSeconds:10. |
142 'unlock ...' printCR. |
142 'unlock ...' printCR. |
143 (OperatingSystem |
143 (OperatingSystem |
144 unlockFD:(f fileDescriptor)) printCR. |
144 unlockFD:(f fileDescriptor)) printCR. |
145 Delay waitForSeconds:3. |
145 Delay waitForSeconds:3. |
146 ] |
146 ] |
147 [exBegin] |
147 [exBegin] |
148 " |
148 " |
149 ! ! |
149 ! ! |
150 |
150 |
151 !AbstractOperatingSystem class methodsFor:'initialization'! |
151 !AbstractOperatingSystem class methodsFor:'initialization'! |
152 |
152 |
154 "initialize the class" |
154 "initialize the class" |
155 |
155 |
156 self initializeConcreteClass. |
156 self initializeConcreteClass. |
157 |
157 |
158 ErrorSignal isNil ifTrue:[ |
158 ErrorSignal isNil ifTrue:[ |
159 ErrorSignal := Object errorSignal newSignalMayProceed:true. |
159 ErrorSignal := Object errorSignal newSignalMayProceed:true. |
160 ErrorSignal nameClass:self message:#errorSignal. |
160 ErrorSignal nameClass:self message:#errorSignal. |
161 ErrorSignal notifierString:'OS error encountered'. |
161 ErrorSignal notifierString:'OS error encountered'. |
162 |
162 |
163 AccessDeniedErrorSignal := ErrorSignal newSignalMayProceed:true. |
163 AccessDeniedErrorSignal := ErrorSignal newSignalMayProceed:true. |
164 AccessDeniedErrorSignal nameClass:self message:#accessDeniedError. |
164 AccessDeniedErrorSignal nameClass:self message:#accessDeniedError. |
165 AccessDeniedErrorSignal notifierString:'OS access denied'. |
165 AccessDeniedErrorSignal notifierString:'OS access denied'. |
166 |
166 |
167 FileNotFoundErrorSignal := ErrorSignal newSignalMayProceed:true. |
167 FileNotFoundErrorSignal := ErrorSignal newSignalMayProceed:true. |
168 FileNotFoundErrorSignal nameClass:self message:#fileNotFoundErrorSignal. |
168 FileNotFoundErrorSignal nameClass:self message:#fileNotFoundErrorSignal. |
169 FileNotFoundErrorSignal notifierString:'OS file not found'. |
169 FileNotFoundErrorSignal notifierString:'OS file not found'. |
170 |
170 |
171 InvalidArgumentsSignal := ErrorSignal newSignalMayProceed:true. |
171 InvalidArgumentsSignal := ErrorSignal newSignalMayProceed:true. |
172 InvalidArgumentsSignal nameClass:self message:#invalidArgumentsSignal. |
172 InvalidArgumentsSignal nameClass:self message:#invalidArgumentsSignal. |
173 InvalidArgumentsSignal notifierString:'bad arg to OS call'. |
173 InvalidArgumentsSignal notifierString:'bad arg to OS call'. |
174 |
174 |
175 UnsupportedOperationSignal := ErrorSignal newSignalMayProceed:true. |
175 UnsupportedOperationSignal := ErrorSignal newSignalMayProceed:true. |
176 UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal. |
176 UnsupportedOperationSignal nameClass:self message:#unsupportedOperationSignal. |
177 UnsupportedOperationSignal notifierString:'operation not supported by this OS'. |
177 UnsupportedOperationSignal notifierString:'operation not supported by this OS'. |
178 ] |
178 ] |
179 |
179 |
180 "Modified: / 19.5.1999 / 14:21:28 / cg" |
180 "Modified: / 19.5.1999 / 14:21:28 / cg" |
181 ! |
181 ! |
182 |
182 |
183 initializeConcreteClass |
183 initializeConcreteClass |
184 |osType cls| |
184 |osType cls| |
185 |
185 |
186 osType := self getSystemType. |
186 osType := self getSystemType. |
187 osType = 'win32' ifTrue:[ |
187 osType = 'win32' ifTrue:[ |
188 cls := Win32OperatingSystem |
188 cls := Win32OperatingSystem |
189 ] ifFalse:[ |
189 ] ifFalse:[ |
190 osType = 'os2' ifTrue:[ |
190 osType = 'os2' ifTrue:[ |
191 cls := OS2OperatingSystem |
191 cls := OS2OperatingSystem |
192 ] ifFalse:[ |
192 ] ifFalse:[ |
193 osType = 'macos' ifTrue:[ |
193 osType = 'macos' ifTrue:[ |
194 cls := MacOperatingSystem |
194 cls := MacOperatingSystem |
195 ] ifFalse:[ |
195 ] ifFalse:[ |
196 ((osType = 'VMS') or:[osType = 'openVMS']) ifTrue:[ |
196 ((osType = 'VMS') or:[osType = 'openVMS']) ifTrue:[ |
197 cls := OpenVMSOperatingSystem |
197 cls := OpenVMSOperatingSystem |
198 ] ifFalse:[ |
198 ] ifFalse:[ |
199 cls := UnixOperatingSystem |
199 cls := UnixOperatingSystem |
200 ] |
200 ] |
201 ] |
201 ] |
202 ] |
202 ] |
203 ]. |
203 ]. |
204 OperatingSystem := ConcreteClass := cls. |
204 OperatingSystem := ConcreteClass := cls. |
205 ! ! |
205 ! ! |
206 |
206 |
207 !AbstractOperatingSystem class methodsFor:'OS signal constants'! |
207 !AbstractOperatingSystem class methodsFor:'OS signal constants'! |
704 If successful, this method does NOT return and smalltalk is gone. |
704 If successful, this method does NOT return and smalltalk is gone. |
705 If not successful, it does return. |
705 If not successful, it does return. |
706 Can be used on UNIX with fork or on other systems to chain to another program." |
706 Can be used on UNIX with fork or on other systems to chain to another program." |
707 |
707 |
708 ^ self |
708 ^ self |
709 exec:aCommandPath |
709 exec:aCommandPath |
710 withArguments:argArray |
710 withArguments:argArray |
711 environment:nil |
711 environment:nil |
712 fileDescriptors:nil |
712 fileDescriptors:nil |
713 closeDescriptors:nil |
713 closeDescriptors:nil |
714 fork:false |
714 fork:false |
715 newPgrp:false |
715 newPgrp:false |
716 inDirectory:nil |
716 inDirectory:nil |
717 |
717 |
718 "/ never reached ... |
718 "/ never reached ... |
719 |
719 |
720 "Modified: / 12.11.1998 / 14:44:26 / cg" |
720 "Modified: / 12.11.1998 / 14:44:26 / cg" |
721 ! |
721 ! |
722 |
722 |
723 exec:aCommandPath withArguments:argColl environment:env fileDescriptors:fdColl closeDescriptors:closeFdColl fork:doFork newPgrp:newPgrp |
723 exec:aCommandPath withArguments:argColl environment:env fileDescriptors:fdColl closeDescriptors:closeFdColl fork:doFork newPgrp:newPgrp |
724 "Internal lowLevel entry for combined fork & exec; |
724 "Internal lowLevel entry for combined fork & exec; |
725 |
725 |
726 If fork is false (chain a command): |
726 If fork is false (chain a command): |
727 execute the OS command specified by the argument, aCommandPath, with |
727 execute the OS command specified by the argument, aCommandPath, with |
728 arguments in argArray (no arguments, if nil). |
728 arguments in argArray (no arguments, if nil). |
729 If successful, this method does not return and smalltalk is gone. |
729 If successful, this method does not return and smalltalk is gone. |
730 If not successful, it does return. |
730 If not successful, it does return. |
731 Normal use is with forkForCommand. |
731 Normal use is with forkForCommand. |
732 |
732 |
733 If fork is true (subprocess command execution): |
733 If fork is true (subprocess command execution): |
734 fork a child to do the above. |
734 fork a child to do the above. |
735 The process id of the child process is returned; nil if the fork failed. |
735 The process id of the child process is returned; nil if the fork failed. |
736 |
736 |
737 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
737 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
738 fdArray[1] = 15 -> use fd 15 as stdin. |
738 fdArray[1] = 15 -> use fd 15 as stdin. |
739 If an element of the array is set to nil, the corresponding filedescriptor |
739 If an element of the array is set to nil, the corresponding filedescriptor |
740 will be closed for the child. |
740 will be closed for the child. |
741 fdArray[0] == StdIn for child |
741 fdArray[0] == StdIn for child |
742 fdArray[1] == StdOut for child |
742 fdArray[1] == StdOut for child |
743 fdArray[2] == StdErr for child |
743 fdArray[2] == StdErr for child |
744 on VMS, these must be channels as returned by createMailBox. |
744 on VMS, these must be channels as returned by createMailBox. |
745 |
745 |
746 closeFdArray contains descriptors that will be closed in the subprocess. |
746 closeFdArray contains descriptors that will be closed in the subprocess. |
747 closeDescriptors are ignored in the WIN32 & VMS versions. |
747 closeDescriptors are ignored in the WIN32 & VMS versions. |
748 |
748 |
749 If newPgrp is true, the subprocess will be established in a new process group. |
749 If newPgrp is true, the subprocess will be established in a new process group. |
750 The processgroup will be equal to id. |
750 The processgroup will be equal to id. |
751 newPgrp is not used on WIN32 and VMS systems. |
751 newPgrp is not used on WIN32 and VMS systems. |
752 |
752 |
753 env specifies environment variables which are passed differently from |
753 env specifies environment variables which are passed differently from |
754 the current environment. If non-nil, it must be a dictionary providing |
754 the current environment. If non-nil, it must be a dictionary providing |
755 key-value pairs for changed/added environment variables. |
755 key-value pairs for changed/added environment variables. |
756 To pass a variable as empty (i.e. unset), pass a nil value. |
756 To pass a variable as empty (i.e. unset), pass a nil value. |
757 |
757 |
758 Notice: this used to be two separate ST-methods; however, in order to use |
758 Notice: this used to be two separate ST-methods; however, in order to use |
759 vfork on some machines, it had to be merged into one, to avoid write |
759 vfork on some machines, it had to be merged into one, to avoid write |
760 accesses to ST/X memory from the vforked-child. |
760 accesses to ST/X memory from the vforked-child. |
761 The code below only does read accesses." |
761 The code below only does read accesses." |
762 |
762 |
763 ^ self |
763 ^ self |
764 exec:aCommandPath |
764 exec:aCommandPath |
765 withArguments:argColl |
765 withArguments:argColl |
766 environment:env |
766 environment:env |
767 fileDescriptors:fdColl |
767 fileDescriptors:fdColl |
768 closeDescriptors:closeFdColl |
768 closeDescriptors:closeFdColl |
769 fork:doFork |
769 fork:doFork |
770 newPgrp:newPgrp |
770 newPgrp:newPgrp |
771 inDirectory:nil |
771 inDirectory:nil |
772 |
772 |
773 " |
773 " |
774 |id| |
774 |id| |
775 |
775 |
776 id := OperatingSystem fork. |
776 id := OperatingSystem fork. |
777 id == 0 ifTrue:[ |
777 id == 0 ifTrue:[ |
778 'I am the child'. |
778 'I am the child'. |
779 OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp'). |
779 OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp'). |
780 'not reached'. |
780 'not reached'. |
781 ] |
781 ] |
782 " |
782 " |
783 " |
783 " |
784 |id| |
784 |id| |
785 |
785 |
786 id := OperatingSystem fork. |
786 id := OperatingSystem fork. |
787 id == 0 ifTrue:[ |
787 id == 0 ifTrue:[ |
788 'I am the child'. |
788 'I am the child'. |
789 OperatingSystem |
789 OperatingSystem |
790 exec:'/bin/sh' |
790 exec:'/bin/sh' |
791 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2'). |
791 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2'). |
792 'not reached'. |
792 'not reached'. |
793 ]. |
793 ]. |
794 id printNL. |
794 id printNL. |
795 (Delay forSeconds:3.5) wait. |
795 (Delay forSeconds:3.5) wait. |
796 'killing ...' printNL. |
796 'killing ...' printNL. |
797 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
797 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
811 ! |
811 ! |
812 |
812 |
813 exec:aCommandPath withArguments:argArray fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp |
813 exec:aCommandPath withArguments:argArray fileDescriptors:fdArray closeDescriptors:closeFdArray fork:doFork newPgrp:newPgrp |
814 "combined fork & exec; |
814 "combined fork & exec; |
815 If fork is false (chain a command): |
815 If fork is false (chain a command): |
816 execute the OS command specified by the argument, aCommandPath, with |
816 execute the OS command specified by the argument, aCommandPath, with |
817 arguments in argArray (no arguments, if nil). |
817 arguments in argArray (no arguments, if nil). |
818 If successful, this method does not return and smalltalk is gone. |
818 If successful, this method does not return and smalltalk is gone. |
819 If not successful, it does return. |
819 If not successful, it does return. |
820 Normal use is with forkForCommand. |
820 Normal use is with forkForCommand. |
821 |
821 |
822 If fork is true (subprocess command execution): |
822 If fork is true (subprocess command execution): |
823 fork a child to do the above. |
823 fork a child to do the above. |
824 The process id of the child process is returned; nil if the fork failed. |
824 The process id of the child process is returned; nil if the fork failed. |
825 |
825 |
826 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
826 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
827 fdArray[1] = 15 -> use fd 15 as stdin. |
827 fdArray[1] = 15 -> use fd 15 as stdin. |
828 If an element of the array is set to nil, the corresponding filedescriptor |
828 If an element of the array is set to nil, the corresponding filedescriptor |
829 will be closed for the child. |
829 will be closed for the child. |
830 fdArray[0] == StdIn for child |
830 fdArray[0] == StdIn for child |
831 fdArray[1] == StdOut for child |
831 fdArray[1] == StdOut for child |
832 fdArray[2] == StdErr for child |
832 fdArray[2] == StdErr for child |
833 on VMS, these must be channels as returned by createMailBox. |
833 on VMS, these must be channels as returned by createMailBox. |
834 |
834 |
835 closeFdArray contains descriptors that will be closed in the subprocess. |
835 closeFdArray contains descriptors that will be closed in the subprocess. |
836 closeDescriptors are ignored in the WIN32 & VMS versions. |
836 closeDescriptors are ignored in the WIN32 & VMS versions. |
837 |
837 |
838 NOTE that in WIN32 the fds are HANDLES!! |
838 NOTE that in WIN32 the fds are HANDLES!! |
839 |
839 |
840 If newPgrp is true, the subprocess will be established in a new process group. |
840 If newPgrp is true, the subprocess will be established in a new process group. |
841 The processgroup will be equal to id. |
841 The processgroup will be equal to id. |
842 newPgrp is not used on WIN32 and VMS systems. |
842 newPgrp is not used on WIN32 and VMS systems. |
843 |
843 |
844 Notice: this used to be two separate ST-methods; however, in order to use |
844 Notice: this used to be two separate ST-methods; however, in order to use |
845 vfork on some machines, it had to be merged into one, to avoid write |
845 vfork on some machines, it had to be merged into one, to avoid write |
846 accesses to ST/X memory from the vforked-child. |
846 accesses to ST/X memory from the vforked-child. |
847 The code below only does read accesses." |
847 The code below only does read accesses." |
848 |
848 |
849 ^ self |
849 ^ self |
850 exec:aCommandPath |
850 exec:aCommandPath |
851 withArguments:argArray |
851 withArguments:argArray |
852 environment:nil |
852 environment:nil |
853 fileDescriptors:fdArray |
853 fileDescriptors:fdArray |
854 closeDescriptors:closeFdArray |
854 closeDescriptors:closeFdArray |
855 fork:doFork |
855 fork:doFork |
856 newPgrp:newPgrp |
856 newPgrp:newPgrp |
857 inDirectory:nil |
857 inDirectory:nil |
858 |
858 |
859 " |
859 " |
860 |id| |
860 |id| |
861 |
861 |
862 id := OperatingSystem fork. |
862 id := OperatingSystem fork. |
863 id == 0 ifTrue:[ |
863 id == 0 ifTrue:[ |
864 'I am the child'. |
864 'I am the child'. |
865 OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp'). |
865 OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp'). |
866 'not reached'. |
866 'not reached'. |
867 ] |
867 ] |
868 " |
868 " |
869 " |
869 " |
870 |id| |
870 |id| |
871 |
871 |
872 id := OperatingSystem fork. |
872 id := OperatingSystem fork. |
873 id == 0 ifTrue:[ |
873 id == 0 ifTrue:[ |
874 'I am the child'. |
874 'I am the child'. |
875 OperatingSystem |
875 OperatingSystem |
876 exec:'/bin/sh' |
876 exec:'/bin/sh' |
877 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2'). |
877 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2'). |
878 'not reached'. |
878 'not reached'. |
879 ]. |
879 ]. |
880 id printNL. |
880 id printNL. |
881 (Delay forSeconds:3.5) wait. |
881 (Delay forSeconds:3.5) wait. |
882 'killing ...' printNL. |
882 'killing ...' printNL. |
883 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
883 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
964 The command reads its input and writes its output |
964 The command reads its input and writes its output |
965 from/to whatever terminal device ST/X was started |
965 from/to whatever terminal device ST/X was started |
966 (typically, the xterm window)" |
966 (typically, the xterm window)" |
967 |
967 |
968 ^ self |
968 ^ self |
969 exec:aCommandPath |
969 exec:aCommandPath |
970 withArguments:argArray |
970 withArguments:argArray |
971 environment:nil |
971 environment:nil |
972 fileDescriptors:nil |
972 fileDescriptors:nil |
973 closeDescriptors:nil |
973 closeDescriptors:nil |
974 fork:doFork |
974 fork:doFork |
975 newPgrp:false |
975 newPgrp:false |
976 inDirectory:aDirectory |
976 inDirectory:aDirectory |
977 |
977 |
978 " |
978 " |
979 |id| |
979 |id| |
980 |
980 |
981 id := OperatingSystem fork. |
981 id := OperatingSystem fork. |
982 id == 0 ifTrue:[ |
982 id == 0 ifTrue:[ |
983 'I am the child'. |
983 'I am the child'. |
984 OperatingSystem |
984 OperatingSystem |
985 exec:'/bin/ls' |
985 exec:'/bin/ls' |
986 withArguments:#('ls' '/tmp') |
986 withArguments:#('ls' '/tmp') |
987 fork:false. |
987 fork:false. |
988 'not reached'. |
988 'not reached'. |
989 ] |
989 ] |
990 " |
990 " |
991 |
991 |
992 " |
992 " |
993 |id| |
993 |id| |
994 |
994 |
995 id := OperatingSystem fork. |
995 id := OperatingSystem fork. |
996 id == 0 ifTrue:[ |
996 id == 0 ifTrue:[ |
997 'I am the child'. |
997 'I am the child'. |
998 OperatingSystem |
998 OperatingSystem |
999 exec:'/bin/sh' |
999 exec:'/bin/sh' |
1000 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2') |
1000 withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2') |
1001 fork:false. |
1001 fork:false. |
1002 'not reached'. |
1002 'not reached'. |
1003 ]. |
1003 ]. |
1004 id printNL. |
1004 id printNL. |
1005 (Delay forSeconds:3.5) wait. |
1005 (Delay forSeconds:3.5) wait. |
1006 'killing ...' printNL. |
1006 'killing ...' printNL. |
1007 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
1007 OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id. |
2037 |
2055 |
2038 infoOf:aPathName |
2056 infoOf:aPathName |
2039 "return some object filled with info for the file 'aPathName'; |
2057 "return some object filled with info for the file 'aPathName'; |
2040 the info (for which corresponding access methods are understood by |
2058 the info (for which corresponding access methods are understood by |
2041 the returned object) is: |
2059 the returned object) is: |
2042 type - a symbol giving the files type |
2060 type - a symbol giving the files type |
2043 mode - numeric access mode |
2061 mode - numeric access mode |
2044 uid - owners user id |
2062 uid - owners user id |
2045 gid - owners group id |
2063 gid - owners group id |
2046 size - files size |
2064 size - files size |
2047 id - files number (i.e. inode number) |
2065 id - files number (i.e. inode number) |
2048 accessed - last access time (as Timestamp) |
2066 accessed - last access time (as Timestamp) |
2049 modified - last modification time (as Timestamp) |
2067 modified - last modification time (as Timestamp) |
2050 statusChanged - last status change time (as Timestamp) |
2068 statusChanged - last status change time (as Timestamp) |
2051 alternativeName - (windows only: the MSDOS name of the file) |
2069 alternativeName - (windows only: the MSDOS name of the file) |
2052 |
2070 |
2053 Some of the fields may be returned as nil on systems which do not provide |
2071 Some of the fields may be returned as nil on systems which do not provide |
2054 all of the information. |
2072 all of the information. |
2055 Return nil if such a file does not exist. |
2073 Return nil if such a file does not exist. |
2056 For symbolic links (if supported by the OS), |
2074 For symbolic links (if supported by the OS), |
2306 ! |
2324 ! |
2307 |
2325 |
2308 disableTimer |
2326 disableTimer |
2309 "disable timer interrupts. |
2327 "disable timer interrupts. |
2310 WARNING: |
2328 WARNING: |
2311 the system will not operate correctly with timer interrupts |
2329 the system will not operate correctly with timer interrupts |
2312 disabled, because no scheduling or timeouts are possible." |
2330 disabled, because no scheduling or timeouts are possible." |
2313 |
2331 |
2314 self subclassResponsibility |
2332 self subclassResponsibility |
2315 ! |
2333 ! |
2316 |
2334 |
2317 disableUserInterrupts |
2335 disableUserInterrupts |
2318 "disable userInterrupt processing; |
2336 "disable userInterrupt processing; |
2319 when disabled, no ^C processing takes place. |
2337 when disabled, no ^C processing takes place. |
2320 WARNING: |
2338 WARNING: |
2321 If at all, use this only for debugged stand-alone applications, since |
2339 If at all, use this only for debugged stand-alone applications, since |
2322 no exit to the debugger is possible with user interrupts disabled. |
2340 no exit to the debugger is possible with user interrupts disabled. |
2323 We recommend setting up a handler for the signal instead of disabling it." |
2341 We recommend setting up a handler for the signal instead of disabling it." |
2324 |
2342 |
2325 self disableSignal:(self sigBREAK). |
2343 self disableSignal:(self sigBREAK). |
2326 self disableSignal:(self sigINT). |
2344 self disableSignal:(self sigINT). |
2327 ! |
2345 ! |
2328 |
2346 |
2557 Return true, if the spy-timerInterrupt was enabled. |
2575 Return true, if the spy-timerInterrupt was enabled. |
2558 This was used by the old MessageTally for profiling. |
2576 This was used by the old MessageTally for profiling. |
2559 On systems, where no virtual timer is available, use the real timer |
2577 On systems, where no virtual timer is available, use the real timer |
2560 (which is of course less correct). |
2578 (which is of course less correct). |
2561 OBSOLETE: the new messageTally runs as a high prio process, not using |
2579 OBSOLETE: the new messageTally runs as a high prio process, not using |
2562 spy interrupts." |
2580 spy interrupts." |
2563 |
2581 |
2564 ^ false |
2582 ^ false |
2565 ! |
2583 ! |
2566 |
2584 |
2567 stopSpyTimer |
2585 stopSpyTimer |
2568 "stop spy timing - disable spy timer. |
2586 "stop spy timing - disable spy timer. |
2569 OBSOLETE: the new messageTally runs as a high prio process, not using |
2587 OBSOLETE: the new messageTally runs as a high prio process, not using |
2570 spy interrupts." |
2588 spy interrupts." |
2571 |
2589 |
2572 ^ false |
2590 ^ false |
2573 ! |
2591 ! |
2574 |
2592 |
2575 terminateProcess:processId |
2593 terminateProcess:processId |
2576 "terminate a unix process. |
2594 "terminate a unix process. |
2577 The process has a chance to do some cleanup. |
2595 The process has a chance to do some cleanup. |
2578 |
2596 |
2579 WARNING: in order to avoid zombie processes (on unix), |
2597 WARNING: in order to avoid zombie processes (on unix), |
2580 you may have to fetch the processes exitstatus with |
2598 you may have to fetch the processes exitstatus with |
2581 OperatingSystem>>getStatusOfProcess:aProcessId." |
2599 OperatingSystem>>getStatusOfProcess:aProcessId." |
2582 |
2600 |
2583 self subclassResponsibility |
2601 self subclassResponsibility |
2584 ! |
2602 ! |
2585 |
2603 |
2586 terminateProcessGroup:processGroupId |
2604 terminateProcessGroup:processGroupId |
2587 "terminate a unix process group. |
2605 "terminate a unix process group. |
2588 The process has a chance to do some cleanup. |
2606 The process has a chance to do some cleanup. |
2589 |
2607 |
2590 WARNING: in order to avoid zombie processes (on unix), |
2608 WARNING: in order to avoid zombie processes (on unix), |
2591 you may have to fetch the processes exitstatus with |
2609 you may have to fetch the processes exitstatus with |
2592 OperatingSystem>>getStatusOfProcess:aProcessId." |
2610 OperatingSystem>>getStatusOfProcess:aProcessId." |
2593 |
2611 |
2594 self subclassResponsibility |
2612 self subclassResponsibility |
2595 ! |
2613 ! |
2596 |
2614 |
2597 unblockInterrupts |
2615 unblockInterrupts |
2799 |
2817 |
2800 getHostName |
2818 getHostName |
2801 "return the hostname we are running on - if there is |
2819 "return the hostname we are running on - if there is |
2802 a HOST environment variable, we are much faster here ... |
2820 a HOST environment variable, we are much faster here ... |
2803 Notice: |
2821 Notice: |
2804 not all systems support this; on some, 'unknown' is returned." |
2822 not all systems support this; on some, 'unknown' is returned." |
2805 |
2823 |
2806 self subclassResponsibility |
2824 self subclassResponsibility |
2807 ! |
2825 ! |
2808 |
2826 |
2809 getLocaleInfo |
2827 getLocaleInfo |
2810 "return a dictionary filled with values from the locale information; |
2828 "return a dictionary filled with values from the locale information; |
2811 Not all fields may be present, depending on the OS's setup and capabilities. |
2829 Not all fields may be present, depending on the OS's setup and capabilities. |
2812 Possible fields are: |
2830 Possible fields are: |
2813 decimalPoint <String> |
2831 decimalPoint <String> |
2814 |
2832 |
2815 thousandsSep <String> |
2833 thousandsSep <String> |
2816 |
2834 |
2817 internationalCurrencySymbol <String> |
2835 internationalCurrencySymbol <String> |
2818 |
2836 |
2819 currencySymbol <String> |
2837 currencySymbol <String> |
2820 |
2838 |
2821 monetaryDecimalPoint <String> |
2839 monetaryDecimalPoint <String> |
2822 |
2840 |
2823 monetaryThousandsSeparator <String> |
2841 monetaryThousandsSeparator <String> |
2824 |
2842 |
2825 positiveSign <String> |
2843 positiveSign <String> |
2826 |
2844 |
2827 negativeSign <String> |
2845 negativeSign <String> |
2828 |
2846 |
2829 internationalFractionalDigits <Integer> |
2847 internationalFractionalDigits <Integer> |
2830 |
2848 |
2831 fractionalDigits <Integer> |
2849 fractionalDigits <Integer> |
2832 |
2850 |
2833 positiveSignPrecedesCurrencySymbol <Boolean> |
2851 positiveSignPrecedesCurrencySymbol <Boolean> |
2834 |
2852 |
2835 negativeSignPrecedesCurrencySymbol <Boolean> |
2853 negativeSignPrecedesCurrencySymbol <Boolean> |
2836 |
2854 |
2837 positiveSignSeparatedBySpaceFromCurrencySymbol <Boolean> |
2855 positiveSignSeparatedBySpaceFromCurrencySymbol <Boolean> |
2838 |
2856 |
2839 negativeSignSeparatedBySpaceFromCurrencySymbol <Boolean> |
2857 negativeSignSeparatedBySpaceFromCurrencySymbol <Boolean> |
2840 |
2858 |
2841 positiveSignPosition <Symbol> |
2859 positiveSignPosition <Symbol> |
2842 one of: #parenthesesAround, |
2860 one of: #parenthesesAround, |
2843 #signPrecedes, |
2861 #signPrecedes, |
2844 #signSuceeds, |
2862 #signSuceeds, |
2845 #signPrecedesCurrencySymbol, |
2863 #signPrecedesCurrencySymbol, |
2846 #signSuceedsCurrencySymbol |
2864 #signSuceedsCurrencySymbol |
2847 |
2865 |
2848 negativeSignPosition <like above> |
2866 negativeSignPosition <like above> |
2849 |
2867 |
2850 it is up to the application to deal with undefined values. |
2868 it is up to the application to deal with undefined values. |
2851 |
2869 |
2852 Notice, that (for now), the system does not use this information; |
2870 Notice, that (for now), the system does not use this information; |
2853 it should be used by applications as required. |
2871 it should be used by applications as required. |
3049 OS, for example, linux returns 'ix86', while WIN32 returns 'x86'. |
3067 OS, for example, linux returns 'ix86', while WIN32 returns 'x86'. |
3050 |
3068 |
3051 This method is mainly provided to augment error reports with some system |
3069 This method is mainly provided to augment error reports with some system |
3052 information. |
3070 information. |
3053 (in case of system/version specific OS errors, conditional workarounds and patches |
3071 (in case of system/version specific OS errors, conditional workarounds and patches |
3054 may be based upon this info). |
3072 may be based upon this info). |
3055 Your application should NOT depend upon this in any way. |
3073 Your application should NOT depend upon this in any way. |
3056 |
3074 |
3057 The returned info may (or may not) contain: |
3075 The returned info may (or may not) contain: |
3058 #system -> some operating system identification (irix, Linux, nt, win32s ...) |
3076 #system -> some operating system identification (irix, Linux, nt, win32s ...) |
3059 #version -> OS version (some os version identification) |
3077 #version -> OS version (some os version identification) |
3060 #release -> OS release (3.5, 1.2.1 ...) |
3078 #release -> OS release (3.5, 1.2.1 ...) |
3061 #node -> some host identification (hostname) |
3079 #node -> some host identification (hostname) |
3062 #domain -> domain name (hosts domain) |
3080 #domain -> domain name (hosts domain) |
3063 #machine -> type of machine (i586, mips ...) |
3081 #machine -> type of machine (i586, mips ...) |
3064 " |
3082 " |
3065 |
3083 |
3066 |info| |
3084 |info| |
3067 |
3085 |
3068 info := IdentityDictionary new. |
3086 info := IdentityDictionary new. |
3360 "/ |
3378 "/ |
3361 "/ the users home (login) directory |
3379 "/ the users home (login) directory |
3362 "/ |
3380 "/ |
3363 homePath := OperatingSystem getHomeDirectory. |
3381 homePath := OperatingSystem getHomeDirectory. |
3364 homePath notNil ifTrue:[ |
3382 homePath notNil ifTrue:[ |
3365 sysPath add:homePath. |
3383 sysPath add:homePath. |
3366 |
3384 |
3367 "/ |
3385 "/ |
3368 "/ a users private smalltalk directory in its home (login) directory |
3386 "/ a users private smalltalk directory in its home (login) directory |
3369 "/ |
3387 "/ |
3370 OperatingSystem isUNIXlike ifTrue:[ |
3388 OperatingSystem isUNIXlike ifTrue:[ |
3371 priv := '.smalltalk'. |
3389 priv := '.smalltalk'. |
3372 ] ifFalse:[ |
3390 ] ifFalse:[ |
3373 priv := 'smalltalk'. |
3391 priv := 'smalltalk'. |
3374 ]. |
3392 ]. |
3375 userPrivateSTXDir := homePath asFilename constructString:priv. |
3393 userPrivateSTXDir := homePath asFilename constructString:priv. |
3376 (userPrivateSTXDir asFilename isDirectory) ifTrue:[ |
3394 (userPrivateSTXDir asFilename isDirectory) ifTrue:[ |
3377 sysPath add:userPrivateSTXDir |
3395 sysPath add:userPrivateSTXDir |
3378 ]. |
3396 ]. |
3379 ]. |
3397 ]. |
3380 |
3398 |
3381 "/ |
3399 "/ |
3382 "/ SMALLTALK_LIBDIR and/or STX_LIBDIR from the environment |
3400 "/ SMALLTALK_LIBDIR and/or STX_LIBDIR from the environment |
3383 "/ |
3401 "/ |
3384 p := OperatingSystem getEnvironment:'SMALLTALK_LIBDIR'. |
3402 p := OperatingSystem getEnvironment:'SMALLTALK_LIBDIR'. |
3385 p notNil ifTrue:[ |
3403 p notNil ifTrue:[ |
3386 sysPath add:p |
3404 sysPath add:p |
3387 ]. |
3405 ]. |
3388 p := OperatingSystem getEnvironment:'STX_LIBDIR'. |
3406 p := OperatingSystem getEnvironment:'STX_LIBDIR'. |
3389 p notNil ifTrue:[ |
3407 p notNil ifTrue:[ |
3390 sysPath add:p |
3408 sysPath add:p |
3391 ]. |
3409 ]. |
3392 ^ sysPath |
3410 ^ sysPath |
3393 ! ! |
3411 ! ! |
3394 |
3412 |
3395 !AbstractOperatingSystem class methodsFor:'private'! |
3413 !AbstractOperatingSystem class methodsFor:'private'! |
3877 "return true, if data is available on a filedescriptor |
3895 "return true, if data is available on a filedescriptor |
3878 (i.e. read is possible without blocking). |
3896 (i.e. read is possible without blocking). |
3879 This depends on a working select or FIONREAD to be provided by the OS." |
3897 This depends on a working select or FIONREAD to be provided by the OS." |
3880 |
3898 |
3881 self supportsSelect ifFalse:[ |
3899 self supportsSelect ifFalse:[ |
3882 "/ mhmh - what should we do then ? |
3900 "/ mhmh - what should we do then ? |
3883 "/ For now, return true as if data was present, |
3901 "/ For now, return true as if data was present, |
3884 "/ and let the thread fall into the read. |
3902 "/ and let the thread fall into the read. |
3885 "/ It will then (hopefully) be desceduled there and |
3903 "/ It will then (hopefully) be desceduled there and |
3886 "/ effectively polling for input. |
3904 "/ effectively polling for input. |
3887 |
3905 |
3888 ^ true |
3906 ^ true |
3889 ]. |
3907 ]. |
3890 |
3908 |
3891 (self selectOnAnyReadable:(Array with:fd) |
3909 (self selectOnAnyReadable:(Array with:fd) |
3892 writable:nil |
3910 writable:nil |
3893 exception:nil |
3911 exception:nil |
3894 withTimeOut:0) == fd |
3912 withTimeOut:0) == fd |
3895 ifTrue:[^ true]. |
3913 ifTrue:[^ true]. |
3896 ^ false |
3914 ^ false |
3897 ! |
3915 ! |
3898 |
3916 |
3899 readWriteCheck:fd |
3917 readWriteCheck:fd |
3900 "return true, if filedescriptor can be read or written without blocking. |
3918 "return true, if filedescriptor can be read or written without blocking. |
3901 This is actually only used with sockets, to wait for a connect to |
3919 This is actually only used with sockets, to wait for a connect to |
3902 be finished." |
3920 be finished." |
3903 |
3921 |
3904 self supportsSelect ifFalse:[ |
3922 self supportsSelect ifFalse:[ |
3905 "/ mhmh - what should we do then ? |
3923 "/ mhmh - what should we do then ? |
3906 "/ For now, return true as if data was present, |
3924 "/ For now, return true as if data was present, |
3907 "/ and let the thread fall into the write. |
3925 "/ and let the thread fall into the write. |
3908 "/ It will then (hopefully) be desceduled there and |
3926 "/ It will then (hopefully) be desceduled there and |
3909 "/ effectively polling for output. |
3927 "/ effectively polling for output. |
3910 ^ true |
3928 ^ true |
3911 ]. |
3929 ]. |
3912 |
3930 |
3913 (self selectOnAnyReadable:(Array with:fd) |
3931 (self selectOnAnyReadable:(Array with:fd) |
3914 writable:(Array with:fd) |
3932 writable:(Array with:fd) |
3915 exception:nil |
3933 exception:nil |
3916 withTimeOut:0) == fd |
3934 withTimeOut:0) == fd |
3917 ifTrue:[^ true]. |
3935 ifTrue:[^ true]. |
3918 ^ false |
3936 ^ false |
3919 ! |
3937 ! |
3920 |
3938 |
3921 selectOn:fd1 and:fd2 withTimeOut:millis |
3939 selectOn:fd1 and:fd2 withTimeOut:millis |
3922 "wait for any fd to become ready; timeout after t milliseconds. |
3940 "wait for any fd to become ready; timeout after t milliseconds. |
3923 A zero timeout-time will immediately return (i.e. poll). |
3941 A zero timeout-time will immediately return (i.e. poll). |
3924 Return fd if i/o ok, nil if timed-out or interrupted. |
3942 Return fd if i/o ok, nil if timed-out or interrupted. |
3925 Obsolete: |
3943 Obsolete: |
3926 This is a leftover method and will vanish." |
3944 This is a leftover method and will vanish." |
3927 |
3945 |
3928 ^ self selectOnAnyReadable:(Array with:fd1 with:fd2) |
3946 ^ self selectOnAnyReadable:(Array with:fd1 with:fd2) |
3929 writable:(Array with:fd1 with:fd2) |
3947 writable:(Array with:fd1 with:fd2) |
3930 exception:nil |
3948 exception:nil |
3931 withTimeOut:millis |
3949 withTimeOut:millis |
3932 ! |
3950 ! |
3933 |
3951 |
3934 selectOn:fd withTimeOut:millis |
3952 selectOn:fd withTimeOut:millis |
3935 "wait for aFileDesriptor to become ready; timeout after t milliseconds. |
3953 "wait for aFileDesriptor to become ready; timeout after t milliseconds. |
3936 Return true, if i/o ok, false if timed-out or interrupted. |
3954 Return true, if i/o ok, false if timed-out or interrupted. |
3937 With 0 as timeout argument, this can be used to check for availability |
3955 With 0 as timeout argument, this can be used to check for availability |
3938 of read-data. |
3956 of read-data. |
3939 Experimental." |
3957 Experimental." |
3940 |
3958 |
3941 ^ self selectOnAnyReadable:(Array with:fd) |
3959 ^ self selectOnAnyReadable:(Array with:fd) |
3942 writable:(Array with:fd) |
3960 writable:(Array with:fd) |
3943 exception:nil |
3961 exception:nil |
3944 withTimeOut:millis |
3962 withTimeOut:millis |
3945 ! |
3963 ! |
3946 |
3964 |
3947 selectOnAny:fdArray withTimeOut:millis |
3965 selectOnAny:fdArray withTimeOut:millis |
3948 "wait for any fd in fdArray (an Array of integers) to become ready; |
3966 "wait for any fd in fdArray (an Array of integers) to become ready; |
3949 timeout after t milliseconds. An empty set will always wait. |
3967 timeout after t milliseconds. An empty set will always wait. |
3950 Return first ready fd if i/o ok, nil if timed-out or interrupted. |
3968 Return first ready fd if i/o ok, nil if timed-out or interrupted. |
3951 Experimental." |
3969 Experimental." |
3952 |
3970 |
3953 ^ self selectOnAnyReadable:fdArray |
3971 ^ self selectOnAnyReadable:fdArray |
3954 writable:fdArray |
3972 writable:fdArray |
3955 exception:nil |
3973 exception:nil |
3956 withTimeOut:millis |
3974 withTimeOut:millis |
3957 ! |
3975 ! |
3958 |
3976 |
3959 selectOnAnyReadable:fdArray withTimeOut:millis |
3977 selectOnAnyReadable:fdArray withTimeOut:millis |
3960 "wait for any fd in fdArray (an Array of integers) to become ready for |
3978 "wait for any fd in fdArray (an Array of integers) to become ready for |
3961 reading. Timeout after t milliseconds. An empty set will always wait. |
3979 reading. Timeout after t milliseconds. An empty set will always wait. |
3962 A zero timeout-time will immediately return (i.e. poll). |
3980 A zero timeout-time will immediately return (i.e. poll). |
3963 Return first ready fd if i/o ok, nil if timed-out or interrupted. |
3981 Return first ready fd if i/o ok, nil if timed-out or interrupted. |
3964 Experimental." |
3982 Experimental." |
3965 |
3983 |
3966 ^ self selectOnAnyReadable:fdArray |
3984 ^ self selectOnAnyReadable:fdArray |
3967 writable:nil |
3985 writable:nil |
3968 exception:nil |
3986 exception:nil |
3969 withTimeOut:millis |
3987 withTimeOut:millis |
3970 ! |
3988 ! |
3971 |
3989 |
3972 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray withTimeOut:millis |
3990 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray withTimeOut:millis |
3973 "wait for any fd in readFdArray (an Array of integers) to become ready for |
3991 "wait for any fd in readFdArray (an Array of integers) to become ready for |
3974 reading, writeFdArray to become ready for writing, or exceptFdArray to |
3992 reading, writeFdArray to become ready for writing, or exceptFdArray to |
3994 |
4012 |
3995 writeCheck:fd |
4013 writeCheck:fd |
3996 "return true, if filedescriptor can be written without blocking" |
4014 "return true, if filedescriptor can be written without blocking" |
3997 |
4015 |
3998 self supportsSelect ifFalse:[ |
4016 self supportsSelect ifFalse:[ |
3999 "/ mhmh - what should we do then ? |
4017 "/ mhmh - what should we do then ? |
4000 "/ For now, return true as if data was present, |
4018 "/ For now, return true as if data was present, |
4001 "/ and let the thread fall into the write. |
4019 "/ and let the thread fall into the write. |
4002 "/ It will then (hopefully) be desceduled there and |
4020 "/ It will then (hopefully) be desceduled there and |
4003 "/ effectively polling for output. |
4021 "/ effectively polling for output. |
4004 ^ true |
4022 ^ true |
4005 ]. |
4023 ]. |
4006 |
4024 |
4007 (self selectOnAnyReadable:nil |
4025 (self selectOnAnyReadable:nil |
4008 writable:(Array with:fd) |
4026 writable:(Array with:fd) |
4009 exception:nil |
4027 exception:nil |
4010 withTimeOut:0) == fd |
4028 withTimeOut:0) == fd |
4011 ifTrue:[^ true]. |
4029 ifTrue:[^ true]. |
4012 ^ false |
4030 ^ false |
4013 ! ! |
4031 ! ! |
4014 |
4032 |
4015 !AbstractOperatingSystem class methodsFor:'documentation'! |
4033 !AbstractOperatingSystem class methodsFor:'documentation'! |
4016 |
4034 |
4017 version |
4035 version |
4018 ^ '$Header: /cvs/stx/stx/libbasic/AbstractOperatingSystem.st,v 1.27 1999-10-06 12:10:22 cg Exp $' |
4036 ^ '$Header: /cvs/stx/stx/libbasic/AbstractOperatingSystem.st,v 1.28 1999-10-06 12:59:16 ca Exp $' |
4019 ! ! |
4037 ! ! |
4020 AbstractOperatingSystem initialize! |
4038 AbstractOperatingSystem initialize! |