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 |
|
13 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
14 |
13 |
15 OSFileHandle subclass:#UnixFileDescriptorHandle |
14 OSFileHandle subclass:#UnixFileDescriptorHandle |
16 instanceVariableNames:'' |
15 instanceVariableNames:'' |
17 classVariableNames:'' |
16 classVariableNames:'' |
55 INT fd = (INT)(__externalAddressVal(self)); |
54 INT fd = (INT)(__externalAddressVal(self)); |
56 INT cnt, offs; |
55 INT cnt, offs; |
57 int nInstBytes, objSize; |
56 int nInstBytes, objSize; |
58 |
57 |
59 if (! __bothSmallInteger(count, firstIndex)) { |
58 if (! __bothSmallInteger(count, firstIndex)) { |
60 goto bad; |
59 goto bad; |
61 } |
60 } |
62 cnt = __smallIntegerVal(count); |
61 cnt = __smallIntegerVal(count); |
63 offs = __smallIntegerVal(firstIndex) - 1; |
62 offs = __smallIntegerVal(firstIndex) - 1; |
64 |
63 |
65 if (fd < 0) { |
64 if (fd < 0) { |
66 goto bad; |
65 goto bad; |
67 } |
66 } |
68 if (__isExternalBytesLike(aByteBuffer)) { |
67 if (__isExternalBytesLike(aByteBuffer)) { |
69 OBJ sz; |
68 OBJ sz; |
70 |
69 |
71 nInstBytes = 0; |
70 nInstBytes = 0; |
72 extPtr = (char *)(__externalBytesAddress(aByteBuffer)); |
71 extPtr = (char *)(__externalBytesAddress(aByteBuffer)); |
73 if (extPtr == NULL) goto bad; |
72 if (extPtr == NULL) goto bad; |
74 sz = __externalBytesSize(aByteBuffer); |
73 sz = __externalBytesSize(aByteBuffer); |
75 if (__isSmallInteger(sz)) { |
74 if (__isSmallInteger(sz)) { |
76 objSize = __smallIntegerVal(sz); |
75 objSize = __smallIntegerVal(sz); |
77 } else { |
76 } else { |
78 objSize = -1; /* unknown */ |
77 objSize = -1; /* unknown */ |
79 } |
78 } |
80 } else { |
79 } else { |
81 OBJ oClass; |
80 OBJ oClass = __Class(aByteBuffer); |
82 int nInstVars; |
81 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
83 |
82 |
84 oClass = __Class(aByteBuffer); |
83 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
85 switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
84 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
86 case BYTEARRAY: |
85 case BYTEARRAY: |
87 case WORDARRAY: |
86 case WORDARRAY: |
88 case LONGARRAY: |
87 case LONGARRAY: |
89 case SWORDARRAY: |
88 case SWORDARRAY: |
90 case SLONGARRAY: |
89 case SLONGARRAY: |
91 case FLOATARRAY: |
90 case FLOATARRAY: |
92 case DOUBLEARRAY: |
91 case DOUBLEARRAY: |
93 break; |
92 #ifdef __NEED_DOUBLE_ALIGN |
94 default: |
93 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
95 goto bad; |
94 #endif |
96 } |
95 break; |
97 extPtr = (char *)0; |
96 case LONGLONGARRAY: |
98 nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars); |
97 case SLONGLONGARRAY: |
99 nInstBytes = __OBJS2BYTES__(nInstVars); |
98 #ifdef __NEED_LONGLONG_ALIGN |
100 objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; |
99 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
|
100 #endif |
|
101 default: |
|
102 goto bad; |
|
103 } |
|
104 extPtr = (char *)0; |
|
105 objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; |
101 } |
106 } |
102 if ((offs >= 0) |
107 if ((offs >= 0) |
103 && (cnt >= 0) |
108 && (cnt >= 0) |
104 && ((objSize == -1) || (objSize >= (cnt + offs)))) { |
109 && ((objSize == -1) || (objSize >= (cnt + offs)))) { |
105 nRead = 0; |
110 nRead = 0; |
106 |
111 |
107 do { |
112 do { |
108 int n; |
113 int n; |
109 |
114 |
110 if (extPtr) { |
115 if (extPtr) { |
111 n = read(fd, extPtr+offs, cnt); |
116 n = read(fd, extPtr+offs, cnt); |
112 } else { |
117 } else { |
113 char *bp; |
118 char *bp; |
114 |
119 |
115 /* |
120 /* |
116 * on interrupt, anObject may be moved to another location. |
121 * on interrupt, anObject may be moved to another location. |
117 * So we recompute the byte-address here. |
122 * So we recompute the byte-address here. |
118 */ |
123 */ |
119 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; |
124 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; |
120 |
125 |
121 n = read(fd, bp + offs, cnt); |
126 n = read(fd, bp + offs, cnt); |
122 } |
127 } |
123 if (n > 0) { |
128 if (n > 0) { |
124 cnt -= n; |
129 cnt -= n; |
125 offs += n; |
130 offs += n; |
126 nRead += n; |
131 nRead += n; |
127 } else { |
132 } else { |
128 if (n < 0) { |
133 if (n < 0) { |
129 if (errno == EINTR) { |
134 if (errno == EINTR) { |
130 continue; |
135 continue; |
131 } |
136 } |
132 break; |
137 break; |
133 } |
138 } |
134 } |
139 } |
135 } while (cnt > 0); |
140 } while (cnt > 0); |
136 |
141 |
137 RETURN (__mkSmallInteger(nRead)); |
142 RETURN (__mkSmallInteger(nRead)); |
138 } |
143 } |
139 bad: ; |
144 bad: ; |
140 %}. |
145 %}. |
141 ^ self primitiveFailed |
146 ^ self primitiveFailed |
142 |
147 |
161 INT fd = (INT)(__externalAddressVal(self)); |
166 INT fd = (INT)(__externalAddressVal(self)); |
162 INT cnt, offs; |
167 INT cnt, offs; |
163 int nInstBytes, objSize; |
168 int nInstBytes, objSize; |
164 |
169 |
165 if (! __bothSmallInteger(count, firstIndex)) { |
170 if (! __bothSmallInteger(count, firstIndex)) { |
166 goto bad; |
171 goto bad; |
167 } |
172 } |
168 cnt = __smallIntegerVal(count); |
173 cnt = __smallIntegerVal(count); |
169 offs = __smallIntegerVal(firstIndex) - 1; |
174 offs = __smallIntegerVal(firstIndex) - 1; |
170 |
175 |
171 if (fd < 0) { |
176 if (fd < 0) { |
172 goto bad; |
177 goto bad; |
173 } |
178 } |
174 if (__isExternalBytesLike(aByteBuffer)) { |
179 if (__isExternalBytesLike(aByteBuffer)) { |
175 OBJ sz; |
180 OBJ sz; |
176 |
181 |
177 nInstBytes = 0; |
182 nInstBytes = 0; |
178 extPtr = (char *)(__externalBytesAddress(aByteBuffer)); |
183 extPtr = (char *)(__externalBytesAddress(aByteBuffer)); |
179 if (extPtr == NULL) goto bad; |
184 if (extPtr == NULL) goto bad; |
180 sz = __externalBytesSize(aByteBuffer); |
185 sz = __externalBytesSize(aByteBuffer); |
181 if (__isSmallInteger(sz)) { |
186 if (__isSmallInteger(sz)) { |
182 objSize = __smallIntegerVal(sz); |
187 objSize = __smallIntegerVal(sz); |
183 } else { |
188 } else { |
184 objSize = -1; /* unknown */ |
189 objSize = -1; /* unknown */ |
185 } |
190 } |
186 } else { |
191 } else { |
187 OBJ oClass; |
192 OBJ oClass = __Class(aByteBuffer); |
188 int nInstVars; |
193 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars); |
189 |
194 |
190 oClass = __Class(aByteBuffer); |
195 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars); |
191 switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
196 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) { |
192 case BYTEARRAY: |
197 case BYTEARRAY: |
193 case WORDARRAY: |
198 case WORDARRAY: |
194 case LONGARRAY: |
199 case LONGARRAY: |
195 case SWORDARRAY: |
200 case SWORDARRAY: |
196 case SLONGARRAY: |
201 case SLONGARRAY: |
197 case FLOATARRAY: |
202 case FLOATARRAY: |
198 case DOUBLEARRAY: |
203 case DOUBLEARRAY: |
199 break; |
204 #ifdef __NEED_DOUBLE_ALIGN |
200 default: |
205 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1); |
201 goto bad; |
206 #endif |
202 } |
207 break; |
203 extPtr = (char *)0; |
208 case LONGLONGARRAY: |
204 nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars); |
209 case SLONGLONGARRAY: |
205 nInstBytes = __OBJS2BYTES__(nInstVars); |
210 #ifdef __NEED_LONGLONG_ALIGN |
206 objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; |
211 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1); |
|
212 #endif |
|
213 default: |
|
214 goto bad; |
|
215 } |
|
216 extPtr = (char *)0; |
|
217 objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes; |
207 } |
218 } |
208 if ((offs >= 0) |
219 if ((offs >= 0) |
209 && (cnt >= 0) |
220 && (cnt >= 0) |
210 && ((objSize == -1) || (objSize >= (cnt + offs)))) { |
221 && ((objSize == -1) || (objSize >= (cnt + offs)))) { |
211 nWritten = 0; |
222 nWritten = 0; |
212 |
223 |
213 do { |
224 do { |
214 int n; |
225 int n; |
215 |
226 |
216 if (extPtr) { |
227 if (extPtr) { |
217 n = write(fd, extPtr+offs, cnt); |
228 n = write(fd, extPtr+offs, cnt); |
218 } else { |
229 } else { |
219 char *bp; |
230 char *bp; |
220 |
231 |
221 /* |
232 /* |
222 * on interrupt, anObject may be moved to another location. |
233 * on interrupt, anObject may be moved to another location. |
223 * So we recompute the byte-address here. |
234 * So we recompute the byte-address here. |
224 */ |
235 */ |
225 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; |
236 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes; |
226 |
237 |
227 n = write(fd, bp + offs, cnt); |
238 n = write(fd, bp + offs, cnt); |
228 } |
239 } |
229 if (n > 0) { |
240 if (n > 0) { |
230 cnt -= n; |
241 cnt -= n; |
231 offs += n; |
242 offs += n; |
232 nWritten += n; |
243 nWritten += n; |
233 } else { |
244 } else { |
234 if (n < 0) { |
245 if (n < 0) { |
235 if (errno == EINTR) { |
246 if (errno == EINTR) { |
236 continue; |
247 continue; |
237 } |
248 } |
238 break; |
249 break; |
239 } |
250 } |
240 } |
251 } |
241 } while (cnt > 0); |
252 } while (cnt > 0); |
242 |
253 |
243 RETURN (__mkSmallInteger(nWritten)); |
254 RETURN (__mkSmallInteger(nWritten)); |
244 } |
255 } |
245 bad: ; |
256 bad: ; |
246 %}. |
257 %}. |
247 ^ self primitiveFailed |
258 ^ self primitiveFailed |
248 |
259 |