Bug Summary

File:os_io.c
Location:line 4403, column 12
Description:Function call argument is an uninitialized value

Annotated Source Code

1/* File: "os_io.c" */
2
3/* Copyright (c) 1994-2013 by Marc Feeley, All Rights Reserved. */
4
5/*
6 * This module implements the operating system specific routines
7 * related to I/O.
8 */
9
10#define ___INCLUDED_FROM_OS_IO
11#define ___VERSION407000 407000
12#include "gambit.h"
13
14#include "os_base.h"
15#include "os_io.h"
16#include "os_tty.h"
17#include "os_files.h"
18#include "setup.h"
19#include "c_intf.h"
20
21/*---------------------------------------------------------------------------*/
22
23
24___io_module ___io_mod =
25{
26 0,
27 0
28
29#ifdef ___IO_MODULE_INIT
30 ___IO_MODULE_INIT
31#endif
32};
33
34
35/*---------------------------------------------------------------------------*/
36
37/* Device groups. */
38
39
40___SCMOBJlong ___device_group_setup
41 ___P((___device_group **dgroup),(___device_group **dgroup)
42 (dgroup)(___device_group **dgroup)
43___device_group **dgroup;)(___device_group **dgroup)
44{
45 ___SCMOBJlong e;
46 ___device_group *g;
47
48 g = ___CAST(___device_group*,((___device_group*)(___alloc_mem (sizeof (___device_group))))
49 ___alloc_mem (sizeof (___device_group)))((___device_group*)(___alloc_mem (sizeof (___device_group))));
50
51 if (g == NULL((void*)0))
52 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
53
54 g->list = NULL((void*)0);
55
56 *dgroup = g;
57
58 return ___FIX(___NO_ERR)(((long)(0))<<2);
59}
60
61
62void ___device_group_cleanup
63 ___P((___device_group *dgroup),(___device_group *dgroup)
64 (dgroup)(___device_group *dgroup)
65___device_group *dgroup;)(___device_group *dgroup)
66{
67 while (dgroup->list != NULL((void*)0))
68 if (___device_cleanup (dgroup->list) != ___FIX(___NO_ERR)(((long)(0))<<2))
69 break;
70
71 ___free_mem (dgroup);
72}
73
74
75void ___device_add_to_group
76 ___P((___device_group *dgroup,(___device_group *dgroup, ___device *dev)
77 ___device *dev),(___device_group *dgroup, ___device *dev)
78 (dgroup,(___device_group *dgroup, ___device *dev)
79 dev)(___device_group *dgroup, ___device *dev)
80___device_group *dgroup;(___device_group *dgroup, ___device *dev)
81___device *dev;)(___device_group *dgroup, ___device *dev)
82{
83 ___device *head = dgroup->list;
84
85 dev->group = dgroup;
86
87 if (head == NULL((void*)0))
88 {
89 dev->next = dev;
90 dev->prev = dev;
91 dgroup->list = dev;
92 }
93 else
94 {
95 ___device *tail = head->prev;
96 dev->next = head;
97 dev->prev = tail;
98 tail->next = dev;
99 head->prev = dev;
100 }
101}
102
103void ___device_remove_from_group
104 ___P((___device *dev),(___device *dev)
105 (dev)(___device *dev)
106___device *dev;)(___device *dev)
107{
108 ___device_group *dgroup = dev->group;
109 ___device *prev = dev->prev;
110 ___device *next = dev->next;
111
112 if (prev == dev)
113 dgroup->list = NULL((void*)0);
114 else
115 {
116 if (dgroup->list == dev)
117 dgroup->list = next;
118 prev->next = next;
119 next->prev = prev;
120 dev->next = dev;
121 dev->prev = dev;
122 }
123
124 dev->group = NULL((void*)0);
125}
126
127___device_group *___global_device_group ___PVOID(void)
128{
129 return ___io_mod.dgroup;
130}
131
132
133/*---------------------------------------------------------------------------*/
134
135/* Nonblocking pipes */
136
137#ifdef USE_PUMPS
138
139___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_setup
140 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, int size)
141 int size),(___nonblocking_pipe *pipe, int size)
142 (pipe,(___nonblocking_pipe *pipe, int size)
143 size)(___nonblocking_pipe *pipe, int size)
144___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, int size)
145int size;)(___nonblocking_pipe *pipe, int size)
146{
147 ___U8unsigned char *buffer;
148 HANDLE mutex;
149 HANDLE revent;
150 HANDLE wevent;
151
152 buffer = ___CAST(___U8*,((unsigned char*)(___alloc_mem (size)))
153 ___alloc_mem (size))((unsigned char*)(___alloc_mem (size)));
154
155 if (buffer == NULL((void*)0))
156 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
157
158 mutex = CreateMutex (NULL((void*)0), /* can't inherit */
159 FALSE, /* unlocked */
160 NULL((void*)0)); /* no name */
161
162 if (mutex == NULL((void*)0))
163 {
164 ___SCMOBJlong e = err_code_from_GetLastError ()___err_code_from_GetLastError();
165 ___free_mem (buffer);
166 return e;
167 }
168
169 revent = CreateEvent (NULL((void*)0), /* can't inherit */
170 TRUE, /* manual reset */
171 FALSE, /* not signaled */
172 NULL((void*)0)); /* no name */
173
174 if (revent == NULL((void*)0))
175 {
176 ___SCMOBJlong e = err_code_from_GetLastError ()___err_code_from_GetLastError();
177 CloseHandle (mutex); /* ignore error */
178 ___free_mem (buffer);
179 return e;
180 }
181
182 wevent = CreateEvent (NULL((void*)0), /* can't inherit */
183 TRUE, /* manual reset */
184 FALSE, /* not signaled */
185 NULL((void*)0)); /* no name */
186
187 if (wevent == NULL((void*)0))
188 {
189 ___SCMOBJlong e = err_code_from_GetLastError ()___err_code_from_GetLastError();
190 CloseHandle (revent); /* ignore error */
191 CloseHandle (mutex); /* ignore error */
192 ___free_mem (buffer);
193 return e;
194 }
195
196 pipe->mutex = mutex;
197 pipe->revent = revent;
198 pipe->wevent = wevent;
199 pipe->rerr = ___FIX(___NO_ERR)(((long)(0))<<2);
200 pipe->werr = ___FIX(___NO_ERR)(((long)(0))<<2);
201 pipe->oob = 0;
202 pipe->rd = 0;
203 pipe->wr = 0;
204 pipe->size = size;
205 pipe->buffer = buffer;
206
207 return ___FIX(___NO_ERR)(((long)(0))<<2);
208}
209
210___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_cleanup
211 ___P((___nonblocking_pipe *pipe),(___nonblocking_pipe *pipe)
212 (pipe)(___nonblocking_pipe *pipe)
213___nonblocking_pipe *pipe;)(___nonblocking_pipe *pipe)
214{
215 CloseHandle (pipe->wevent); /* ignore error */
216 CloseHandle (pipe->revent); /* ignore error */
217 CloseHandle (pipe->mutex); /* ignore error */
218 ___free_mem (pipe->buffer);
219
220 return ___FIX(___NO_ERR)(((long)(0))<<2);
221}
222
223___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_set_reader_err
224 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, long err)
225 ___SCMOBJ err),(___nonblocking_pipe *pipe, long err)
226 (pipe,(___nonblocking_pipe *pipe, long err)
227 err)(___nonblocking_pipe *pipe, long err)
228___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, long err)
229___SCMOBJ err;)(___nonblocking_pipe *pipe, long err)
230{
231 if (WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
232 return err_code_from_GetLastError ()___err_code_from_GetLastError();
233
234 /* note: the reader error indicator may get overwritten */
235
236 pipe->rerr = err;
237
238 SetEvent (pipe->wevent); /* ignore error */
239
240 if (pipe->werr == ___FIX(___NO_ERR)(((long)(0))<<2))
241 ResetEvent (pipe->revent); /* ignore error */
242
243 ReleaseMutex (pipe->mutex); /* ignore error */
244
245 return ___FIX(___NO_ERR)(((long)(0))<<2);
246}
247
248___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_set_writer_err
249 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, long err)
250 ___SCMOBJ err),(___nonblocking_pipe *pipe, long err)
251 (pipe,(___nonblocking_pipe *pipe, long err)
252 err)(___nonblocking_pipe *pipe, long err)
253___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, long err)
254___SCMOBJ err;)(___nonblocking_pipe *pipe, long err)
255{
256 if (WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
257 return err_code_from_GetLastError ()___err_code_from_GetLastError();
258
259 /* note: the writer error indicator may get overwritten */
260
261 pipe->werr = err;
262
263 SetEvent (pipe->revent); /* ignore error */
264
265 if (pipe->rerr == ___FIX(___NO_ERR)(((long)(0))<<2))
266 ResetEvent (pipe->wevent); /* ignore error */
267
268 ReleaseMutex (pipe->mutex); /* ignore error */
269
270 return ___FIX(___NO_ERR)(((long)(0))<<2);
271}
272
273___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_write_oob
274 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
275 ___nonblocking_pipe_oob_msg *oob_msg),(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
276 (pipe,(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
277 oob_msg)(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
278___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
279___nonblocking_pipe_oob_msg *oob_msg;)(___nonblocking_pipe *pipe, ___nonblocking_pipe_oob_msg *oob_msg
)
280{
281 if (WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
282 return err_code_from_GetLastError ()___err_code_from_GetLastError();
283
284 if (pipe->werr != ___FIX(___NO_ERR)(((long)(0))<<2) || pipe->oob)
285 {
286 ReleaseMutex (pipe->mutex); /* ignore error */
287 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
288 }
289
290 pipe->oob = 1;
291 pipe->oob_msg = *oob_msg;
292
293 if (pipe->rerr == ___FIX(___NO_ERR)(((long)(0))<<2))
294 {
295 SetEvent (pipe->revent); /* ignore error */
296 ResetEvent (pipe->wevent); /* ignore error */
297 }
298
299 ReleaseMutex (pipe->mutex); /* ignore error */
300
301 return ___FIX(___NO_ERR)(((long)(0))<<2);
302}
303
304___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_read_ready_wait
305 ___P((___nonblocking_pipe *pipe),(___nonblocking_pipe *pipe)
306 (pipe)(___nonblocking_pipe *pipe)
307___nonblocking_pipe *pipe;)(___nonblocking_pipe *pipe)
308{
309 ___SCMOBJlong werr;
310
311 if (WaitForSingleObject (pipe->revent, INFINITE) == WAIT_FAILED ||
312 WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
313 return err_code_from_GetLastError ()___err_code_from_GetLastError();
314
315 werr = pipe->werr;
316
317 if (werr != ___FIX(___NO_ERR)(((long)(0))<<2))
318 {
319 pipe->werr = ___FIX(___NO_ERR)(((long)(0))<<2);
320
321 if (pipe->rerr != ___FIX(___NO_ERR)(((long)(0))<<2) ||
322 (pipe->rd == pipe->wr && !pipe->oob))
323 ResetEvent (pipe->revent); /* ignore error */
324 }
325
326 ReleaseMutex (pipe->mutex); /* ignore error */
327
328 return werr;
329}
330
331___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_write_ready_wait
332 ___P((___nonblocking_pipe *pipe),(___nonblocking_pipe *pipe)
333 (pipe)(___nonblocking_pipe *pipe)
334___nonblocking_pipe *pipe;)(___nonblocking_pipe *pipe)
335{
336 ___SCMOBJlong rerr;
337
338 if (WaitForSingleObject (pipe->wevent, INFINITE) == WAIT_FAILED ||
339 WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
340 return err_code_from_GetLastError ()___err_code_from_GetLastError();
341
342 rerr = pipe->rerr;
343
344 if (rerr != ___FIX(___NO_ERR)(((long)(0))<<2))
345 {
346 pipe->rerr = ___FIX(___NO_ERR)(((long)(0))<<2);
347
348 ResetEvent (pipe->wevent); /* ignore error */
349 }
350
351 ReleaseMutex (pipe->mutex); /* ignore error */
352
353 return rerr;
354}
355
356___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_read
357 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
358 ___U8 *buf,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
359 ___stream_index len,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
360 ___stream_index *len_done,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
361 ___nonblocking_pipe_oob_msg *oob_msg),(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
362 (pipe,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
363 buf,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
364 len,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
365 len_done,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
366 oob_msg)(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
367___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
368___U8 *buf;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
369___stream_index len;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
370___stream_index *len_done;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
371___nonblocking_pipe_oob_msg *oob_msg;)(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done, ___nonblocking_pipe_oob_msg *
oob_msg)
372{
373 ___SCMOBJlong rerr;
374 ___SCMOBJlong werr;
375 DWORD rd;
376 DWORD wr;
377 ___U8unsigned char *p;
378 DWORD end;
379 DWORD n;
380 DWORD i;
381
382 if (len <= 0)
383 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
384
385 if (WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
386 return err_code_from_GetLastError ()___err_code_from_GetLastError();
387
388 rerr = pipe->rerr;
389 werr = pipe->werr;
390 rd = pipe->rd;
391 wr = pipe->wr;
392
393 if (rerr != ___FIX(___NO_ERR)(((long)(0))<<2))
394 {
395 /* there is a reader error */
396
397 if (werr == ___FIX(___NO_ERR)(((long)(0))<<2))
398 werr = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
399 else
400 {
401 pipe->werr = ___FIX(___NO_ERR)(((long)(0))<<2);
402 ResetEvent (pipe->revent); /* ignore error */
403 }
404 ReleaseMutex (pipe->mutex); /* ignore error */
405 return werr;
406 }
407
408 /* there is no reader error */
409
410 if (rd == wr)
411 {
412 /* no bytes in FIFO buffer */
413
414 if (pipe->oob)
415 {
416 /* out-of-band present */
417
418 *oob_msg = pipe->oob_msg;
419 pipe->oob = 0;
420 if (werr == ___FIX(___NO_ERR)(((long)(0))<<2))
421 {
422 ResetEvent (pipe->revent); /* ignore error */
423#if 0
424 /******************zzzzzzzzzzzzzz****/
425 SetEvent (pipe->wevent); /* ignore error */
426#endif
427 }
428 ReleaseMutex (pipe->mutex); /* ignore error */
429 *len_done = 0;
430 return ___FIX(___NO_ERR)(((long)(0))<<2);
431 }
432
433 /* out-of-band not present */
434
435 if (werr != ___FIX(___NO_ERR)(((long)(0))<<2))
436 {
437 /* there is a writer error */
438
439 pipe->werr = ___FIX(___NO_ERR)(((long)(0))<<2);
440
441 ResetEvent (pipe->revent); /* ignore error */
442 ReleaseMutex (pipe->mutex); /* ignore error */
443 return werr;
444 }
445
446 /* there is no writer error */
447
448 SetEvent (pipe->wevent); /* ignore error */
449 ReleaseMutex (pipe->mutex); /* ignore error */
450 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
451 }
452
453 /* at least one byte in FIFO buffer */
454
455 end = pipe->size - rd; /* number of bytes from rd to end */
456
457 n = wr + end; /* number of bytes available */
458 if (n >= pipe->size)
459 n -= pipe->size;
460
461 if (n > ___CAST(DWORD,len)((DWORD)(len))) /* don't transfer more than len */
462 n = len;
463
464 *len_done = n;
465
466 p = pipe->buffer + rd; /* prepare transfer source */
467
468 rd = rd + n;
469 if (rd >= pipe->size)
470 rd -= pipe->size;
471
472 pipe->rd = rd;
473
474 if (werr == ___FIX(___NO_ERR)(((long)(0))<<2) && !pipe->oob)
475 {
476 /* there is no writer error and out-of-band not present */
477
478 if (rd == wr) /* the FIFO will be empty? */
479 ResetEvent (pipe->revent); /* ignore error */
480
481 /* the FIFO will not be full */
482
483 SetEvent (pipe->wevent); /* ignore error */
484 }
485
486 if (n <= end)
487 {
488 /* only need to transfer n bytes starting from original rd */
489
490 for (i=n; i>0; i--)
491 *buf++ = *p++;
492 }
493 else
494 {
495 /* need to transfer end bytes starting from original rd */
496
497 for (i=end; i>0; i--)
498 *buf++ = *p++;
499
500 /* and to transfer n-end bytes starting from 0 */
501
502 p = pipe->buffer;
503
504 for (i=n-end; i>0; i--)
505 *buf++ = *p++;
506 }
507
508 ReleaseMutex (pipe->mutex); /* ignore error */
509
510 return ___FIX(___NO_ERR)(((long)(0))<<2);
511}
512
513___HIDDENstatic ___SCMOBJlong ___nonblocking_pipe_write
514 ___P((___nonblocking_pipe *pipe,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
515 ___U8 *buf,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
516 ___stream_index len,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
517 ___stream_index *len_done),(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
518 (pipe,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
519 buf,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
520 len,(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
521 len_done)(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
522___nonblocking_pipe *pipe;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
523___U8 *buf;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
524___stream_index len;(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
525___stream_index *len_done;)(___nonblocking_pipe *pipe, unsigned char *buf, ___stream_index
len, ___stream_index *len_done)
526{
527 ___SCMOBJlong rerr;
528 ___SCMOBJlong werr;
529 DWORD rd;
530 DWORD wr;
531 ___U8unsigned char *p;
532 DWORD end;
533 DWORD n;
534 DWORD i;
535
536 if (len <= 0)
537 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
538
539 if (WaitForSingleObject (pipe->mutex, INFINITE) == WAIT_FAILED)
540 return err_code_from_GetLastError ()___err_code_from_GetLastError();
541
542 rerr = pipe->rerr;
543 werr = pipe->werr;
544 rd = pipe->rd;
545 wr = pipe->wr;
546
547 if (werr != ___FIX(___NO_ERR)(((long)(0))<<2))
548 {
549 /* there is a writer error */
550
551 if (rerr == ___FIX(___NO_ERR)(((long)(0))<<2))
552 rerr = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
553 else
554 {
555 pipe->rerr = ___FIX(___NO_ERR)(((long)(0))<<2);
556 ResetEvent (pipe->wevent); /* ignore error */
557 }
558 ReleaseMutex (pipe->mutex); /* ignore error */
559 return rerr;
560 }
561
562 /* there is no writer error */
563
564 if (rerr != ___FIX(___NO_ERR)(((long)(0))<<2))
565 {
566 /* there is a reader error */
567
568 pipe->rerr = ___FIX(___NO_ERR)(((long)(0))<<2);
569
570 if (rd != wr || pipe->oob) /* FIFO is not empty */
571 SetEvent (pipe->revent); /* ignore error */
572
573 ResetEvent (pipe->wevent); /* ignore error */
574 ReleaseMutex (pipe->mutex); /* ignore error */
575 return rerr;
576 }
577
578 /* there is no reader error */
579
580 if (wr + 1 - rd == 0 || wr + 1 - rd == pipe->size || pipe->oob)
581 {
582 /* FIFO buffer is full or out-of-band present */
583
584 ReleaseMutex (pipe->mutex); /* ignore error */
585 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
586 }
587
588 /* FIFO buffer is not full and out-of-band not present */
589
590 end = pipe->size - wr; /* number of bytes from wr to end */
591
592 n = rd + end - 1; /* number of bytes available */
593 if (n >= pipe->size)
594 n -= pipe->size;
595
596 if (n > ___CAST(DWORD,len)((DWORD)(len))) /* don't transfer more than len */
597 n = len;
598
599 *len_done = n;
600
601 p = pipe->buffer + wr; /* prepare transfer source */
602
603 wr = wr + n;
604 if (wr >= pipe->size)
605 wr -= pipe->size;
606
607 pipe->wr = wr;
608
609 if (wr + 1 - rd == 0 || wr + 1 - rd == pipe->size) /* FIFO will be full? */
610 ResetEvent (pipe->wevent); /* ignore error */
611
612 /* FIFO will not be empty */
613
614 SetEvent (pipe->revent); /* ignore error */
615
616 if (n <= end)
617 {
618 /* only need to transfer n bytes starting from original wr */
619
620 for (i=n; i>0; i--)
621 *p++ = *buf++;
622 }
623 else
624 {
625 /* need to transfer end bytes starting from original wr */
626
627 for (i=end; i>0; i--)
628 *p++ = *buf++;
629
630 /* and to transfer n-end bytes starting from 0 */
631
632 p = pipe->buffer;
633
634 for (i=n-end; i>0; i--)
635 *p++ = *buf++;
636 }
637
638 ReleaseMutex (pipe->mutex); /* ignore error */
639
640 return ___FIX(___NO_ERR)(((long)(0))<<2);
641}
642
643#endif
644
645
646/*---------------------------------------------------------------------------*/
647
648/* Operations on I/O devices. */
649
650/* Miscellaneous utility functions. */
651
652#ifdef USE_POSIX
653
654
655#ifdef USE_sigaction
656typedef sigset_t sigset_type;
657#else
658typedef int sigset_type;
659#endif
660
661
662___HIDDENstatic sigset_type block_signal
663 ___P((int signum),(int signum)
664 (signum)(int signum)
665int signum;)(int signum)
666{
667 sigset_type oldmask;
668
669#ifdef USE_sigaction
670
671 sigset_type toblock;
672
673 sigemptyset (&toblock);
674 sigaddset (&toblock, signum);
675 sigprocmask (SIG_BLOCK0, &toblock, &oldmask);
676
677#endif
678
679#ifdef USE_signal
680
681 oldmask = sigblock (sigmask (signum)(((unsigned long int) 1) << (((signum) - 1) % (8 * sizeof
(unsigned long int))))
);
682
683#endif
684
685 return oldmask;
686}
687
688
689___HIDDENstatic void restore_sigmask
690 ___P((sigset_type oldmask),(sigset_type oldmask)
691 (oldmask)(sigset_type oldmask)
692sigset_type oldmask;)(sigset_type oldmask)
693{
694#ifdef USE_sigaction
695
696 sigprocmask (SIG_SETMASK2, &oldmask, 0);
697
698#endif
699
700#ifdef USE_signal
701
702 sigsetmask (oldmask);
703
704#endif
705}
706
707
708/*
709 * Some system calls can be interrupted by a signal and fail with
710 * errno == EINTR. The following functions are wrappers for system
711 * calls which may be interrupted. They simply ignore the EINTR and
712 * retry the operation.
713 *
714 * TODO: add wrappers for all the system calls which can fail
715 * with EINTR. Also, move these functions to a central place.
716 */
717
718pid_t waitpid_no_EINTR
719 ___P((pid_t pid,(pid_t pid, int *stat_loc, int options)
720 int *stat_loc,(pid_t pid, int *stat_loc, int options)
721 int options),(pid_t pid, int *stat_loc, int options)
722 (pid,(pid_t pid, int *stat_loc, int options)
723 stat_loc,(pid_t pid, int *stat_loc, int options)
724 options)(pid_t pid, int *stat_loc, int options)
725pid_t pid;(pid_t pid, int *stat_loc, int options)
726int *stat_loc;(pid_t pid, int *stat_loc, int options)
727int options;)(pid_t pid, int *stat_loc, int options)
728{
729 pid_t result;
730
731 for (;;)
732 {
733 result = waitpid (pid, stat_loc, options);
734 if (result >= 0 || errno(*__errno_location ()) != EINTR4)
735 break;
736 }
737
738 return result;
739}
740
741
742___SSIZE_Tlong read_no_EINTR
743 ___P((int fd,(int fd, void *buf, unsigned long len)
744 void *buf,(int fd, void *buf, unsigned long len)
745 ___SIZE_T len),(int fd, void *buf, unsigned long len)
746 (fd,(int fd, void *buf, unsigned long len)
747 buf,(int fd, void *buf, unsigned long len)
748 len)(int fd, void *buf, unsigned long len)
749int fd;(int fd, void *buf, unsigned long len)
750void *buf;(int fd, void *buf, unsigned long len)
751___SIZE_T len;)(int fd, void *buf, unsigned long len)
752{
753 char *p = ___CAST(char*,buf)((char*)(buf));
754 ___SSIZE_Tlong result = 0;
755 int n;
756
757 while (result < len)
758 {
759 n = read (fd, p+result, len-result);
760 if (n > 0)
761 result += n;
762 else if (n == 0)
763 break;
764 else if (errno(*__errno_location ()) != EINTR4)
765 return n; /* this forgets that some bytes were transferred */
766 }
767
768 return result;
769}
770
771
772int close_no_EINTR
773 ___P((int fd),(int fd)
774 (fd)(int fd)
775int fd;)(int fd)
776{
777 int result;
778
779 for (;;)
780 {
781 result = close (fd);
782 if (result >= 0 || errno(*__errno_location ()) != EINTR4)
783 break;
784 }
785
786 return result;
787}
788
789
790int dup_no_EINTR
791 ___P((int fd),(int fd)
792 (fd)(int fd)
793int fd;)(int fd)
794{
795 int result;
796
797 for (;;)
798 {
799 result = dup (fd);
800 if (result >= 0 || errno(*__errno_location ()) != EINTR4)
801 break;
802 }
803
804 return result;
805}
806
807
808int dup2_no_EINTR
809 ___P((int fd,(int fd, int fd2)
810 int fd2),(int fd, int fd2)
811 (fd,(int fd, int fd2)
812 fd2)(int fd, int fd2)
813int fd;(int fd, int fd2)
814int fd2;)(int fd, int fd2)
815{
816 int result;
817
818 for (;;)
819 {
820 result = dup2 (fd, fd2);
821 if (result >= 0 || errno(*__errno_location ()) != EINTR4)
822 break;
823 }
824
825 return result;
826}
827
828
829int set_fd_blocking_mode
830 ___P((int fd,(int fd, int blocking)
831 ___BOOL blocking),(int fd, int blocking)
832 (fd,(int fd, int blocking)
833 blocking)(int fd, int blocking)
834int fd;(int fd, int blocking)
835___BOOL blocking;)(int fd, int blocking)
836{
837 int fl;
838
839#ifdef USE_fcntl
840
841 if ((fl = fcntl (fd, F_GETFL3, 0)) >= 0)
842 fl = fcntl (fd,
843 F_SETFL4,
844 blocking ? (fl & ~O_NONBLOCK04000) : (fl | O_NONBLOCK04000));
845
846#else
847
848 fl = 0;
849
850#endif
851
852 return fl;
853}
854
855#endif
856
857
858/*---------------------------------------------------------------------------*/
859
860/* Generic device operations. */
861
862___SCMOBJlong ___device_select
863 ___P((___device **devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
864 int nb_read_devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
865 int nb_write_devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
866 ___time timeout),(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
867 (devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
868 nb_read_devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
869 nb_write_devs,(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
870 timeout)(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
871___device **devs;(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
872int nb_read_devs;(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
873int nb_write_devs;(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
874___time timeout;)(___device **devs, int nb_read_devs, int nb_write_devs, ___time
timeout)
875{
876 int nb_devs;
877 ___device_select_state state;
878 int pass;
879 int dev_list;
880 int i;
881 int prev;
882 ___time delta;
883
884 nb_devs = nb_read_devs + nb_write_devs;
885
886 state.devs = devs;
887
888 state.timeout = timeout;
889 state.relative_timeout = POS_INFINITY(1.7976931348623157e308);
890
891#ifdef USE_select
892
893 state.highest_fd_plus_1 = 0;
894
895 ___FD_ZERO(&state.readfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&state.readfds)->__fds_bits
)[0]) : "memory"); } while (0)
;
896 ___FD_ZERO(&state.writefds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&state.writefds)->__fds_bits
)[0]) : "memory"); } while (0)
;
897 ___FD_ZERO(&state.exceptfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&state.exceptfds)->__fds_bits
)[0]) : "memory"); } while (0)
;
898
899#endif
900
901#ifdef USE_poll
902
903 state.pollfd_count = 0;
904 ___FD_ZERO (&state.readfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&state.readfds)->__fds_bits
)[0]) : "memory"); } while (0)
;
905 ___FD_ZERO (&state.writefds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&state.writefds)->__fds_bits
)[0]) : "memory"); } while (0)
;
906
907#endif
908
909#ifdef USE_MsgWaitForMultipleObjects
910
911 state.message_queue_mask = 0;
912 state.message_queue_dev_pos = -1;
913
914 state.wait_objs_buffer[0] = ___io_mod.abort_select;
915 state.wait_objs_buffer[1] = ___time_mod.heartbeat_thread;
916
917 state.nb_wait_objs = 2;
918
919#endif
920
921 if (nb_devs > 0)
922 {
923 state.devs_next[nb_devs-1] = -1;
924
925 for (i=nb_devs-2; i>=0; i--)
926 state.devs_next[i] = i+1;
927
928 dev_list = 0;
929 }
930 else
931 dev_list = -1;
932
933 pass = ___SELECT_PASS_11;
934
935 while (dev_list != -1)
936 {
937 i = dev_list;
938 prev = -1;
939
940 while (i != -1)
941 {
942 ___SCMOBJlong e;
943 ___device *d = devs[i];
944 if ((e = ___device_select_virt((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
945 (d,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
946 i>=nb_read_devs,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
947 i,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
948 pass,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
949 &state)((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,pass,&state)
)
950 == ___FIX(___NO_ERR)(((long)(0))<<2))
951 {
952 prev = i;
953 i = state.devs_next[i];
954 }
955 else
956 {
957 int j;
958 if (e != ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
)
959 return e;
960 j = state.devs_next[i];
961 if (prev == -1)
962 dev_list = j;
963 else
964 state.devs_next[prev] = j;
965#ifdef USE_MsgWaitForMultipleObjects
966 state.devs_next[i] = -1;
967#endif
968 i = j;
969 }
970 }
971
972 pass++;
973 }
974
975 ___absolute_time_to_relative_time (state.timeout, &delta);
976
977 if (___time_less (state.relative_timeout, delta))
978 {
979 delta = state.relative_timeout;
980 state.timeout = ___time_mod.time_neg_infinity;
981 }
982 else
983 state.relative_timeout = NEG_INFINITY(-1.7976931348623157e308);
984
985#ifdef USE_select
986
987 {
988 struct timeval delta_tv_struct;
989 struct timeval *delta_tv = &delta_tv_struct;
990 int result;
991
992 ___absolute_time_to_nonnegative_timeval (delta, &delta_tv);
993
994 if (delta_tv != NULL((void*)0) &&
995 state.highest_fd_plus_1 == 0)
996 {
997 /*
998 * ___device_select is only being called for sleeping until a
999 * certain timeout or interrupt occurs. This is a case that
1000 * can be optimized.
1001 */
1002
1003 if (delta_tv->tv_sec < 0 ||
1004 (delta_tv->tv_sec == 0 &&
1005 delta_tv->tv_usec == 0))
1006 {
1007 /*
1008 * The timeout has already passed, so we don't need to
1009 * sleep. This simple optimization avoids doing a system
1010 * call to the select or nanosleep functions (which can be
1011 * expensive on some operating systems).
1012 */
1013
1014 result = 0;
1015
1016 goto select_done;
1017 }
1018#ifdef USE_nanosleep
1019 else
1020 {
1021
1022 /*
1023 * For better timeout resolution, the nanosleep function
1024 * is used instead of the select function. On some
1025 * operating systems (e.g. OpenBSD 4.5) the nanosleep
1026 * function can be more expensive than a call to select,
1027 * but the better timeout resolution outweighs the run
1028 * time cost.
1029 */
1030
1031 struct timespec delta_ts_struct;
1032 delta_ts_struct.tv_sec = delta_tv->tv_sec;
1033 delta_ts_struct.tv_nsec = delta_tv->tv_usec * 1000;
1034 result = nanosleep (&delta_ts_struct, NULL((void*)0));
1035
1036 goto select_done;
1037 }
1038#endif
1039 }
1040
1041 /*
1042 * Heartbeat interrupts must be disabled in case they are based on the
1043 * real-time timer. This is needed to bypass issues in two buggy
1044 * operating systems:
1045 *
1046 * - On MacOS X, the virtual-time timer does not fire at the correct
1047 * rate (apparently this happens only on machines with more than
1048 * one core).
1049 *
1050 * - On CYGWIN, the select system call can be interrupted by the
1051 * timer and in some cases the error "No child processes" will
1052 * be returned by select.
1053 */
1054
1055 ___disable_heartbeat_interrupts ();
1056
1057 result =
1058 select (state.highest_fd_plus_1,
1059 &state.readfds,
1060 &state.writefds,
1061 &state.exceptfds,
1062 delta_tv);
1063
1064 ___enable_heartbeat_interrupts ();
1065
1066 select_done:
1067
1068 if (result < 0)
1069 return err_code_from_errno ()___err_code_from_errno();
1070
1071 state.timeout_reached = (result == 0);
1072 }
1073
1074#endif
1075
1076#ifdef USE_poll
1077 {
1078 struct timeval delta_tv_struct;
1079 struct timeval *delta_tv = &delta_tv_struct;
1080
1081#ifdef USE_ppoll
1082 struct timespec delta_ts_struct;
1083 struct timespec *delta_ts;
1084#else
1085 int delta_msecs;
1086#endif
1087 int result;
1088
1089 ___absolute_time_to_nonnegative_timeval (delta, &delta_tv);
1090
1091 /* pure sleep optimizations */
1092 if (state.pollfd_count == 0 && delta_tv != NULL((void*)0))
1093 {
1094 if (delta_tv->tv_sec < 0 ||
1095 (delta_tv->tv_sec == 0 &&
1096 delta_tv->tv_usec == 0))
1097 {
1098 result = 0;
1099 goto poll_done;
1100 }
1101#ifdef USE_nanosleep
1102 else
1103 {
1104 struct timespec delta_ts_struct;
1105 delta_ts_struct.tv_sec = delta_tv->tv_sec;
1106 delta_ts_struct.tv_nsec = delta_tv->tv_usec * 1000;
1107
1108 result = nanosleep (&delta_ts_struct, NULL((void*)0));
1109
1110 goto poll_done;
1111 }
1112#endif
1113 }
1114
1115 /* setup timeout */
1116#ifdef USE_ppoll
1117
1118 if (delta_tv != NULL((void*)0))
1119 {
1120 /* ppoll doesn't like negative times */
1121 if (delta_tv->tv_sec < 0)
1122 {
1123 delta_ts_struct.tv_sec = 0;
1124 delta_ts_struct.tv_nsec = 0;
1125 }
1126 else
1127 {
1128 delta_ts_struct.tv_sec = delta_tv->tv_sec;
1129 delta_ts_struct.tv_nsec = delta_tv->tv_usec * 1000;
1130 }
1131
1132 delta_ts = &delta_ts_struct;
1133 }
1134 else
1135 delta_ts = NULL((void*)0);
1136
1137#else
1138
1139 if (delta_tv != NULL((void*)0))
1140 {
1141 if (delta_tv->tv_sec < 0)
1142 delta_msecs = 0;
1143 else if (delta_tv->tv_sec < (INT_MAX2147483647 / 1000))
1144 delta_msecs = delta_tv->tv_sec * 1000 + delta_tv->tv_usec / 1000;
1145 else
1146 delta_msecs = INT_MAX2147483647;
1147 }
1148 else
1149 delta_msecs = -1;
1150
1151#endif
1152
1153 /* see comments on select above regarding heartbeat interrupts */
1154 ___disable_heartbeat_interrupts ();
1155
1156#ifdef USE_ppoll
1157 result = ppoll (state.pollfds, state.pollfd_count, delta_ts, NULL((void*)0));
1158#else
1159 result = poll (state.pollfds, state.pollfd_count, delta_msecs);
1160#endif
1161
1162 ___enable_heartbeat_interrupts ();
1163
1164 /* Set the active bitmaps */
1165 if (result > 0)
1166 {
1167 int errmask = (POLLERR | POLLHUP | POLLNVAL);
1168 int active = result;
1169 int x;
1170
1171 for (x = 0; active > 0; ++x)
1172 {
1173 if (state.pollfds[x].revents)
1174 {
1175 if (state.pollfds[x].events & POLLIN)
1176 {
1177 if (state.pollfds[x].revents & (POLLIN | errmask))
1178 ___FD_SET (state.pollfds[x].fd, &state.readfds)((void) (((&state.readfds)->__fds_bits)[((state.pollfds
[x].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 <<
((state.pollfds[x].fd) % (8 * (int) sizeof (__fd_mask))))))
;
1179 }
1180
1181 if (state.pollfds[x].events & POLLOUT)
1182 {
1183 if (state.pollfds[x].revents & (POLLOUT | errmask))
1184 ___FD_SET (state.pollfds[x].fd, &state.writefds)((void) (((&state.writefds)->__fds_bits)[((state.pollfds
[x].fd) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 <<
((state.pollfds[x].fd) % (8 * (int) sizeof (__fd_mask))))))
;
1185 }
1186
1187 --active;
1188 }
1189 }
1190 }
1191
1192 poll_done:
1193
1194 if (result < 0)
1195 return err_code_from_errno ()___err_code_from_errno();
1196
1197 state.timeout_reached = (result == 0);
1198 }
1199#endif
1200
1201#ifdef USE_MsgWaitForMultipleObjects
1202
1203 {
1204 DWORD delta_msecs;
1205 int first_iteration = TRUE;
1206
1207 ___absolute_time_to_nonnegative_msecs (delta, &delta_msecs);
1208
1209 state.timeout_reached = 0;
1210
1211 while (state.nb_wait_objs > 0 || state.message_queue_mask != 0)
1212 {
1213 DWORD n;
1214
1215 n = MsgWaitForMultipleObjects
1216 (state.nb_wait_objs,
1217 state.wait_objs_buffer,
1218 FALSE,
1219 delta_msecs,
1220 state.message_queue_mask);
1221
1222 if (n == WAIT_FAILED)
1223 return err_code_from_GetLastError ()___err_code_from_GetLastError();
1224
1225 if ((n - WAIT_OBJECT_0) <= WAIT_OBJECT_0 + state.nb_wait_objs)
1226 n -= WAIT_OBJECT_0;
1227 else if (n >= WAIT_ABANDONED_0 &&
1228 n <= WAIT_ABANDONED_0+state.nb_wait_objs-1)
1229 n -= WAIT_ABANDONED_0;
1230 else
1231 {
1232 /* n == WAIT_TIMEOUT */
1233
1234 /*
1235 * The call to MsgWaitForMultipleObjects timed out. Mark
1236 * the appropriate device "ready".
1237 */
1238
1239 if (first_iteration)
1240 {
1241 /* first call to MsgWaitForMultipleObjects */
1242
1243 state.timeout_reached = 1;
1244 }
1245
1246 break;
1247 }
1248
1249 if (n == state.nb_wait_objs)
1250 {
1251 /*
1252 * The message queue contains a message that is of interest.
1253 * Mark the appropriate device "ready".
1254 */
1255
1256 i = state.message_queue_dev_pos;
1257 if (i >= 0)
1258 state.devs_next[i] = 0;
1259
1260 /*
1261 * Don't check if other devices are ready because this might
1262 * cause an infinite loop.
1263 */
1264
1265 break;
1266 }
1267 else if (n == 0)
1268 {
1269 /*
1270 * The call to ___device_select must be aborted because the
1271 * abort_select event is set. This occurs when an interrupt
1272 * (such as a CTRL-C user interrupt) needs to be serviced
1273 * promptly by the main program.
1274 */
1275
1276 ResetEvent (___io_mod.abort_select); /* ignore error */
1277
1278 return ___FIX(___ERRNO_ERR(EINTR))(((long)(((4)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(4)))))<<2)
;
1279 }
1280 else if (n == 1)
1281 {
1282 /*
1283 * The heartbeat thread has died. This is normally due to
1284 * the program being terminated abruptly by the user (for
1285 * example by using the thread manager or the "shutdown"
1286 * item in the start menu). When this happens we must
1287 * initiate a clean termination of the program.
1288 */
1289
1290 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
1291 }
1292 else
1293 {
1294 /* Mark the appropriate device "ready". */
1295
1296 i = state.wait_obj_to_dev_pos[n];
1297 if (i >= 0)
1298 state.devs_next[i] = 0;
1299
1300 /* Prepare to check remaining devices. */
1301
1302 state.nb_wait_objs--;
1303
1304 state.wait_objs_buffer[n] =
1305 state.wait_objs_buffer[state.nb_wait_objs];
1306
1307 state.wait_obj_to_dev_pos[n] =
1308 state.wait_obj_to_dev_pos[state.nb_wait_objs];
1309 }
1310
1311 first_iteration = FALSE;
1312 delta_msecs = 0; /* next MsgWaitForMultipleObjects will only poll */
1313 }
1314 }
1315
1316#endif
1317
1318 for (i=nb_devs-1; i>=0; i--)
1319 {
1320 ___SCMOBJlong e;
1321 ___device *d = devs[i];
1322 if (d != NULL((void*)0))
1323 if ((e = ___device_select_virt((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
1324 (d,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
1325 i>=nb_read_devs,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
1326 i,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
1327 ___SELECT_PASS_CHECK,((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
1328 &state)((___device_vtbl*)((d)->vtbl))->select_virt(d,i>=nb_read_devs
,i,0,&state)
)
1329 != ___FIX(___NO_ERR)(((long)(0))<<2))
1330 return e;
1331 }
1332
1333 return ___FIX(___NO_ERR)(((long)(0))<<2);
1334}
1335
1336
1337void ___device_select_add_relative_timeout
1338 ___P((___device_select_state *state,(___device_select_state *state, int i, double seconds)
1339 int i,(___device_select_state *state, int i, double seconds)
1340 ___F64 seconds),(___device_select_state *state, int i, double seconds)
1341 (state,(___device_select_state *state, int i, double seconds)
1342 i,(___device_select_state *state, int i, double seconds)
1343 seconds)(___device_select_state *state, int i, double seconds)
1344___device_select_state *state;(___device_select_state *state, int i, double seconds)
1345int i;(___device_select_state *state, int i, double seconds)
1346___F64 seconds;)(___device_select_state *state, int i, double seconds)
1347{
1348 if (seconds < state->relative_timeout)
1349 state->relative_timeout = seconds;
1350}
1351
1352
1353void ___device_select_add_timeout
1354 ___P((___device_select_state *state,(___device_select_state *state, int i, ___time timeout)
1355 int i,(___device_select_state *state, int i, ___time timeout)
1356 ___time timeout),(___device_select_state *state, int i, ___time timeout)
1357 (state,(___device_select_state *state, int i, ___time timeout)
1358 i,(___device_select_state *state, int i, ___time timeout)
1359 timeout)(___device_select_state *state, int i, ___time timeout)
1360___device_select_state *state;(___device_select_state *state, int i, ___time timeout)
1361int i;(___device_select_state *state, int i, ___time timeout)
1362___time timeout;)(___device_select_state *state, int i, ___time timeout)
1363{
1364 if (___time_less (timeout, state->timeout))
1365 state->timeout = timeout;
1366}
1367
1368
1369#ifdef USE_select
1370
1371void ___device_select_add_fd
1372 ___P((___device_select_state *state,(___device_select_state *state, int fd, int for_writing)
1373 int fd,(___device_select_state *state, int fd, int for_writing)
1374 ___BOOL for_writing),(___device_select_state *state, int fd, int for_writing)
1375 (state,(___device_select_state *state, int fd, int for_writing)
1376 fd,(___device_select_state *state, int fd, int for_writing)
1377 for_writing)(___device_select_state *state, int fd, int for_writing)
1378___device_select_state *state;(___device_select_state *state, int fd, int for_writing)
1379int fd;(___device_select_state *state, int fd, int for_writing)
1380___BOOL for_writing;)(___device_select_state *state, int fd, int for_writing)
1381{
1382 if (for_writing)
1383 ___FD_SET(fd, &state->writefds)((void) (((&state->writefds)->__fds_bits)[((fd) / (
8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((
fd) % (8 * (int) sizeof (__fd_mask))))))
;
1384 else
1385 ___FD_SET(fd, &state->readfds)((void) (((&state->readfds)->__fds_bits)[((fd) / (8
* (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((fd
) % (8 * (int) sizeof (__fd_mask))))))
;
1386
1387 if (fd >= state->highest_fd_plus_1)
1388 state->highest_fd_plus_1 = fd+1;
1389}
1390
1391#endif
1392
1393#ifdef USE_poll
1394
1395void ___device_select_add_fd
1396 ___P((___device_select_state *state,(___device_select_state *state, int fd, int for_writing)
1397 int fd,(___device_select_state *state, int fd, int for_writing)
1398 ___BOOL for_writing),(___device_select_state *state, int fd, int for_writing)
1399 (state,(___device_select_state *state, int fd, int for_writing)
1400 fd,(___device_select_state *state, int fd, int for_writing)
1401 for_writing)(___device_select_state *state, int fd, int for_writing)
1402___device_select_state *state;(___device_select_state *state, int fd, int for_writing)
1403int fd;(___device_select_state *state, int fd, int for_writing)
1404___BOOL for_writing;)(___device_select_state *state, int fd, int for_writing)
1405{
1406 state->pollfds[state->pollfd_count].fd = fd;
1407
1408 if (for_writing)
1409 state->pollfds[state->pollfd_count].events = POLLOUT;
1410 else
1411 state->pollfds[state->pollfd_count].events = POLLIN;
1412
1413 ++state->pollfd_count;
1414}
1415
1416#endif
1417
1418
1419#ifdef USE_MsgWaitForMultipleObjects
1420
1421void ___device_select_add_wait_obj
1422 ___P((___device_select_state *state,(___device_select_state *state, int i, HANDLE wait_obj)
1423 int i,(___device_select_state *state, int i, HANDLE wait_obj)
1424 HANDLE wait_obj),(___device_select_state *state, int i, HANDLE wait_obj)
1425 (state,(___device_select_state *state, int i, HANDLE wait_obj)
1426 i,(___device_select_state *state, int i, HANDLE wait_obj)
1427 wait_obj)(___device_select_state *state, int i, HANDLE wait_obj)
1428___device_select_state *state;(___device_select_state *state, int i, HANDLE wait_obj)
1429int i;(___device_select_state *state, int i, HANDLE wait_obj)
1430HANDLE wait_obj;)(___device_select_state *state, int i, HANDLE wait_obj)
1431{
1432 DWORD j = state->nb_wait_objs;
1433
1434 if (j < MAXIMUM_WAIT_OBJECTS)
1435 {
1436 state->wait_objs_buffer[j] = wait_obj;
1437 state->wait_obj_to_dev_pos[j] = i;
1438 state->nb_wait_objs = j+1;
1439 }
1440}
1441
1442#endif
1443
1444
1445___SCMOBJlong ___device_force_output
1446 ___P((___device *self,(___device *self, int level)
1447 int level),(___device *self, int level)
1448 (self,(___device *self, int level)
1449 level)(___device *self, int level)
1450___device *self;(___device *self, int level)
1451int level;)(___device *self, int level)
1452{
1453 return ___device_force_output_virt (self, level)((___device_vtbl*)((self)->vtbl))->force_output_virt(self
,level)
;
1454}
1455
1456___SCMOBJlong ___device_close
1457 ___P((___device *self,(___device *self, int direction)
1458 int direction),(___device *self, int direction)
1459 (self,(___device *self, int direction)
1460 direction)(___device *self, int direction)
1461___device *self;(___device *self, int direction)
1462int direction;)(___device *self, int direction)
1463{
1464 return ___device_close_virt (self, direction)((___device_vtbl*)((self)->vtbl))->close_virt(self,direction
)
;
1465}
1466
1467___HIDDENstatic void device_transfer_close_responsibility
1468 ___P((___device *self),(___device *self)
1469 (self)(___device *self)
1470___device *self;)(___device *self)
1471{
1472 /*
1473 * Transfer responsibility for closing device to the runtime system.
1474 */
1475
1476 self->close_direction = self->direction;
1477}
1478
1479___HIDDENstatic void device_add_ref
1480 ___P((___device *self),(___device *self)
1481 (self)(___device *self)
1482___device *self;)(___device *self)
1483{
1484#ifdef USE_PUMPS
1485 InterlockedIncrement (&self->refcount);
1486#else
1487 self->refcount++;
1488#endif
1489}
1490
1491___SCMOBJlong ___device_release
1492 ___P((___device *self),(___device *self)
1493 (self)(___device *self)
1494___device *self;)(___device *self)
1495{
1496 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
1497
1498 if (
1499#ifdef USE_PUMPS
1500 InterlockedDecrement (&self->refcount) == 0
1501#else
1502 --self->refcount == 0
1503#endif
1504 )
1505 {
1506 e = ___device_release_virt (self)((___device_vtbl*)((self)->vtbl))->release_virt(self);
1507 ___free_mem (self);
1508 }
1509
1510 return e;
1511}
1512
1513___SCMOBJlong ___device_cleanup
1514 ___P((___device *self),(___device *self)
1515 (self)(___device *self)
1516___device *self;)(___device *self)
1517{
1518 ___SCMOBJlong e;
1519 ___device *devs[1];
1520
1521 if (self->group == NULL((void*)0))
1522 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
1523
1524 ___device_remove_from_group (self);
1525
1526 for (;;)
1527 {
1528 e = ___device_close (self, ___DIRECTION_RD1);
1529 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
1530 break;
1531 if (e != ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
1532 return e;
1533
1534 devs[0] = self;
1535 e = ___device_select (devs, 1, 0, ___time_mod.time_pos_infinity);
1536 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
1537 return e;
1538 }
1539
1540 for (;;)
1541 {
1542 e = ___device_close (self, ___DIRECTION_WR2);
1543 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
1544 break;
1545 if (e != ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
1546 return e;
1547
1548 devs[0] = self;
1549 e = ___device_select (devs, 0, 1, ___time_mod.time_pos_infinity);
1550 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
1551 return e;
1552 }
1553
1554 return ___device_release (self);
1555}
1556
1557
1558/*
1559 * Procedure called by the Scheme runtime when a device is no longer
1560 * reachable.
1561 */
1562
1563___SCMOBJlong ___device_cleanup_from_ptr
1564 ___P((void *ptr),(void *ptr)
1565 (ptr)(void *ptr)
1566void *ptr;)(void *ptr)
1567{
1568 return ___device_cleanup (___CAST(___device*,ptr)((___device*)(ptr)));
1569}
1570
1571
1572/* - - - - - - - - - - - - - - - - - - */
1573
1574/* Timer device. */
1575
1576/*
1577 * Timer devices are not particularly useful, given that the scheduler
1578 * implements timeouts. Use this as an example.
1579 */
1580
1581___HIDDENstatic int device_timer_kind
1582 ___P((___device *self),(___device *self)
1583 (self)(___device *self)
1584___device *self;)(___device *self)
1585{
1586 return ___TIMER_KIND(1 +4096);
1587}
1588
1589___HIDDENstatic ___SCMOBJlong device_timer_select_virt
1590 ___P((___device *self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1591 ___BOOL for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1592 int i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1593 int pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1594 ___device_select_state *state),(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1595 (self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1596 for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1597 i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1598 pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1599 state)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1600___device *self;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1601___BOOL for_writing;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1602int i;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1603int pass;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1604___device_select_state *state;)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1605{
1606 ___device_timer *d = ___CAST(___device_timer*,self)((___device_timer*)(self));
1607
1608 if (pass == ___SELECT_PASS_11)
1609 {
1610 if (___time_less (d->expiry, state->timeout))
1611 state->timeout = d->expiry;
1612 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
1613 }
1614
1615 /* pass == ___SELECT_PASS_CHECK */
1616
1617 if (state->timeout_reached)
1618 {
1619 if (___time_equal (d->expiry, state->timeout))
1620 state->devs[i] = NULL((void*)0);
1621 }
1622
1623 return ___FIX(___NO_ERR)(((long)(0))<<2);
1624}
1625
1626___HIDDENstatic ___SCMOBJlong device_timer_release_virt
1627 ___P((___device *self),(___device *self)
1628 (self)(___device *self)
1629___device *self;)(___device *self)
1630{
1631 return ___FIX(___NO_ERR)(((long)(0))<<2);
1632}
1633
1634___HIDDENstatic ___SCMOBJlong device_timer_force_output_virt
1635 ___P((___device *self,(___device *self, int level)
1636 int level),(___device *self, int level)
1637 (self,(___device *self, int level)
1638 level)(___device *self, int level)
1639___device *self;(___device *self, int level)
1640int level;)(___device *self, int level)
1641{
1642 return ___FIX(___NO_ERR)(((long)(0))<<2);
1643}
1644
1645___HIDDENstatic ___SCMOBJlong device_timer_close_virt
1646 ___P((___device *self,(___device *self, int direction)
1647 int direction),(___device *self, int direction)
1648 (self,(___device *self, int direction)
1649 direction)(___device *self, int direction)
1650___device *self;(___device *self, int direction)
1651int direction;)(___device *self, int direction)
1652{
1653 return ___FIX(___NO_ERR)(((long)(0))<<2);
1654}
1655
1656___HIDDENstatic ___device_timer_vtbl ___device_timer_table =
1657{
1658 {
1659 device_timer_kind,
1660 device_timer_select_virt,
1661 device_timer_release_virt,
1662 device_timer_force_output_virt,
1663 device_timer_close_virt
1664 }
1665};
1666
1667___SCMOBJlong ___device_timer_setup
1668 ___P((___device_timer **dev,(___device_timer **dev, ___device_group *dgroup)
1669 ___device_group *dgroup),(___device_timer **dev, ___device_group *dgroup)
1670 (dev,(___device_timer **dev, ___device_group *dgroup)
1671 dgroup)(___device_timer **dev, ___device_group *dgroup)
1672___device_timer **dev;(___device_timer **dev, ___device_group *dgroup)
1673___device_group *dgroup;)(___device_timer **dev, ___device_group *dgroup)
1674{
1675 ___device_timer *d;
1676
1677 d = ___CAST(___device_timer*,((___device_timer*)(___alloc_mem (sizeof (___device_timer))))
1678 ___alloc_mem (sizeof (___device_timer)))((___device_timer*)(___alloc_mem (sizeof (___device_timer))));
1679
1680 if (d == NULL((void*)0))
1681 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
1682
1683 d->base.vtbl = &___device_timer_table;
1684 d->base.refcount = 1;
1685 d->base.direction = ___DIRECTION_RD1 | ___DIRECTION_WR2;
1686 d->base.close_direction = 0; /* prevent closing on errors */
1687 d->base.read_stage = ___STAGE_OPEN0;
1688 d->base.write_stage = ___STAGE_OPEN0;
1689
1690 d->expiry = ___time_mod.time_pos_infinity;
1691
1692 *dev = d;
1693
1694 ___device_add_to_group (dgroup, &d->base);
1695
1696 return ___FIX(___NO_ERR)(((long)(0))<<2);
1697}
1698
1699void ___device_timer_set_expiry
1700 ___P((___device_timer *dev,(___device_timer *dev, ___time expiry)
1701 ___time expiry),(___device_timer *dev, ___time expiry)
1702 (dev,(___device_timer *dev, ___time expiry)
1703 expiry)(___device_timer *dev, ___time expiry)
1704___device_timer *dev;(___device_timer *dev, ___time expiry)
1705___time expiry;)(___device_timer *dev, ___time expiry)
1706{
1707 dev->expiry = expiry;
1708}
1709
1710/* - - - - - - - - - - - - - - - - - - */
1711
1712/* Byte stream devices. */
1713
1714#ifdef USE_PUMPS
1715
1716___HIDDENstatic ___SCMOBJlong ___device_stream_pump_setup
1717 ___P((___device_stream_pump **pump,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1718 DWORD committed_stack_size,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1719 LPTHREAD_START_ROUTINE proc,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1720 LPVOID arg),(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1721 (pump,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1722 committed_stack_size,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1723 proc,(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1724 arg)(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1725___device_stream_pump **pump;(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1726DWORD committed_stack_size;(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1727LPTHREAD_START_ROUTINE proc;(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1728LPVOID arg;)(___device_stream_pump **pump, DWORD committed_stack_size, LPTHREAD_START_ROUTINE
proc, LPVOID arg)
1729{
1730 ___SCMOBJlong e;
1731 ___device_stream_pump *p;
1732 HANDLE thread_handle;
1733 DWORD thread_id;
1734
1735 p = ___CAST(___device_stream_pump*,((___device_stream_pump*)(___alloc_mem (sizeof (___device_stream_pump
))))
1736 ___alloc_mem (sizeof (___device_stream_pump)))((___device_stream_pump*)(___alloc_mem (sizeof (___device_stream_pump
))))
;
1737
1738 if (p == NULL((void*)0))
1739 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
1740
1741 e = ___nonblocking_pipe_setup (&p->pipe, PIPE_BUFFER_SIZE+1);
1742
1743 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
1744 {
1745 ___free_mem (p);
1746 return e;
1747 }
1748
1749 *pump = p; /* set before thread created to avoid race condition */
1750
1751 thread_handle =
1752 CreateThread (NULL((void*)0), /* no security attributes */
1753 committed_stack_size, /* committed stack size */
1754 proc, /* thread procedure */
1755 arg, /* argument to thread procedure */
1756 0, /* use default creation flags */
1757 &thread_id);
1758
1759 if (thread_handle == NULL((void*)0) ||
1760 !SetThreadPriority (thread_handle, PUMP_PRIORITY))
1761 {
1762 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
1763 ___nonblocking_pipe_cleanup (&p->pipe);
1764 ___free_mem (p);
1765 *pump = NULL((void*)0); /* make sure caller does not think a pump was created */
1766 return e;
1767 }
1768
1769 p->thread = thread_handle;
1770
1771 return ___FIX(___NO_ERR)(((long)(0))<<2);
1772}
1773
1774___HIDDENstatic ___SCMOBJlong ___device_stream_pump_reader_kill
1775 ___P((___device_stream_pump *pump),(___device_stream_pump *pump)
1776 (pump)(___device_stream_pump *pump)
1777___device_stream_pump *pump;)(___device_stream_pump *pump)
1778{
1779 return ___nonblocking_pipe_set_reader_err
1780 (&pump->pipe,
1781 ___FIX(___KILL_PUMP)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+13)))<<2)
);
1782}
1783
1784___HIDDENstatic ___SCMOBJlong ___device_stream_pump_writer_kill
1785 ___P((___device_stream_pump *pump),(___device_stream_pump *pump)
1786 (pump)(___device_stream_pump *pump)
1787___device_stream_pump *pump;)(___device_stream_pump *pump)
1788{
1789 return ___nonblocking_pipe_set_writer_err
1790 (&pump->pipe,
1791 ___FIX(___KILL_PUMP)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+13)))<<2)
);
1792}
1793
1794___HIDDENstatic ___SCMOBJlong ___device_stream_pump_wait
1795 ___P((___device_stream_pump *pump),(___device_stream_pump *pump)
1796 (pump)(___device_stream_pump *pump)
1797___device_stream_pump *pump;)(___device_stream_pump *pump)
1798{
1799 DWORD code;
1800
1801 code = WaitForSingleObject (pump->thread, 0);
1802
1803 if (code == WAIT_FAILED)
1804 return err_code_from_GetLastError ()___err_code_from_GetLastError();
1805
1806 if (code == WAIT_TIMEOUT)
1807 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
1808
1809 return ___FIX(___NO_ERR)(((long)(0))<<2);
1810}
1811
1812___HIDDENstatic ___SCMOBJlong ___device_stream_pump_cleanup
1813 ___P((___device_stream_pump *pump),(___device_stream_pump *pump)
1814 (pump)(___device_stream_pump *pump)
1815___device_stream_pump *pump;)(___device_stream_pump *pump)
1816{
1817 CloseHandle (pump->thread); /* ignore error */
1818 ___nonblocking_pipe_cleanup (&pump->pipe); /* ignore error */
1819 ___free_mem (pump);
1820
1821 return ___FIX(___NO_ERR)(((long)(0))<<2);
1822}
1823
1824#endif
1825
1826___SCMOBJlong ___device_stream_select_virt
1827 ___P((___device *self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1828 ___BOOL for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1829 int i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1830 int pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1831 ___device_select_state *state),(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1832 (self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1833 for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1834 i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1835 pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1836 state)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1837___device *self;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1838___BOOL for_writing;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1839int i;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1840int pass;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1841___device_select_state *state;)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
1842{
1843 ___device_stream *d = ___CAST(___device_stream*,self)((___device_stream*)(self));
1844
1845#ifdef USE_PUMPS
1846
1847 int stage = (for_writing
1848 ? d->base.write_stage
1849 : d->base.read_stage);
1850 ___device_stream_pump *p = (for_writing
1851 ? d->write_pump
1852 : d->read_pump);
1853
1854 if (p != NULL((void*)0))
1855 {
1856 if (pass == ___SELECT_PASS_11)
1857 {
1858 HANDLE wait_obj;
1859
1860 if (stage != ___STAGE_OPEN0)
1861 wait_obj = p->thread;
1862 else
1863 {
1864 if (for_writing)
1865 wait_obj = p->pipe.wevent;
1866 else
1867 wait_obj = p->pipe.revent;
1868 }
1869
1870 ___device_select_add_wait_obj (state, i, wait_obj);
1871
1872 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
1873 }
1874
1875 /* pass == ___SELECT_PASS_CHECK */
1876
1877 if (stage != ___STAGE_OPEN0)
1878 state->devs[i] = NULL((void*)0);
1879 else
1880 {
1881 if (state->devs_next[i] != -1)
1882 state->devs[i] = NULL((void*)0);
1883 }
1884
1885 return ___FIX(___NO_ERR)(((long)(0))<<2);
1886 }
1887
1888#endif
1889
1890 return ___device_stream_select_raw_virt((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
1891 (d,((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
1892 for_writing,((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
1893 i,((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
1894 pass,((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
1895 state)((___device_stream_vtbl*)((d)->base.vtbl))->select_raw_virt
(d,for_writing,i,pass,state)
;
1896}
1897
1898
1899___SCMOBJlong ___device_stream_release_virt
1900 ___P((___device *self),(___device *self)
1901 (self)(___device *self)
1902___device *self;)(___device *self)
1903{
1904 ___SCMOBJlong e;
1905 ___device_stream *d = ___CAST(___device_stream*,self)((___device_stream*)(self));
1906
1907 e = ___device_stream_release_raw_virt (d)((___device_stream_vtbl*)((d)->base.vtbl))->release_raw_virt
(d)
;
1908
1909#ifdef USE_PUMPS
1910
1911 {
1912 ___device_stream_pump *p;
1913
1914 p = d->read_pump;
1915 if (p != NULL((void*)0))
1916 ___device_stream_pump_cleanup (p); /* ignore error */
1917
1918 p = d->write_pump;
1919 if (p != NULL((void*)0))
1920 ___device_stream_pump_cleanup (p); /* ignore error */
1921 }
1922
1923#endif
1924
1925 return e;
1926}
1927
1928
1929___SCMOBJlong ___device_stream_force_output_virt
1930 ___P((___device *self,(___device *self, int level)
1931 int level),(___device *self, int level)
1932 (self,(___device *self, int level)
1933 level)(___device *self, int level)
1934___device *self;(___device *self, int level)
1935int level;)(___device *self, int level)
1936{
1937 ___device_stream *d = ___CAST(___device_stream*,self)((___device_stream*)(self));
1938
1939#ifdef USE_PUMPS
1940
1941 {
1942 ___device_stream_pump *p = d->write_pump;
1943
1944 if (p != NULL((void*)0))
1945 {
1946 ___nonblocking_pipe_oob_msg oob_msg;
1947
1948 oob_msg.op = OOB_FORCE_OUTPUT0 + level;
1949
1950 return ___nonblocking_pipe_write_oob (&p->pipe, &oob_msg);
1951 }
1952 }
1953
1954#endif
1955
1956 return ___device_stream_force_output_raw_virt (d, level)((___device_stream_vtbl*)((d)->base.vtbl))->force_output_raw_virt
(d,level)
;
1957}
1958
1959
1960___SCMOBJlong ___device_stream_close_virt
1961 ___P((___device *self,(___device *self, int direction)
1962 int direction),(___device *self, int direction)
1963 (self,(___device *self, int direction)
1964 direction)(___device *self, int direction)
1965___device *self;(___device *self, int direction)
1966int direction;)(___device *self, int direction)
1967{
1968 ___device_stream *d = ___CAST(___device_stream*,self)((___device_stream*)(self));
1969
1970#ifdef USE_PUMPS
1971
1972 if (direction & ___DIRECTION_RD1)
1973 {
1974 ___device_stream_pump *p = d->read_pump;
1975
1976 if (p != NULL((void*)0))
1977 ___device_stream_pump_reader_kill (p);
1978 }
1979
1980 if (direction & ___DIRECTION_WR2)
1981 {
1982 ___device_stream_pump *p = d->write_pump;
1983
1984 if (p != NULL((void*)0))
1985 ___device_stream_pump_writer_kill (p);
1986 }
1987
1988#endif
1989
1990 return ___device_stream_close_raw_virt (d, direction)((___device_stream_vtbl*)((d)->base.vtbl))->close_raw_virt
(d,direction)
;
1991}
1992
1993
1994___SCMOBJlong ___device_stream_seek
1995 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
1996 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
1997 int whence),(___device_stream *self, ___stream_index *pos, int whence)
1998 (self,(___device_stream *self, ___stream_index *pos, int whence)
1999 pos,(___device_stream *self, ___stream_index *pos, int whence)
2000 whence)(___device_stream *self, ___stream_index *pos, int whence)
2001___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
2002___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
2003int whence;)(___device_stream *self, ___stream_index *pos, int whence)
2004{
2005#ifdef USE_PUMPS
2006
2007 {
2008 ___device_stream_pump *p = self->write_pump;
2009
2010 if (p != NULL((void*)0))
2011 {
2012 ___nonblocking_pipe_oob_msg oob_msg;
2013
2014 oob_msg.op = OOB_SEEK_ABS + whence;
2015 oob_msg.stream_index_param = *pos;
2016
2017 return ___nonblocking_pipe_write_oob (&p->pipe, &oob_msg);
2018 }
2019 }
2020
2021#endif
2022
2023 return ___device_stream_seek_raw_virt (self, pos, whence)((___device_stream_vtbl*)((self)->base.vtbl))->seek_raw_virt
(self,pos,whence)
;
2024}
2025
2026___SCMOBJlong ___device_stream_read
2027 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2028 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2029 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2030 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2031 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2032 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2033 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2034 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2035___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2036___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2037___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2038___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2039{
2040#ifdef USE_PUMPS
2041
2042 {
2043 ___device_stream_pump *p = self->read_pump;
2044
2045 if (p != NULL((void*)0))
2046 {
2047 ___nonblocking_pipe_oob_msg oob_msg;
2048 return ___nonblocking_pipe_read
2049 (&p->pipe,
2050 buf,
2051 len,
2052 len_done,
2053 &oob_msg);
2054 }
2055 }
2056
2057#endif
2058
2059 return ___device_stream_read_raw_virt (self, buf, len, len_done)((___device_stream_vtbl*)((self)->base.vtbl))->read_raw_virt
(self,buf,len,len_done)
;
2060}
2061
2062___SCMOBJlong ___device_stream_write
2063 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2064 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2065 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2066 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2067 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2068 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2069 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2070 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2071___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2072___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2073___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2074___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2075{
2076#ifdef USE_PUMPS
2077
2078 {
2079 ___device_stream_pump *p = self->write_pump;
2080
2081 if (p != NULL((void*)0))
2082 return ___nonblocking_pipe_write (&p->pipe, buf, len, len_done);
2083 }
2084
2085#endif
2086
2087 return ___device_stream_write_raw_virt (self, buf, len, len_done)((___device_stream_vtbl*)((self)->base.vtbl))->write_raw_virt
(self,buf,len,len_done)
;
2088}
2089
2090/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2091
2092#ifdef USE_PUMPS
2093
2094___HIDDENstatic DWORD WINAPI ___device_stream_read_pump_proc
2095 ___P((LPVOID param),(LPVOID param)
2096 (param)(LPVOID param)
2097LPVOID param;)(LPVOID param)
2098{
2099 ___device_stream *dev = ___CAST(___device_stream*,param)((___device_stream*)(param));
2100 ___nonblocking_pipe *p = &dev->read_pump->pipe;
2101 ___SCMOBJlong e;
2102 ___stream_index len;
2103 ___stream_index n;
2104 ___stream_index i;
2105 ___U8unsigned char buf[PIPE_BUFFER_SIZE];
2106 ___nonblocking_pipe_oob_msg oob_msg;
2107
2108 for (;;)
2109 {
2110 /* wait until the reader needs some data */
2111
2112 e = ___nonblocking_pipe_write_ready_wait (p);
2113
2114 /* read some characters from device */
2115
2116 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
2117 e = ___device_stream_read_raw_virt (dev, buf, PIPE_BUFFER_SIZE, &len)((___device_stream_vtbl*)((dev)->base.vtbl))->read_raw_virt
(dev,buf,PIPE_BUFFER_SIZE,&len)
;
2118
2119 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
2120 {
2121 if (len == 0)
2122 {
2123 /* we reached the end-of-stream */
2124
2125 oob_msg.op = OOB_EOS;
2126
2127 while ((e = ___nonblocking_pipe_write_oob (p, &oob_msg))
2128 == ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
2129 {
2130 /* suspend thread until operation can be performed */
2131
2132 e = ___nonblocking_pipe_write_ready_wait (p);
2133 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2134 break;
2135 }
2136 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2137 break;
2138 }
2139 else
2140 {
2141 /* write to the pipe the bytes that were read */
2142
2143 i = 0;
2144
2145 while (i < len)
2146 {
2147 while ((e = ___nonblocking_pipe_write (p, buf+i, len-i, &n))
2148 == ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
2149 {
2150 /* suspend thread until operation can be performed */
2151
2152 e = ___nonblocking_pipe_write_ready_wait (p);
2153 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2154 break;
2155 }
2156 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2157 break;
2158 i += n;
2159 }
2160 }
2161 }
2162
2163 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2164 {
2165 if (e == ___FIX(___KILL_PUMP)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+13)))<<2)
) /* terminate? */
2166 break;
2167
2168 if (e == ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
2169 continue;
2170
2171 /* report the failure back through the pipe */
2172
2173 e = ___nonblocking_pipe_set_writer_err (p, e);
2174
2175 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2176 {
2177 /*
2178 * The failure could not be reported. To avoid an
2179 * infinite loop the thread is terminated.
2180 */
2181
2182 ExitThread (0);
2183 }
2184 }
2185 }
2186
2187 ___device_release (&dev->base); /* ignore error */
2188
2189 return 0;
2190}
2191
2192___HIDDENstatic DWORD WINAPI ___device_stream_write_pump_proc
2193 ___P((LPVOID param),(LPVOID param)
2194 (param)(LPVOID param)
2195LPVOID param;)(LPVOID param)
2196{
2197 ___device_stream *dev = ___CAST(___device_stream*,param)((___device_stream*)(param));
2198 ___nonblocking_pipe *p = &dev->write_pump->pipe;
2199 ___SCMOBJlong e;
2200 ___stream_index len;
2201 ___stream_index n;
2202 ___stream_index i;
2203 ___U8unsigned char buf[PIPE_BUFFER_SIZE];
2204 ___nonblocking_pipe_oob_msg oob_msg;
2205
2206 for (;;)
2207 {
2208 /* get from the pipe some bytes to write to the device */
2209
2210 while ((e = ___nonblocking_pipe_read
2211 (p,
2212 buf,
2213 PIPE_BUFFER_SIZE,
2214 &len,
2215 &oob_msg))
2216 == ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
)
2217 {
2218 /* suspend thread until operation can be performed */
2219
2220 e = ___nonblocking_pipe_read_ready_wait (p);
2221 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2222 break;
2223 }
2224
2225 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
2226 {
2227 if (len > 0)
2228 {
2229 /* write to the device the bytes that were read from the pipe */
2230
2231 i = 0;
2232
2233 while (i < len)
2234 {
2235 e = ___device_stream_write_raw_virt (dev, buf+i, len-i, &n)((___device_stream_vtbl*)((dev)->base.vtbl))->write_raw_virt
(dev,buf+i,len-i,&n)
;
2236 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2237 break;
2238 i += n;
2239 }
2240 }
2241 else
2242 {
2243 switch (oob_msg.op)
2244 {
2245 case OOB_FORCE_OUTPUT0:
2246 case OOB_FORCE_OUTPUT1:
2247 case OOB_FORCE_OUTPUT2:
2248 case OOB_FORCE_OUTPUT3:
2249#ifdef ___DEBUG
2250 ___printf ("***** got OOB_FORCE_OUTPUT%d\n",
2251 oob_msg.op - OOB_FORCE_OUTPUT0);
2252#endif
2253 e = ___device_stream_force_output_raw_virt (dev, oob_msg.op - OOB_FORCE_OUTPUT0)((___device_stream_vtbl*)((dev)->base.vtbl))->force_output_raw_virt
(dev,oob_msg.op - OOB_FORCE_OUTPUT0)
;
2254 break;
2255 case OOB_SEEK_ABS:
2256 case OOB_SEEK_REL:
2257 case OOB_SEEK_REL_END:
2258#ifdef ___DEBUG
2259 ___printf ("***** got OOB_SEEK %d %d\n",
2260 oob_msg.stream_index_param,
2261 oob_msg.op - OOB_SEEK_ABS);
2262#endif
2263 e = ___device_stream_seek_raw_virt((___device_stream_vtbl*)((dev)->base.vtbl))->seek_raw_virt
(dev,&oob_msg.stream_index_param,oob_msg.op - OOB_SEEK_ABS
)
2264 (dev,((___device_stream_vtbl*)((dev)->base.vtbl))->seek_raw_virt
(dev,&oob_msg.stream_index_param,oob_msg.op - OOB_SEEK_ABS
)
2265 &oob_msg.stream_index_param,((___device_stream_vtbl*)((dev)->base.vtbl))->seek_raw_virt
(dev,&oob_msg.stream_index_param,oob_msg.op - OOB_SEEK_ABS
)
2266 oob_msg.op - OOB_SEEK_ABS)((___device_stream_vtbl*)((dev)->base.vtbl))->seek_raw_virt
(dev,&oob_msg.stream_index_param,oob_msg.op - OOB_SEEK_ABS
)
;
2267 break;
2268 case OOB_EOS:
2269#ifdef ___DEBUG
2270 ___printf ("***** got OOB_EOS\n");
2271#endif
2272 break;
2273 }
2274 }
2275 }
2276
2277 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2278 {
2279 if (e == ___FIX(___KILL_PUMP)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+13)))<<2)
) /* terminate? */
2280 break;
2281
2282 /* report the failure back through the pipe */
2283
2284 e = ___nonblocking_pipe_set_reader_err (p, e);
2285
2286 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2287 {
2288 /*
2289 * The failure could not be reported. To avoid an
2290 * infinite loop the thread is terminated.
2291 */
2292
2293 ExitThread (0);
2294 }
2295 }
2296 }
2297
2298 ___device_release (&dev->base); /* ignore error */
2299
2300 return 0;
2301}
2302
2303#endif
2304
2305___SCMOBJlong ___device_stream_setup
2306 ___P((___device_stream *dev,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2307 ___device_group *dgroup,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2308 int direction,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2309 int pumps_on),(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2310 (dev,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2311 dgroup,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2312 direction,(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2313 pumps_on)/*********************/(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2314___device_stream *dev;(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2315___device_group *dgroup;(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2316int direction;(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2317int pumps_on;)(___device_stream *dev, ___device_group *dgroup, int direction
, int pumps_on)
2318{
2319 dev->base.refcount = 1;
2320 dev->base.direction = direction;
2321 dev->base.close_direction = 0; /* prevent closing on errors */
2322 dev->base.read_stage = ___STAGE_CLOSED3;
2323 dev->base.write_stage = ___STAGE_CLOSED3;
2324
2325#ifdef USE_PUMPS
2326 dev->read_pump = NULL((void*)0);
2327 dev->write_pump = NULL((void*)0);
2328#endif
2329
2330 ___device_add_to_group (dgroup, &dev->base);
2331
2332 if (direction & ___DIRECTION_RD1)
2333 {
2334 dev->base.read_stage = ___STAGE_OPEN0;
2335
2336#ifdef USE_PUMPS
2337
2338 if (pumps_on & ___DIRECTION_RD1)
2339 {
2340 ___SCMOBJlong e;
2341
2342 device_add_ref (&dev->base);
2343
2344 if ((e = ___device_stream_pump_setup
2345 (&dev->read_pump,
2346 65536,
2347 ___device_stream_read_pump_proc,
2348 dev))
2349 != ___FIX(___NO_ERR)(((long)(0))<<2))
2350 {
2351 ___device_release (&dev->base); /* ignore error */
2352 ___device_cleanup (&dev->base); /* ignore error */
2353 return e;
2354 }
2355 }
2356
2357#endif
2358 }
2359
2360 if (direction & ___DIRECTION_WR2)
2361 {
2362 dev->base.write_stage = ___STAGE_OPEN0;
2363
2364#ifdef USE_PUMPS
2365
2366 if (pumps_on & ___DIRECTION_WR2)
2367 {
2368 ___SCMOBJlong e;
2369
2370 device_add_ref (&dev->base);
2371
2372 if ((e = ___device_stream_pump_setup
2373 (&dev->write_pump,
2374 65536,
2375 ___device_stream_write_pump_proc,
2376 dev))
2377 != ___FIX(___NO_ERR)(((long)(0))<<2))
2378 {
2379 ___device_release (&dev->base); /* ignore error */
2380 ___device_cleanup (&dev->base); /* ignore error */
2381 return e;
2382 }
2383 }
2384
2385#endif
2386 }
2387
2388 return ___FIX(___NO_ERR)(((long)(0))<<2);
2389}
2390
2391
2392/*---------------------------------------------------------------------------*/
2393
2394/* Serial stream device */
2395
2396#ifdef USE_WIN32
2397
2398typedef struct ___device_serial_struct
2399 {
2400 ___device_stream base;
2401 HANDLE h;
2402 } ___device_serial;
2403
2404typedef struct ___device_serial_vtbl_struct
2405 {
2406 ___device_stream_vtbl base;
2407 } ___device_serial_vtbl;
2408
2409___HIDDENstatic int ___device_serial_kind
2410 ___P((___device *self),(___device *self)
2411 (self)(___device *self)
2412___device *self;)(___device *self)
2413{
2414 return ___SERIAL_DEVICE_KIND(15 +128);
2415}
2416
2417___HIDDENstatic ___SCMOBJlong ___device_serial_close_raw_virt
2418 ___P((___device_stream *self,(___device_stream *self, int direction)
2419 int direction),(___device_stream *self, int direction)
2420 (self,(___device_stream *self, int direction)
2421 direction)(___device_stream *self, int direction)
2422___device_stream *self;(___device_stream *self, int direction)
2423int direction;)(___device_stream *self, int direction)
2424{
2425 ___device_serial *d = ___CAST(___device_serial*,self)((___device_serial*)(self));
2426 int is_not_closed = 0;
2427
2428 if (d->base.base.read_stage != ___STAGE_CLOSED3)
2429 is_not_closed |= ___DIRECTION_RD1;
2430
2431 if (d->base.base.write_stage != ___STAGE_CLOSED3)
2432 is_not_closed |= ___DIRECTION_WR2;
2433
2434 if (is_not_closed == 0)
2435 return ___FIX(___NO_ERR)(((long)(0))<<2);
2436
2437 if (is_not_closed == (___DIRECTION_RD1|___DIRECTION_WR2))
2438 {
2439 d->base.base.read_stage = ___STAGE_CLOSED3;
2440 d->base.base.write_stage = ___STAGE_CLOSED3;
2441
2442 if ((d->base.base.close_direction & (___DIRECTION_RD1|___DIRECTION_WR2))
2443 == (___DIRECTION_RD1|___DIRECTION_WR2))
2444 {
2445 if (!CloseHandle (d->h))
2446 return err_code_from_GetLastError ()___err_code_from_GetLastError();
2447 }
2448 }
2449
2450 return ___FIX(___NO_ERR)(((long)(0))<<2);
2451}
2452
2453___HIDDENstatic ___SCMOBJlong ___device_serial_select_raw_virt
2454 ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2455 ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2456 int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2457 int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2458 ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2459 (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2460 for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2461 i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2462 pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2463 state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2464___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2465___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2466int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2467int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2468___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2469{
2470 ___device_serial *d = ___CAST(___device_serial*,self)((___device_serial*)(self));
2471 int stage = (for_writing
2472 ? d->base.base.write_stage
2473 : d->base.base.read_stage);
2474
2475 if (pass == ___SELECT_PASS_11)
2476 {
2477 if (stage != ___STAGE_OPEN0)
2478 state->timeout = ___time_mod.time_neg_infinity;
2479 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
2480 }
2481
2482 /* pass == ___SELECT_PASS_CHECK */
2483
2484 if (stage != ___STAGE_OPEN0)
2485 state->devs[i] = NULL((void*)0);
2486 else
2487 {
2488 if (state->devs_next[i] != -1)
2489 state->devs[i] = NULL((void*)0);
2490 }
2491
2492 return ___FIX(___NO_ERR)(((long)(0))<<2);
2493}
2494
2495___HIDDENstatic ___SCMOBJlong ___device_serial_release_raw_virt
2496 ___P((___device_stream *self),(___device_stream *self)
2497 (self)(___device_stream *self)
2498___device_stream *self;)(___device_stream *self)
2499{
2500 return ___FIX(___NO_ERR)(((long)(0))<<2);
2501}
2502
2503___HIDDENstatic ___SCMOBJlong ___device_serial_force_output_raw_virt
2504 ___P((___device_stream *self,(___device_stream *self, int level)
2505 int level),(___device_stream *self, int level)
2506 (self,(___device_stream *self, int level)
2507 level)(___device_stream *self, int level)
2508___device_stream *self;(___device_stream *self, int level)
2509int level;)(___device_stream *self, int level)
2510{
2511 ___device_serial *d = ___CAST(___device_serial*,self)((___device_serial*)(self));
2512
2513 if (d->base.base.write_stage == ___STAGE_OPEN0)
2514 {
2515 if (level > 0)
2516 {
2517 if (!FlushFileBuffers (d->h))
2518 return err_code_from_GetLastError ()___err_code_from_GetLastError();
2519 }
2520 }
2521
2522 return ___FIX(___NO_ERR)(((long)(0))<<2);
2523}
2524
2525___HIDDENstatic ___SCMOBJlong ___device_serial_seek_raw_virt
2526 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
2527 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
2528 int whence),(___device_stream *self, ___stream_index *pos, int whence)
2529 (self,(___device_stream *self, ___stream_index *pos, int whence)
2530 pos,(___device_stream *self, ___stream_index *pos, int whence)
2531 whence)(___device_stream *self, ___stream_index *pos, int whence)
2532___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
2533___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
2534int whence;)(___device_stream *self, ___stream_index *pos, int whence)
2535{
2536 return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+7)))<<2)
;
2537}
2538
2539___HIDDENstatic ___SCMOBJlong ___device_serial_read_raw_virt
2540 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2541 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2542 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2543 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2544 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2545 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2546 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2547 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2548___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2549___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2550___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2551___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2552{
2553 ___device_serial *d = ___CAST(___device_serial*,self)((___device_serial*)(self));
2554
2555 if (d->base.base.read_stage != ___STAGE_OPEN0)
2556 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
2557
2558 {
2559 DWORD n;
2560
2561 if (!ReadFile (d->h, buf, len, &n, NULL((void*)0)))
2562 return err_code_from_GetLastError ()___err_code_from_GetLastError();
2563
2564 if (n == 0)
2565 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
2566
2567 *len_done = n;
2568 }
2569
2570 return ___FIX(___NO_ERR)(((long)(0))<<2);
2571}
2572
2573___HIDDENstatic ___SCMOBJlong ___device_serial_write_raw_virt
2574 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2575 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2576 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2577 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2578 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2579 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2580 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2581 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2582___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2583___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2584___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2585___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
2586{
2587 ___device_serial *d = ___CAST(___device_serial*,self)((___device_serial*)(self));
2588
2589 if (d->base.base.write_stage != ___STAGE_OPEN0)
2590 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
2591
2592 {
2593 DWORD n;
2594
2595 if (!WriteFile (d->h, buf, len, &n, NULL((void*)0)))
2596 {
2597 /*
2598 * Even though WriteFile has reported a failure, the operation
2599 * was executed correctly (i.e. len_done contains the number
2600 * of bytes written) if GetLastError returns ERROR_SUCCESS.
2601 */
2602
2603 if (GetLastError () != ERROR_SUCCESS)
2604 return err_code_from_GetLastError ()___err_code_from_GetLastError();
2605 }
2606
2607 *len_done = n;
2608 }
2609
2610 return ___FIX(___NO_ERR)(((long)(0))<<2);
2611}
2612
2613___HIDDENstatic ___SCMOBJlong ___device_serial_width_virt
2614 ___P((___device_stream *self),(___device_stream *self)
2615 (self)(___device_stream *self)
2616___device_stream *self;)(___device_stream *self)
2617{
2618 return ___FIX(80)(((long)(80))<<2);
2619}
2620
2621___HIDDENstatic ___SCMOBJlong ___device_serial_default_options_virt
2622 ___P((___device_stream *self),(___device_stream *self)
2623 (self)(___device_stream *self)
2624___device_stream *self;)(___device_stream *self)
2625{
2626 int char_encoding_errors = ___CHAR_ENCODING_ERRORS_ON(1<<5);
2627 int char_encoding = ___CHAR_ENCODING_ISO_8859_1(2<<0);
2628 int eol_encoding = ___EOL_ENCODING_LF(1<<7);
2629 int buffering = ___FULL_BUFFERING(3<<9);
2630
2631 return ___FIX(___STREAM_OPTIONS(char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2632 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2633 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2634 buffering,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2635 char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2636 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2637 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
2638 buffering))(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
;
2639}
2640
2641
2642___HIDDENstatic ___SCMOBJlong ___device_serial_options_set_virt
2643 ___P((___device_stream *self,(___device_stream *self, long options)
2644 ___SCMOBJ options),(___device_stream *self, long options)
2645 (self,(___device_stream *self, long options)
2646 options)(___device_stream *self, long options)
2647___device_stream *self;(___device_stream *self, long options)
2648___SCMOBJ options;)(___device_stream *self, long options)
2649{
2650 return ___FIX(___NO_ERR)(((long)(0))<<2);
2651}
2652
2653
2654___HIDDENstatic ___device_serial_vtbl ___device_serial_table =
2655{
2656 {
2657 {
2658 ___device_serial_kind,
2659 ___device_stream_select_virt,
2660 ___device_stream_release_virt,
2661 ___device_stream_force_output_virt,
2662 ___device_stream_close_virt
2663 },
2664 ___device_serial_select_raw_virt,
2665 ___device_serial_release_raw_virt,
2666 ___device_serial_force_output_raw_virt,
2667 ___device_serial_close_raw_virt,
2668 ___device_serial_seek_raw_virt,
2669 ___device_serial_read_raw_virt,
2670 ___device_serial_write_raw_virt,
2671 ___device_serial_width_virt,
2672 ___device_serial_default_options_virt,
2673 ___device_serial_options_set_virt
2674 }
2675};
2676
2677
2678___HIDDENstatic ___SCMOBJlong ___device_serial_set_comm_state
2679 ___P((___device_serial *dev,(___device_serial *dev, LPCTSTR def)
2680 LPCTSTR def),(___device_serial *dev, LPCTSTR def)
2681 (dev,(___device_serial *dev, LPCTSTR def)
2682 def)(___device_serial *dev, LPCTSTR def)
2683___device_serial *dev;(___device_serial *dev, LPCTSTR def)
2684LPCTSTR def;)(___device_serial *dev, LPCTSTR def)
2685{
2686 DCB dcb;
2687
2688 FillMemory (&dcb, sizeof (dcb), 0);
2689
2690 if (!GetCommState (dev->h, &dcb) ||
2691 !BuildCommDCB (def, &dcb) ||
2692 !SetCommState (dev->h, &dcb))
2693 return err_code_from_GetLastError ()___err_code_from_GetLastError();
2694
2695 return ___FIX(___NO_ERR)(((long)(0))<<2);
2696}
2697
2698___SCMOBJlong ___device_serial_setup_from_handle
2699 ___P((___device_serial **dev,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2700 ___device_group *dgroup,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2701 HANDLE h,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2702 int direction),(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2703 (dev,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2704 dgroup,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2705 h,(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2706 direction)(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2707___device_serial **dev;(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2708___device_group *dgroup;(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2709HANDLE h;(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2710int direction;)(___device_serial **dev, ___device_group *dgroup, HANDLE h, int
direction)
2711{
2712 ___device_serial *d;
2713 ___SCMOBJlong e;
2714 COMMTIMEOUTS cto;
2715
2716 d = ___CAST(___device_serial*,((___device_serial*)(___alloc_mem (sizeof (___device_serial))
))
2717 ___alloc_mem (sizeof (___device_serial)))((___device_serial*)(___alloc_mem (sizeof (___device_serial))
))
;
2718
2719 if (d == NULL((void*)0))
2720 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
2721
2722 d->base.base.vtbl = &___device_serial_table;
2723 d->h = h;
2724
2725 *dev = d;
2726
2727 e = ___device_serial_set_comm_state (d, _T("baud=38400 parity=N data=8 stop=1"));
2728
2729 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
2730 {
2731 ___free_mem (d);
2732 return e;
2733 }
2734
2735 /*
2736 * Setup serial device so that ReadFile will return as soon as a
2737 * character is available.
2738 */
2739
2740 cto.ReadIntervalTimeout = MAXDWORD;
2741 cto.ReadTotalTimeoutMultiplier = MAXDWORD;
2742 cto.ReadTotalTimeoutConstant = 1; /* wait no more than 1 ms */
2743 cto.WriteTotalTimeoutMultiplier = 0;
2744 cto.WriteTotalTimeoutConstant = 0;
2745
2746 if (!SetCommTimeouts (h, &cto)
2747#ifdef USE_BIG_SERIAL_BUFFERS
2748 || !SetupComm (h, 65536, 65536))
2749#endif
2750 )
2751 {
2752 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
2753 ___free_mem (d);
2754 return e;
2755 }
2756
2757 return ___device_stream_setup
2758 (&d->base,
2759 dgroup,
2760 direction,
2761 ___DIRECTION_RD1|___DIRECTION_WR2);
2762}
2763
2764#endif
2765
2766
2767/*---------------------------------------------------------------------------*/
2768
2769/* Pipe stream device */
2770
2771/*
2772 * Pipes may be unidirectional or bidirectional. Bidirectional pipes
2773 * are implemented with 2 OS pipes: a "write" pipe and a "read" pipe.
2774 */
2775
2776typedef struct ___device_pipe_struct
2777 {
2778 ___device_stream base;
2779
2780#ifdef USE_POSIX
2781 int fd_wr; /* file descriptor for "write" pipe (-1 if none) */
2782 int fd_rd; /* file descriptor for "read" pipe (-1 if none) */
2783#endif
2784
2785#ifdef USE_WIN32
2786 HANDLE h_wr; /* handle for "write" pipe (NULL if none) */
2787 HANDLE h_rd; /* handle for "read" pipe (NULL if none) */
2788 int poll_interval_nsecs; /* interval between read attempts */
2789#endif
2790 } ___device_pipe;
2791
2792
2793typedef struct ___device_pipe_vtbl_struct
2794 {
2795 ___device_stream_vtbl base;
2796 } ___device_pipe_vtbl;
2797
2798___HIDDENstatic int ___device_pipe_kind
2799 ___P((___device *self),(___device *self)
2800 (self)(___device *self)
2801___device *self;)(___device *self)
2802{
2803 return ___PIPE_DEVICE_KIND(15 +32);
2804}
2805
2806___SCMOBJlong ___device_pipe_cleanup
2807 ___P((___device_pipe *dev),(___device_pipe *dev)
2808 (dev)(___device_pipe *dev)
2809___device_pipe *dev;)(___device_pipe *dev)
2810{
2811 return ___FIX(___NO_ERR)(((long)(0))<<2);
2812}
2813
2814
2815___HIDDENstatic ___SCMOBJlong ___device_pipe_close_raw_virt
2816 ___P((___device_stream *self,(___device_stream *self, int direction)
2817 int direction),(___device_stream *self, int direction)
2818 (self,(___device_stream *self, int direction)
2819 direction)(___device_stream *self, int direction)
2820___device_stream *self;(___device_stream *self, int direction)
2821int direction;)(___device_stream *self, int direction)
2822{
2823 ___device_pipe *d = ___CAST(___device_pipe*,self)((___device_pipe*)(self));
2824 int is_not_closed = 0;
2825
2826 if (d->base.base.read_stage != ___STAGE_CLOSED3)
2827 is_not_closed |= ___DIRECTION_RD1;
2828
2829 if (d->base.base.write_stage != ___STAGE_CLOSED3)
2830 is_not_closed |= ___DIRECTION_WR2;
2831
2832 if (is_not_closed == 0)
2833 return ___FIX(___NO_ERR)(((long)(0))<<2);
2834
2835 if (is_not_closed & direction & ___DIRECTION_RD1)
2836 {
2837 /* Close "read" pipe */
2838
2839 d->base.base.read_stage = ___STAGE_CLOSED3;
2840
2841 if ((d->base.base.close_direction & ___DIRECTION_RD1)
2842 == ___DIRECTION_RD1)
2843 {
2844#ifdef USE_POSIX
2845 if (d->fd_rd >= 0 &&
2846 d->fd_rd != d->fd_wr &&
2847 close_no_EINTR (d->fd_rd) < 0)
2848 return err_code_from_errno ()___err_code_from_errno();
2849#endif
2850
2851#ifdef USE_WIN32
2852 if (d->h_rd != NULL((void*)0) &&
2853 d->h_rd != d->h_wr)
2854 CloseHandle (d->h_rd); /* ignore error */
2855#endif
2856 }
2857 }
2858
2859 if (is_not_closed & direction & ___DIRECTION_WR2)
2860 {
2861 /* Close "write" pipe */
2862
2863 d->base.base.write_stage = ___STAGE_CLOSED3;
2864
2865 if ((d->base.base.close_direction & ___DIRECTION_WR2)
2866 == ___DIRECTION_WR2)
2867 {
2868#ifdef USE_POSIX
2869 if (d->fd_wr >= 0 &&
2870 close_no_EINTR (d->fd_wr) < 0)
2871 return err_code_from_errno ()___err_code_from_errno();
2872#endif
2873
2874#ifdef USE_WIN32
2875 if (d->h_wr != NULL((void*)0))
2876 CloseHandle (d->h_wr); /* ignore error */
2877#endif
2878 }
2879 }
2880
2881 return ___FIX(___NO_ERR)(((long)(0))<<2);
2882}
2883
2884___HIDDENstatic ___SCMOBJlong ___device_pipe_select_raw_virt
2885 ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2886 ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2887 int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2888 int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2889 ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2890 (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2891 for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2892 i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2893 pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2894 state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2895___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2896___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2897int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2898int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2899___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
2900{
2901 ___device_pipe *d = ___CAST(___device_pipe*,self)((___device_pipe*)(self));
2902 int stage = (for_writing
2903 ? d->base.base.write_stage
2904 : d->base.base.read_stage);
2905
2906 if (pass == ___SELECT_PASS_11)
2907 {
2908 if (stage != ___STAGE_OPEN0)
2909 state->timeout = ___time_mod.time_neg_infinity;
2910 else
2911 {
2912#ifdef USE_POSIX
2913 if (for_writing)
2914 {
2915 if (d->fd_wr >= 0)
2916 ___device_select_add_fd (state, d->fd_wr, 1);
2917 }
2918 else
2919 {
2920 if (d->fd_rd >= 0)
2921 ___device_select_add_fd (state, d->fd_rd, 0);
2922 }
2923#endif
2924
2925#ifdef USE_WIN32
2926 if (for_writing)
2927 {
2928 if (d->h_wr != NULL((void*)0))
2929 ___device_select_add_wait_obj (state, i, d->h_wr);
2930 }
2931 else
2932 {
2933 if (d->h_rd != NULL((void*)0))
2934 {
2935 int interval = d->poll_interval_nsecs * 6 / 5;
2936 if (interval < 1000000)
2937 interval = 1000000; /* min interval = 0.001 secs */
2938 else if (interval > 200000000)
2939 interval = 200000000; /* max interval = 0.2 sec */
2940 d->poll_interval_nsecs = interval;
2941 ___device_select_add_relative_timeout (state, i, interval * 1e-9);
2942 }
2943 }
2944#endif
2945 }
2946 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
2947 }
2948
2949 /* pass == ___SELECT_PASS_CHECK */
2950
2951 if (stage != ___STAGE_OPEN0)
2952 state->devs[i] = NULL((void*)0);
2953 else
2954 {
2955#ifdef USE_POSIX
2956
2957 if (for_writing)
2958 {
2959 if (d->fd_wr < 0 || ___FD_ISSET(d->fd_wr, &state->writefds)((((&state->writefds)->__fds_bits)[((d->fd_wr) /
(8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 <<
((d->fd_wr) % (8 * (int) sizeof (__fd_mask))))) != 0)
)
2960 state->devs[i] = NULL((void*)0);
2961 }
2962 else
2963 {
2964 if (d->fd_rd < 0 || ___FD_ISSET(d->fd_rd, &state->readfds)((((&state->readfds)->__fds_bits)[((d->fd_rd) / (
8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 <<
((d->fd_rd) % (8 * (int) sizeof (__fd_mask))))) != 0)
)
2965 state->devs[i] = NULL((void*)0);
2966 }
2967
2968#endif
2969
2970#ifdef USE_WIN32
2971
2972 if (for_writing)
2973 {
2974 if (d->h_wr != NULL((void*)0) && state->devs_next[i] != -1)
2975 state->devs[i] = NULL((void*)0);
2976 }
2977 else
2978 {
2979 if (d->h_rd != NULL((void*)0))
2980 state->devs[i] = NULL((void*)0);
2981 }
2982
2983#endif
2984 }
2985
2986 return ___FIX(___NO_ERR)(((long)(0))<<2);
2987}
2988
2989___HIDDENstatic ___SCMOBJlong ___device_pipe_release_raw_virt
2990 ___P((___device_stream *self),(___device_stream *self)
2991 (self)(___device_stream *self)
2992___device_stream *self;)(___device_stream *self)
2993{
2994 return ___FIX(___NO_ERR)(((long)(0))<<2);
2995}
2996
2997___HIDDENstatic ___SCMOBJlong ___device_pipe_force_output_raw_virt
2998 ___P((___device_stream *self,(___device_stream *self, int level)
2999 int level),(___device_stream *self, int level)
3000 (self,(___device_stream *self, int level)
3001 level)(___device_stream *self, int level)
3002___device_stream *self;(___device_stream *self, int level)
3003int level;)(___device_stream *self, int level)
3004{
3005 return ___FIX(___NO_ERR)(((long)(0))<<2);
3006}
3007
3008___HIDDENstatic ___SCMOBJlong ___device_pipe_seek_raw_virt
3009 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
3010 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
3011 int whence),(___device_stream *self, ___stream_index *pos, int whence)
3012 (self,(___device_stream *self, ___stream_index *pos, int whence)
3013 pos,(___device_stream *self, ___stream_index *pos, int whence)
3014 whence)(___device_stream *self, ___stream_index *pos, int whence)
3015___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
3016___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
3017int whence;)(___device_stream *self, ___stream_index *pos, int whence)
3018{
3019 return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+7)))<<2)
;
3020}
3021
3022___HIDDENstatic ___SCMOBJlong ___device_pipe_read_raw_virt
3023 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3024 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3025 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3026 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3027 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3028 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3029 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3030 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3031___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3032___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3033___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3034___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3035{
3036 ___device_pipe *d = ___CAST(___device_pipe*,self)((___device_pipe*)(self));
3037 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
3038
3039 if (d->base.base.read_stage != ___STAGE_OPEN0)
3040 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
3041
3042#ifdef USE_POSIX
3043
3044 if (d->fd_rd < 0)
3045 *len_done = 0;
3046 else
3047 {
3048 int n = 0;
3049
3050 if ((n = read (d->fd_rd, buf, len)) < 0)
3051 {
3052#if 0
3053 if (errno(*__errno_location ()) == EIO5) errno(*__errno_location ()) = EAGAIN11;
3054#else
3055 if (errno(*__errno_location ()) == EIO5) /* on linux, treating EIO as EAGAIN gives an infinite loop */
3056 n = 0;
3057 else
3058#endif
3059 e = err_code_from_errno ()___err_code_from_errno();
3060 }
3061
3062 *len_done = n;
3063 }
3064
3065#endif
3066
3067#ifdef USE_WIN32
3068
3069 if (d->h_rd == NULL((void*)0))
3070 *len_done = 0;
3071 else
3072 {
3073 DWORD n = 0;
3074
3075 if (!PeekNamedPipe (d->h_rd, NULL((void*)0), 0, NULL((void*)0), &n, NULL((void*)0)))
3076 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
3077 else if (n == 0)
3078 e = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
3079 else
3080 {
3081 if (len > n)
3082 len = n;
3083
3084 if (!ReadFile (d->h_rd, buf, len, &n, NULL((void*)0)))
3085 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
3086 else
3087 d->poll_interval_nsecs = 0;
3088 }
3089
3090 if (e == ___FIX(___WIN32_ERR(ERROR_BROKEN_PIPE))(((long)((((HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE))&~(~((int
)(0))<<25)) | (((HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE))
&~((int)(0))<<27)>>2))))<<2)
)
3091 e = ___FIX(___NO_ERR)(((long)(0))<<2); /* generate end-of-file on broken pipe */
3092
3093 *len_done = n;
3094 }
3095
3096#endif
3097
3098 return e;
3099}
3100
3101___HIDDENstatic ___SCMOBJlong ___device_pipe_write_raw_virt
3102 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3103 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3104 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3105 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3106 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3107 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3108 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3109 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3110___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3111___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3112___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3113___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3114{
3115 ___device_pipe *d = ___CAST(___device_pipe*,self)((___device_pipe*)(self));
3116
3117 if (d->base.base.write_stage != ___STAGE_OPEN0)
3118 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
3119
3120#ifdef USE_POSIX
3121
3122 if (d->fd_wr < 0)
3123 *len_done = len;
3124 else
3125 {
3126 int n;
3127
3128 if ((n = write (d->fd_wr, buf, len)) < 0)
3129 return err_code_from_errno ()___err_code_from_errno();
3130
3131 *len_done = n;
3132 }
3133
3134#endif
3135
3136#ifdef USE_WIN32
3137
3138 if (d->h_wr == NULL((void*)0))
3139 *len_done = len;
3140 else
3141 {
3142 DWORD n;
3143
3144 if (!WriteFile (d->h_wr, buf, len, &n, NULL((void*)0)))
3145 return err_code_from_GetLastError ()___err_code_from_GetLastError();
3146
3147 *len_done = n;
3148 }
3149
3150#endif
3151
3152 return ___FIX(___NO_ERR)(((long)(0))<<2);
3153}
3154
3155___HIDDENstatic ___SCMOBJlong ___device_pipe_width_virt
3156 ___P((___device_stream *self),(___device_stream *self)
3157 (self)(___device_stream *self)
3158___device_stream *self;)(___device_stream *self)
3159{
3160 return ___FIX(80)(((long)(80))<<2);
3161}
3162
3163___HIDDENstatic ___SCMOBJlong ___device_pipe_default_options_virt
3164 ___P((___device_stream *self),(___device_stream *self)
3165 (self)(___device_stream *self)
3166___device_stream *self;)(___device_stream *self)
3167{
3168 int char_encoding_errors = ___CHAR_ENCODING_ERRORS_ON(1<<5);
3169 int char_encoding = ___CHAR_ENCODING_ISO_8859_1(2<<0);
3170 int eol_encoding = ___EOL_ENCODING_LF(1<<7);
3171 int buffering = ___FULL_BUFFERING(3<<9);
3172
3173 return ___FIX(___STREAM_OPTIONS(char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3174 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3175 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3176 buffering,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3177 char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3178 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3179 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
3180 buffering))(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
;
3181}
3182
3183
3184___HIDDENstatic ___SCMOBJlong ___device_pipe_options_set_virt
3185 ___P((___device_stream *self,(___device_stream *self, long options)
3186 ___SCMOBJ options),(___device_stream *self, long options)
3187 (self,(___device_stream *self, long options)
3188 options)(___device_stream *self, long options)
3189___device_stream *self;(___device_stream *self, long options)
3190___SCMOBJ options;)(___device_stream *self, long options)
3191{
3192 return ___FIX(___NO_ERR)(((long)(0))<<2);
3193}
3194
3195
3196___HIDDENstatic ___device_pipe_vtbl ___device_pipe_table =
3197{
3198 {
3199 {
3200 ___device_pipe_kind,
3201 ___device_stream_select_virt,
3202 ___device_stream_release_virt,
3203 ___device_stream_force_output_virt,
3204 ___device_stream_close_virt
3205 },
3206 ___device_pipe_select_raw_virt,
3207 ___device_pipe_release_raw_virt,
3208 ___device_pipe_force_output_raw_virt,
3209 ___device_pipe_close_raw_virt,
3210 ___device_pipe_seek_raw_virt,
3211 ___device_pipe_read_raw_virt,
3212 ___device_pipe_write_raw_virt,
3213 ___device_pipe_width_virt,
3214 ___device_pipe_default_options_virt,
3215 ___device_pipe_options_set_virt
3216 }
3217};
3218
3219
3220#ifdef USE_POSIX
3221
3222___HIDDENstatic ___SCMOBJlong ___device_pipe_setup_from_fd
3223 ___P((___device_pipe **dev,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3224 ___device_group *dgroup,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3225 int fd_rd,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3226 int fd_wr,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3227 int direction),(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3228 (dev,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3229 dgroup,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3230 fd_rd,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3231 fd_wr,(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3232 direction)(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3233___device_pipe **dev;(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3234___device_group *dgroup;(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3235int fd_rd;(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3236int fd_wr;(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3237int direction;)(___device_pipe **dev, ___device_group *dgroup, int fd_rd, int
fd_wr, int direction)
3238{
3239 ___device_pipe *d;
3240
3241 d = ___CAST(___device_pipe*,((___device_pipe*)(___alloc_mem (sizeof (___device_pipe))))
3242 ___alloc_mem (sizeof (___device_pipe)))((___device_pipe*)(___alloc_mem (sizeof (___device_pipe))));
3243
3244 if (d == NULL((void*)0))
3245 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
3246
3247 d->base.base.vtbl = &___device_pipe_table;
3248 d->fd_rd = fd_rd;
3249 d->fd_wr = fd_wr;
3250
3251 *dev = d;
3252
3253 return ___device_stream_setup
3254 (&d->base,
3255 dgroup,
3256 direction,
3257 0);
3258}
3259
3260#endif
3261
3262
3263#ifdef USE_WIN32
3264
3265___HIDDENstatic ___SCMOBJlong ___device_pipe_setup_from_handle
3266 ___P((___device_pipe **dev,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3267 ___device_group *dgroup,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3268 HANDLE h_rd,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3269 HANDLE h_wr,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3270 int direction,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3271 int pumps_on),(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3272 (dev,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3273 dgroup,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3274 h_rd,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3275 h_wr,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3276 direction,(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3277 pumps_on)(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3278___device_pipe **dev;(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3279___device_group *dgroup;(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3280HANDLE h_rd;(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3281HANDLE h_wr;(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3282int direction;(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3283int pumps_on;)(___device_pipe **dev, ___device_group *dgroup, HANDLE h_rd, HANDLE
h_wr, int direction, int pumps_on)
3284{
3285 ___device_pipe *d;
3286
3287 d = ___CAST(___device_pipe*,((___device_pipe*)(___alloc_mem (sizeof (___device_pipe))))
3288 ___alloc_mem (sizeof (___device_pipe)))((___device_pipe*)(___alloc_mem (sizeof (___device_pipe))));
3289
3290 if (d == NULL((void*)0))
3291 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
3292
3293 d->base.base.vtbl = &___device_pipe_table;
3294 d->h_rd = h_rd;
3295 d->h_wr = h_wr;
3296 d->poll_interval_nsecs = 0;
3297
3298 *dev = d;
3299
3300 return ___device_stream_setup
3301 (&d->base,
3302 dgroup,
3303 direction,
3304 pumps_on);
3305}
3306
3307#endif
3308
3309
3310/*---------------------------------------------------------------------------*/
3311
3312/* Process stream device */
3313
3314typedef struct ___device_process_struct
3315 {
3316 ___device_pipe base;
3317
3318#ifdef USE_POSIX
3319 pid_t pid; /* pid of the process */
3320#endif
3321
3322#ifdef USE_WIN32
3323 PROCESS_INFORMATION pi; /* process information */
3324#endif
3325
3326 int status; /* process status */
3327 ___BOOLint got_status; /* was the status retrieved? */
3328 ___BOOLint cleanuped; /* has process been cleaned-up? */
3329 } ___device_process;
3330
3331typedef struct ___device_process_vtbl_struct
3332 {
3333 ___device_stream_vtbl base;
3334 } ___device_process_vtbl;
3335
3336___HIDDENstatic int ___device_process_kind
3337 ___P((___device *self),(___device *self)
3338 (self)(___device *self)
3339___device *self;)(___device *self)
3340{
3341 return ___PROCESS_DEVICE_KIND((15 +32)+65536);
3342}
3343
3344___SCMOBJlong ___device_process_cleanup
3345 ___P((___device_process *dev),(___device_process *dev)
3346 (dev)(___device_process *dev)
3347___device_process *dev;)(___device_process *dev)
3348{
3349 if (!dev->cleanuped)
3350 {
3351 dev->cleanuped = 1;
3352
3353#ifdef USE_POSIX
3354#endif
3355
3356#ifdef USE_WIN32
3357
3358 CloseHandle (dev->pi.hProcess); /* ignore error */
3359 CloseHandle (dev->pi.hThread); /* ignore error */
3360
3361#endif
3362 }
3363
3364 return ___FIX(___NO_ERR)(((long)(0))<<2);
3365}
3366
3367
3368___SCMOBJlong ___device_process_status_set
3369 ___P((___device_process *dev,(___device_process *dev, int status)
3370 int status),(___device_process *dev, int status)
3371 (dev,(___device_process *dev, int status)
3372 status)(___device_process *dev, int status)
3373___device_process *dev;(___device_process *dev, int status)
3374int status;)(___device_process *dev, int status)
3375{
3376 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
3377
3378 if (!dev->got_status)
3379 {
3380 dev->status = status;
3381 dev->got_status = 1;
3382 e = ___device_process_cleanup (dev); /* ignore error */
3383 }
3384
3385 return e;
3386}
3387
3388
3389___SCMOBJlong ___device_process_status_poll
3390 ___P((___device_process *dev),(___device_process *dev)
3391 (dev)(___device_process *dev)
3392___device_process *dev;)(___device_process *dev)
3393{
3394 if (!dev->got_status)
3395 {
3396#ifdef USE_POSIX
3397
3398 /*
3399 * The process status is updated asynchronously by
3400 * sigchld_signal_handler.
3401 */
3402
3403#endif
3404
3405#ifdef USE_WIN32
3406
3407 DWORD status;
3408
3409 if (!GetExitCodeProcess (dev->pi.hProcess, &status))
3410 return err_code_from_GetLastError ()___err_code_from_GetLastError();
3411
3412 if (status != STILL_ACTIVE)
3413 ___device_process_status_set (dev, status << 8); /* ignore error */
3414
3415#endif
3416 }
3417
3418 return ___FIX(___NO_ERR)(((long)(0))<<2);
3419}
3420
3421___HIDDENstatic ___SCMOBJlong ___device_process_close_raw_virt
3422 ___P((___device_stream *self,(___device_stream *self, int direction)
3423 int direction),(___device_stream *self, int direction)
3424 (self,(___device_stream *self, int direction)
3425 direction)(___device_stream *self, int direction)
3426___device_stream *self;(___device_stream *self, int direction)
3427int direction;)(___device_stream *self, int direction)
3428{
3429 ___device_process *d = ___CAST(___device_process*,self)((___device_process*)(self));
3430 ___SCMOBJlong e = ___device_pipe_close_raw_virt (self, direction);
3431
3432 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
3433 {
3434 if (d->base.base.base.read_stage == ___STAGE_CLOSED3 &&
3435 d->base.base.base.write_stage == ___STAGE_CLOSED3)
3436 ___device_process_status_poll (d); /* ignore error */
3437 }
3438
3439 return e;
3440}
3441
3442___HIDDENstatic ___SCMOBJlong ___device_process_select_raw_virt
3443 ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3444 ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3445 int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3446 int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3447 ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3448 (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3449 for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3450 i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3451 pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3452 state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3453___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3454___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3455int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3456int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3457___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3458{
3459 return ___device_pipe_select_raw_virt (self, for_writing, i, pass, state);
3460}
3461
3462___HIDDENstatic ___SCMOBJlong ___device_process_release_raw_virt
3463 ___P((___device_stream *self),(___device_stream *self)
3464 (self)(___device_stream *self)
3465___device_stream *self;)(___device_stream *self)
3466{
3467 ___device_process *d = ___CAST(___device_process*,self)((___device_process*)(self));
3468 ___SCMOBJlong e1 = ___device_pipe_release_raw_virt (self);
3469 ___SCMOBJlong e2 = ___device_process_cleanup (d);
3470 if (e1 == ___FIX(___NO_ERR)(((long)(0))<<2))
3471 e1 = e2;
3472 return e1;
3473}
3474
3475___HIDDENstatic ___SCMOBJlong ___device_process_force_output_raw_virt
3476 ___P((___device_stream *self,(___device_stream *self, int level)
3477 int level),(___device_stream *self, int level)
3478 (self,(___device_stream *self, int level)
3479 level)(___device_stream *self, int level)
3480___device_stream *self;(___device_stream *self, int level)
3481int level;)(___device_stream *self, int level)
3482{
3483 return ___device_pipe_force_output_raw_virt (self, level);
3484}
3485
3486___HIDDENstatic ___SCMOBJlong ___device_process_seek_raw_virt
3487 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
3488 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
3489 int whence),(___device_stream *self, ___stream_index *pos, int whence)
3490 (self,(___device_stream *self, ___stream_index *pos, int whence)
3491 pos,(___device_stream *self, ___stream_index *pos, int whence)
3492 whence)(___device_stream *self, ___stream_index *pos, int whence)
3493___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
3494___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
3495int whence;)(___device_stream *self, ___stream_index *pos, int whence)
3496{
3497 return ___device_pipe_seek_raw_virt (self, pos, whence);
3498}
3499
3500___HIDDENstatic ___SCMOBJlong ___device_process_read_raw_virt
3501 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3502 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3503 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3504 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3505 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3506 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3507 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3508 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3509___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3510___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3511___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3512___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3513{
3514 return ___device_pipe_read_raw_virt (self, buf, len, len_done);
3515}
3516
3517___HIDDENstatic ___SCMOBJlong ___device_process_write_raw_virt
3518 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3519 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3520 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3521 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3522 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3523 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3524 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3525 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3526___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3527___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3528___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3529___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
3530{
3531 return ___device_pipe_write_raw_virt (self, buf, len, len_done);
3532}
3533
3534___HIDDENstatic ___SCMOBJlong ___device_process_width_virt
3535 ___P((___device_stream *self),(___device_stream *self)
3536 (self)(___device_stream *self)
3537___device_stream *self;)(___device_stream *self)
3538{
3539 return ___FIX(80)(((long)(80))<<2);
3540}
3541
3542___HIDDENstatic ___SCMOBJlong ___device_process_default_options_virt
3543 ___P((___device_stream *self),(___device_stream *self)
3544 (self)(___device_stream *self)
3545___device_stream *self;)(___device_stream *self)
3546{
3547 return ___device_pipe_default_options_virt (self);
3548}
3549
3550
3551___HIDDENstatic ___SCMOBJlong ___device_process_options_set_virt
3552 ___P((___device_stream *self,(___device_stream *self, long options)
3553 ___SCMOBJ options),(___device_stream *self, long options)
3554 (self,(___device_stream *self, long options)
3555 options)(___device_stream *self, long options)
3556___device_stream *self;(___device_stream *self, long options)
3557___SCMOBJ options;)(___device_stream *self, long options)
3558{
3559 return ___device_pipe_options_set_virt (self, options);
3560}
3561
3562
3563___HIDDENstatic ___device_process_vtbl ___device_process_table =
3564{
3565 {
3566 {
3567 ___device_process_kind,
3568 ___device_stream_select_virt,
3569 ___device_stream_release_virt,
3570 ___device_stream_force_output_virt,
3571 ___device_stream_close_virt
3572 },
3573 ___device_process_select_raw_virt,
3574 ___device_process_release_raw_virt,
3575 ___device_process_force_output_raw_virt,
3576 ___device_process_close_raw_virt,
3577 ___device_process_seek_raw_virt,
3578 ___device_process_read_raw_virt,
3579 ___device_process_write_raw_virt,
3580 ___device_process_width_virt,
3581 ___device_process_default_options_virt,
3582 ___device_process_options_set_virt
3583 }
3584};
3585
3586#ifdef USE_POSIX
3587
3588___SCMOBJlong ___device_process_setup_from_pid
3589 ___P((___device_process **dev,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3590 ___device_group *dgroup,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3591 pid_t pid,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3592 int fd_stdin,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3593 int fd_stdout,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3594 int direction),(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3595 (dev,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3596 dgroup,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3597 pid,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3598 fd_stdin,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3599 fd_stdout,(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3600 direction)(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3601___device_process **dev;(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3602___device_group *dgroup;(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3603pid_t pid;(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3604int fd_stdin;(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3605int fd_stdout;(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3606int direction;)(___device_process **dev, ___device_group *dgroup, pid_t pid,
int fd_stdin, int fd_stdout, int direction)
3607{
3608 ___device_process *d;
3609
3610 d = ___CAST(___device_process*,((___device_process*)(___alloc_mem (sizeof (___device_process
))))
3611 ___alloc_mem (sizeof (___device_process)))((___device_process*)(___alloc_mem (sizeof (___device_process
))))
;
3612
3613 if (d == NULL((void*)0))
3614 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
3615
3616 /*
3617 * Setup file descriptors to perform nonblocking I/O.
3618 */
3619
3620 if ((fd_stdout >= 0 &&
3621 (direction & ___DIRECTION_RD1) &&
3622 (set_fd_blocking_mode (fd_stdout, 0) < 0)) ||
3623 (fd_stdin >= 0 &&
3624 (direction & ___DIRECTION_WR2) &&
3625 (set_fd_blocking_mode (fd_stdin, 0) < 0)))
3626 {
3627 ___SCMOBJlong e = err_code_from_errno ()___err_code_from_errno();
3628 ___free_mem (d);
3629 return e;
3630 }
3631
3632 d->base.base.base.vtbl = &___device_process_table;
3633 d->base.fd_rd = fd_stdout;
3634 d->base.fd_wr = fd_stdin;
3635 d->pid = pid;
3636 d->status = -1;
3637 d->got_status = 0;
3638 d->cleanuped = 0;
3639
3640 *dev = d;
3641
3642 return ___device_stream_setup
3643 (&d->base.base,
3644 dgroup,
3645 direction,
3646 0);
3647}
3648
3649#endif
3650
3651#ifdef USE_WIN32
3652
3653___SCMOBJlong ___device_process_setup_from_process
3654 ___P((___device_process **dev,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3655 ___device_group *dgroup,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3656 PROCESS_INFORMATION pi,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3657 HANDLE hstdin,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3658 HANDLE hstdout,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3659 int direction),(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3660 (dev,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3661 dgroup,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3662 pi,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3663 hstdin,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3664 hstdout,(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3665 direction)(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3666___device_process **dev;(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3667___device_group *dgroup;(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3668PROCESS_INFORMATION pi;(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3669HANDLE hstdin;(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3670HANDLE hstdout;(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3671int direction;)(___device_process **dev, ___device_group *dgroup, PROCESS_INFORMATION
pi, HANDLE hstdin, HANDLE hstdout, int direction)
3672{
3673 ___device_process *d;
3674
3675 d = ___CAST(___device_process*,((___device_process*)(___alloc_mem (sizeof (___device_process
))))
3676 ___alloc_mem (sizeof (___device_process)))((___device_process*)(___alloc_mem (sizeof (___device_process
))))
;
3677
3678 if (d == NULL((void*)0))
3679 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
3680
3681 d->base.base.base.vtbl = &___device_process_table;
3682 d->base.h_rd = hstdout;
3683 d->base.h_wr = hstdin;
3684 d->pi = pi;
3685 d->status = -1;
3686 d->got_status = 0;
3687 d->cleanuped = 0;
3688
3689 *dev = d;
3690
3691 return ___device_stream_setup
3692 (&d->base.base,
3693 dgroup,
3694 direction,
3695 0);
3696}
3697
3698#endif
3699
3700
3701/*---------------------------------------------------------------------------*/
3702
3703#ifdef USE_NETWORKING
3704
3705/* Socket utilities */
3706
3707#ifdef USE_POSIX
3708#define SOCKET_TYPEint int
3709#define SOCKET_CALL_ERROR(s)((s) < 0) ((s) < 0)
3710#define SOCKET_CALL_ERROR2(s)((s) < 0) ((s) < 0)
3711#define CONNECT_IN_PROGRESS((*__errno_location ()) == 115) (errno(*__errno_location ()) == EINPROGRESS115)
3712#define CONNECT_WOULD_BLOCK((*__errno_location ()) == 11) (errno(*__errno_location ()) == EAGAIN11)
3713#define NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
((e) == ___FIX(___ERRNO_ERR(ENOTCONN))(((long)(((107)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(107)))))<<2)
)
3714#define CLOSE_SOCKET(s)close_no_EINTR (s) close_no_EINTR (s)
3715#define ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno() err_code_from_errno ()___err_code_from_errno()
3716#define IOCTL_SOCKET(s,cmd,argp)ioctl (s,cmd,argp) ioctl (s,cmd,argp)
3717#define SOCKET_LEN_TYPEsocklen_t socklen_t
3718#endif
3719
3720#ifdef USE_WIN32
3721#define SOCKET_TYPEint SOCKET
3722#define SOCKET_CALL_ERROR(s)((s) < 0) ((s) == SOCKET_ERROR)
3723#define SOCKET_CALL_ERROR2(s)((s) < 0) ((s) == INVALID_SOCKET)
3724#define CONNECT_IN_PROGRESS((*__errno_location ()) == 115) ((WSAGetLastError () == WSAEALREADY) || \
3725(WSAGetLastError () == WSAEISCONN))
3726#define CONNECT_WOULD_BLOCK((*__errno_location ()) == 11) ((WSAGetLastError () == WSAEWOULDBLOCK) || \
3727(WSAGetLastError () == WSAEINVAL))
3728#define NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
((e) == ___FIX(___WIN32_ERR(WSAENOTCONN))(((long)((((HRESULT_FROM_WIN32(WSAENOTCONN))&~(~((int)(0)
)<<25)) | (((HRESULT_FROM_WIN32(WSAENOTCONN))&~((int
)(0))<<27)>>2))))<<2)
)
3729#define CLOSE_SOCKET(s)close_no_EINTR (s) closesocket (s)
3730#define ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno() err_code_from_WSAGetLastError ()___err_code_from_WSAGetLastError()
3731#define IOCTL_SOCKET(s,cmd,argp)ioctl (s,cmd,argp) ioctlsocket (s,cmd,argp)
3732#define SOCKET_LEN_TYPEsocklen_t int
3733#endif
3734
3735#ifdef SHUT_RDSHUT_RD
3736#define SHUTDOWN_RDSHUT_RD SHUT_RDSHUT_RD
3737#else
3738#ifdef SD_RECEIVE
3739#define SHUTDOWN_RDSHUT_RD SD_RECEIVE
3740#else
3741#define SHUTDOWN_RDSHUT_RD 0
3742#endif
3743#endif
3744
3745#ifdef SHUT_WRSHUT_WR
3746#define SHUTDOWN_WRSHUT_WR SHUT_WRSHUT_WR
3747#else
3748#ifdef SD_SEND
3749#define SHUTDOWN_WRSHUT_WR SD_SEND
3750#else
3751#define SHUTDOWN_WRSHUT_WR 1
3752#endif
3753#endif
3754
3755#endif
3756
3757
3758/*---------------------------------------------------------------------------*/
3759
3760#ifdef USE_NETWORKING
3761
3762/* TCP client stream device */
3763
3764typedef struct ___device_tcp_client_struct
3765 {
3766 ___device_stream base;
3767 SOCKET_TYPEint s;
3768 struct sockaddr server_addr;
3769 SOCKET_LEN_TYPEsocklen_t server_addrlen;
3770 int try_connect_again;
3771 int connect_done;
3772
3773#ifdef USE_POSIX
3774
3775 int try_connect_interval_nsecs;
3776
3777#endif
3778
3779#ifdef USE_WIN32
3780
3781 long io_events; /* used by ___device_tcp_client_select_raw_virt */
3782 HANDLE io_event; /* used by ___device_tcp_client_select_raw_virt */
3783
3784#endif
3785 } ___device_tcp_client;
3786
3787
3788typedef struct ___device_tcp_client_vtbl_struct
3789 {
3790 ___device_stream_vtbl base;
3791 } ___device_tcp_client_vtbl;
3792
3793
3794___HIDDENstatic int try_connect
3795 ___P((___device_tcp_client *dev),(___device_tcp_client *dev)
3796 (dev)(___device_tcp_client *dev)
3797___device_tcp_client *dev;)(___device_tcp_client *dev)
3798{
3799 if (!SOCKET_CALL_ERROR(connect (dev->s,((connect (dev->s, &dev->server_addr, dev->server_addrlen
)) < 0)
3800 &dev->server_addr,((connect (dev->s, &dev->server_addr, dev->server_addrlen
)) < 0)
3801 dev->server_addrlen))((connect (dev->s, &dev->server_addr, dev->server_addrlen
)) < 0)
||
3802 CONNECT_IN_PROGRESS((*__errno_location ()) == 115) || /* establishing connection in background */
3803 dev->try_connect_again == 2) /* last connect attempt? */
3804 {
3805 dev->try_connect_again = 0; /* we're done waiting */
3806 return 0;
3807 }
3808
3809 if (CONNECT_WOULD_BLOCK((*__errno_location ()) == 11)) /* connect can't be performed now */
3810 return 0;
3811
3812 return -1;
3813}
3814
3815___HIDDENstatic int ___device_tcp_client_kind
3816 ___P((___device *self),(___device *self)
3817 (self)(___device *self)
3818___device *self;)(___device *self)
3819{
3820 return ___TCP_CLIENT_DEVICE_KIND(15 +256);
3821}
3822
3823
3824___HIDDENstatic ___SCMOBJlong ___device_tcp_client_close_raw_virt
3825 ___P((___device_stream *self,(___device_stream *self, int direction)
3826 int direction),(___device_stream *self, int direction)
3827 (self,(___device_stream *self, int direction)
3828 direction)(___device_stream *self, int direction)
3829___device_stream *self;(___device_stream *self, int direction)
3830int direction;)(___device_stream *self, int direction)
3831{
3832 ___device_tcp_client *d = ___CAST(___device_tcp_client*,self)((___device_tcp_client*)(self));
3833 int is_not_closed = 0;
3834
3835 if (d->base.base.read_stage != ___STAGE_CLOSED3)
3836 is_not_closed |= ___DIRECTION_RD1;
3837
3838 if (d->base.base.write_stage != ___STAGE_CLOSED3)
3839 is_not_closed |= ___DIRECTION_WR2;
3840
3841 if (is_not_closed == 0)
3842 return ___FIX(___NO_ERR)(((long)(0))<<2);
3843
3844 if ((is_not_closed & ~direction) == 0)
3845 {
3846 /* Close socket when both sides are closed. */
3847
3848 d->base.base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */
3849 d->base.base.write_stage = ___STAGE_CLOSED3;
3850
3851#ifdef USE_WIN32
3852
3853 if (d->io_event != NULL((void*)0))
3854 CloseHandle (d->io_event); /* ignore error */
3855
3856#endif
3857
3858 if ((d->base.base.close_direction & (___DIRECTION_RD1|___DIRECTION_WR2))
3859 == (___DIRECTION_RD1|___DIRECTION_WR2))
3860 {
3861 if (CLOSE_SOCKET(d->s)close_no_EINTR (d->s) != 0)
3862 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
3863 }
3864 }
3865 else if (is_not_closed & direction & ___DIRECTION_RD1)
3866 {
3867 /* Shutdown receiving side. */
3868
3869 if ((d->base.base.close_direction & ___DIRECTION_RD1)
3870 == ___DIRECTION_RD1)
3871 {
3872 if (shutdown (d->s, SHUTDOWN_RDSHUT_RD) != 0)
3873 {
3874 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
3875 if (!NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
)
3876 return e;
3877 }
3878 }
3879
3880 d->base.base.read_stage = ___STAGE_CLOSED3;
3881 }
3882 else if (is_not_closed & direction & ___DIRECTION_WR2)
3883 {
3884 /* Shutdown sending side. */
3885
3886 if ((d->base.base.close_direction & ___DIRECTION_WR2)
3887 == ___DIRECTION_WR2)
3888 {
3889 if (shutdown (d->s, SHUTDOWN_WRSHUT_WR) != 0)
3890 {
3891 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
3892 if (!NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
)
3893 return e;
3894 }
3895 }
3896
3897 d->base.base.write_stage = ___STAGE_CLOSED3;
3898 }
3899
3900 return ___FIX(___NO_ERR)(((long)(0))<<2);
3901}
3902
3903___HIDDENstatic ___SCMOBJlong ___device_tcp_client_select_raw_virt
3904 ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3905 ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3906 int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3907 int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3908 ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3909 (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3910 for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3911 i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3912 pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3913 state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3914___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3915___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3916int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3917int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3918___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
3919{
3920 ___device_tcp_client *d = ___CAST(___device_tcp_client*,self)((___device_tcp_client*)(self));
3921 int stage = (for_writing
3922 ? d->base.base.write_stage
3923 : d->base.base.read_stage);
3924
3925 if (pass == ___SELECT_PASS_11)
3926 {
3927 if (stage != ___STAGE_OPEN0)
3928 {
3929 state->timeout = ___time_mod.time_neg_infinity;
3930 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
3931 }
3932 else
3933 {
3934#ifdef USE_POSIX
3935
3936 if (d->try_connect_again != 0)
3937 {
3938 int interval = d->try_connect_interval_nsecs * 6 / 5;
3939 if (interval > 200000000) /* max interval = 0.2 sec */
3940 interval = 200000000;
3941 d->try_connect_interval_nsecs = interval;
3942 ___device_select_add_relative_timeout (state, i, interval * 1e-9);
3943 }
3944 else
3945 ___device_select_add_fd (state, d->s, for_writing);
3946
3947 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
3948
3949#endif
3950
3951#ifdef USE_WIN32
3952
3953 d->io_events = 0;
3954
3955 return ___FIX(___NO_ERR)(((long)(0))<<2);
3956
3957#endif
3958 }
3959 }
3960
3961#ifdef USE_WIN32
3962
3963 else if (pass == ___SELECT_PASS_22)
3964 {
3965 if (d->try_connect_again != 0)
3966 d->io_events = (FD_CONNECT | FD_CLOSE);
3967 else if (for_writing)
3968 d->io_events |= (FD_WRITE | FD_CLOSE);
3969 else
3970 d->io_events |= (FD_READ | FD_CLOSE);
3971
3972 return ___FIX(___NO_ERR)(((long)(0))<<2);
3973 }
3974 else if (pass == ___SELECT_PASS_33)
3975 {
3976 HANDLE wait_obj = d->io_event;
3977
3978 ResetEvent (wait_obj); /* ignore error */
3979
3980 WSAEventSelect (d->s, wait_obj, d->io_events);
3981
3982 ___device_select_add_wait_obj (state, i, wait_obj);
3983
3984 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
3985 }
3986
3987#endif
3988
3989 /* pass == ___SELECT_PASS_CHECK */
3990
3991 if (stage != ___STAGE_OPEN0)
3992 state->devs[i] = NULL((void*)0);
3993 else
3994 {
3995#ifdef USE_POSIX
3996
3997 if (d->try_connect_again != 0 ||
3998 (for_writing
3999 ? ___FD_ISSET(d->s, &state->writefds)((((&state->writefds)->__fds_bits)[((d->s) / (8 *
(int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((
d->s) % (8 * (int) sizeof (__fd_mask))))) != 0)
4000 : ___FD_ISSET(d->s, &state->readfds)((((&state->readfds)->__fds_bits)[((d->s) / (8 *
(int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((
d->s) % (8 * (int) sizeof (__fd_mask))))) != 0)
))
4001 {
4002 d->connect_done = 1;
4003 state->devs[i] = NULL((void*)0);
4004 }
4005
4006#endif
4007
4008#ifdef USE_WIN32
4009
4010 if (state->devs_next[i] != -1)
4011 {
4012 state->devs[i] = NULL((void*)0);
4013 if (d->try_connect_again != 0)
4014 {
4015 d->connect_done = 1;
4016 d->try_connect_again = 2;
4017 }
4018 }
4019
4020#endif
4021 }
4022
4023 return ___FIX(___NO_ERR)(((long)(0))<<2);
4024}
4025
4026___HIDDENstatic ___SCMOBJlong ___device_tcp_client_release_raw_virt
4027 ___P((___device_stream *self),(___device_stream *self)
4028 (self)(___device_stream *self)
4029___device_stream *self;)(___device_stream *self)
4030{
4031 return ___FIX(___NO_ERR)(((long)(0))<<2);
4032}
4033
4034___HIDDENstatic ___SCMOBJlong ___device_tcp_client_force_output_raw_virt
4035 ___P((___device_stream *self,(___device_stream *self, int level)
4036 int level),(___device_stream *self, int level)
4037 (self,(___device_stream *self, int level)
4038 level)(___device_stream *self, int level)
4039___device_stream *self;(___device_stream *self, int level)
4040int level;)(___device_stream *self, int level)
4041{
4042 return ___FIX(___NO_ERR)(((long)(0))<<2);
4043}
4044
4045___HIDDENstatic ___SCMOBJlong ___device_tcp_client_seek_raw_virt
4046 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
4047 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
4048 int whence),(___device_stream *self, ___stream_index *pos, int whence)
4049 (self,(___device_stream *self, ___stream_index *pos, int whence)
4050 pos,(___device_stream *self, ___stream_index *pos, int whence)
4051 whence)(___device_stream *self, ___stream_index *pos, int whence)
4052___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
4053___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
4054int whence;)(___device_stream *self, ___stream_index *pos, int whence)
4055{
4056 return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+7)))<<2)
;
4057}
4058
4059___HIDDENstatic ___SCMOBJlong ___device_tcp_client_read_raw_virt
4060 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4061 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4062 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4063 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4064 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4065 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4066 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4067 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4068___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4069___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4070___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4071___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4072{
4073 ___device_tcp_client *d = ___CAST(___device_tcp_client*,self)((___device_tcp_client*)(self));
4074 int n;
4075
4076 if (d->base.base.read_stage != ___STAGE_OPEN0)
4077 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
4078
4079 if (d->try_connect_again != 0)
4080 {
4081 if (try_connect (d) == 0)
4082 {
4083 if (d->try_connect_again != 0)
4084 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
4085 }
4086 else
4087 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4088 }
4089
4090 if (SOCKET_CALL_ERROR(n = recv (d->s, ___CAST(char*,buf), len, 0))((n = recv (d->s, ((char*)(buf)), len, 0)) < 0))
4091 {
4092 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4093 if (NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
&& !d->connect_done)
4094 e = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
4095 return e;
4096 }
4097
4098 *len_done = n;
4099
4100 return ___FIX(___NO_ERR)(((long)(0))<<2);
4101}
4102
4103
4104___HIDDENstatic ___SCMOBJlong ___device_tcp_client_write_raw_virt
4105 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4106 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4107 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4108 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4109 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4110 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4111 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4112 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4113___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4114___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4115___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4116___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
4117{
4118 ___device_tcp_client *d = ___CAST(___device_tcp_client*,self)((___device_tcp_client*)(self));
4119 int n;
4120
4121 if (d->base.base.write_stage != ___STAGE_OPEN0)
4122 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
4123
4124 if (d->try_connect_again != 0)
4125 {
4126 if (try_connect (d) == 0)
4127 {
4128 if (d->try_connect_again != 0)
4129 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
4130 }
4131 else
4132 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4133 }
4134
4135 if (SOCKET_CALL_ERROR(n = send (d->s, ___CAST(char*,buf), len, 0))((n = send (d->s, ((char*)(buf)), len, 0)) < 0))
4136 {
4137 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4138 if (NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
&& !d->connect_done)
4139 e = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
4140 return e;
4141 }
4142
4143 *len_done = n;
4144
4145 return ___FIX(___NO_ERR)(((long)(0))<<2);
4146}
4147
4148
4149___HIDDENstatic ___SCMOBJlong ___device_tcp_client_width_virt
4150 ___P((___device_stream *self),(___device_stream *self)
4151 (self)(___device_stream *self)
4152___device_stream *self;)(___device_stream *self)
4153{
4154 return ___FIX(80)(((long)(80))<<2);
4155}
4156
4157
4158___HIDDENstatic ___SCMOBJlong ___device_tcp_client_default_options_virt
4159 ___P((___device_stream *self),(___device_stream *self)
4160 (self)(___device_stream *self)
4161___device_stream *self;)(___device_stream *self)
4162{
4163 int char_encoding_errors = ___CHAR_ENCODING_ERRORS_ON(1<<5);
4164 int char_encoding = ___CHAR_ENCODING_ISO_8859_1(2<<0);
4165 int eol_encoding = ___EOL_ENCODING_LF(1<<7);
4166 int buffering = ___FULL_BUFFERING(3<<9);
4167
4168 return ___FIX(___STREAM_OPTIONS(char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4169 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4170 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4171 buffering,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4172 char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4173 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4174 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
4175 buffering))(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
;
4176}
4177
4178
4179___HIDDENstatic ___SCMOBJlong ___device_tcp_client_options_set_virt
4180 ___P((___device_stream *self,(___device_stream *self, long options)
4181 ___SCMOBJ options),(___device_stream *self, long options)
4182 (self,(___device_stream *self, long options)
4183 options)(___device_stream *self, long options)
4184___device_stream *self;(___device_stream *self, long options)
4185___SCMOBJ options;)(___device_stream *self, long options)
4186{
4187 return ___FIX(___NO_ERR)(((long)(0))<<2);
4188}
4189
4190
4191___HIDDENstatic ___device_tcp_client_vtbl ___device_tcp_client_table =
4192{
4193 {
4194 {
4195 ___device_tcp_client_kind,
4196 ___device_stream_select_virt,
4197 ___device_stream_release_virt,
4198 ___device_stream_force_output_virt,
4199 ___device_stream_close_virt
4200 },
4201 ___device_tcp_client_select_raw_virt,
4202 ___device_tcp_client_release_raw_virt,
4203 ___device_tcp_client_force_output_raw_virt,
4204 ___device_tcp_client_close_raw_virt,
4205 ___device_tcp_client_seek_raw_virt,
4206 ___device_tcp_client_read_raw_virt,
4207 ___device_tcp_client_write_raw_virt,
4208 ___device_tcp_client_width_virt,
4209 ___device_tcp_client_default_options_virt,
4210 ___device_tcp_client_options_set_virt
4211 }
4212};
4213
4214
4215#define ___SOCK_KEEPALIVE_FLAG(options)(((options) & 1) != 0) (((options) & 1) != 0)
4216#define ___SOCK_NO_COALESCE_FLAG(options)(((options) & 2) != 0) (((options) & 2) != 0)
4217#define ___SOCK_REUSE_ADDRESS_FLAG(options)(((options) & 2048) != 0) (((options) & 2048) != 0)
4218
4219
4220___HIDDENstatic ___SCMOBJlong create_tcp_socket
4221 ___P((SOCKET_TYPE *sock,(int *sock, int options)
4222 int options),(int *sock, int options)
4223 (sock,(int *sock, int options)
4224 options)(int *sock, int options)
4225SOCKET_TYPE *sock;(int *sock, int options)
4226int options;)(int *sock, int options)
4227{
4228 int keepalive_flag = ___SOCK_KEEPALIVE_FLAG(options)(((options) & 1) != 0);
4229 int no_coalesce_flag = ___SOCK_NO_COALESCE_FLAG(options)(((options) & 2) != 0);
4230 int reuse_address_flag = ___SOCK_REUSE_ADDRESS_FLAG(options)(((options) & 2048) != 0);
4231 SOCKET_TYPEint s;
4232
4233 if (SOCKET_CALL_ERROR2(s = socket (AF_INET, SOCK_STREAM, 0))((s = socket (2, SOCK_STREAM, 0)) < 0))
5
Taking true branch
4234 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4235
4236#ifndef TCP_NODELAY1
4237#define TCP_NODELAY1 1
4238#endif
4239
4240 if ((keepalive_flag != 0 &&
4241 setsockopt (s, /* keep connection alive or not */
4242 SOL_SOCKET1,
4243 SO_KEEPALIVE9,
4244 ___CAST(char*,&keepalive_flag)((char*)(&keepalive_flag)),
4245 sizeof (keepalive_flag)) != 0) ||
4246 (reuse_address_flag != 0 &&
4247 setsockopt (s, /* allow reusing the same address */
4248 SOL_SOCKET1,
4249 SO_REUSEADDR2,
4250 ___CAST(char*,&reuse_address_flag)((char*)(&reuse_address_flag)),
4251 sizeof (reuse_address_flag)) != 0) ||
4252 (no_coalesce_flag != 0 &&
4253 setsockopt (s, /* enable or disable packet coalescing algorithm */
4254 IPPROTO_TCPIPPROTO_TCP,
4255 TCP_NODELAY1,
4256 ___CAST(char*,&no_coalesce_flag)((char*)(&no_coalesce_flag)),
4257 sizeof (no_coalesce_flag)) != 0))
4258 {
4259 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4260 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4261 return e;
4262 }
4263
4264 *sock = s;
4265
4266 return ___FIX(___NO_ERR)(((long)(0))<<2);
4267}
4268
4269
4270___HIDDENstatic int set_socket_non_blocking
4271 ___P((SOCKET_TYPE s),(int s)
4272 (s)(int s)
4273SOCKET_TYPE s;)(int s)
4274{
4275#ifndef USE_ioctl
4276#undef FIONBIO0x5421
4277#endif
4278
4279#ifdef FIONBIO0x5421
4280
4281 unsigned long param = 1;
4282
4283 return SOCKET_CALL_ERROR(IOCTL_SOCKET(s, FIONBIO, &param))((ioctl (s,0x5421,&param)) < 0);
4284
4285#else
4286
4287 return set_fd_blocking_mode (s, 0);
4288
4289#endif
4290}
4291
4292
4293___SCMOBJlong ___device_tcp_client_setup_from_socket
4294 ___P((___device_tcp_client **dev,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4295 ___device_group *dgroup,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4296 SOCKET_TYPE s,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4297 struct sockaddr *server_addr,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4298 SOCKET_LEN_TYPE server_addrlen,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4299 int try_connect_again,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4300 int direction),(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4301 (dev,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4302 dgroup,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4303 s,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4304 server_addr,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4305 server_addrlen,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4306 try_connect_again,(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4307 direction)(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4308___device_tcp_client **dev;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4309___device_group *dgroup;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4310SOCKET_TYPE s;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4311struct sockaddr *server_addr;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4312SOCKET_LEN_TYPE server_addrlen;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4313int try_connect_again;(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4314int direction;)(___device_tcp_client **dev, ___device_group *dgroup, int s, struct
sockaddr *server_addr, socklen_t server_addrlen, int try_connect_again
, int direction)
4315{
4316 ___SCMOBJlong e;
4317 ___device_tcp_client *d;
4318
4319 d = ___CAST(___device_tcp_client*,((___device_tcp_client*)(___alloc_mem (sizeof (___device_tcp_client
))))
4320 ___alloc_mem (sizeof (___device_tcp_client)))((___device_tcp_client*)(___alloc_mem (sizeof (___device_tcp_client
))))
;
4321
4322 if (d == NULL((void*)0))
4323 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
4324
4325 /*
4326 * Setup socket to perform nonblocking I/O.
4327 */
4328
4329 if (set_socket_non_blocking (s) != 0) /* set nonblocking mode */
4330 {
4331 e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4332 ___free_mem (d);
4333 return e;
4334 }
4335
4336 d->base.base.vtbl = &___device_tcp_client_table;
4337 d->s = s;
4338 d->server_addr = *server_addr;
4339 d->server_addrlen = server_addrlen;
4340 d->try_connect_again = try_connect_again;
4341 d->connect_done = 0;
4342
4343#ifdef USE_POSIX
4344
4345 d->try_connect_interval_nsecs = 1000000; /* 0.001 secs */
4346
4347#endif
4348
4349#ifdef USE_WIN32
4350
4351 d->io_event =
4352 CreateEvent (NULL((void*)0), /* can't inherit */
4353 TRUE, /* manual reset */
4354 FALSE, /* not signaled */
4355 NULL((void*)0)); /* no name */
4356
4357 if (d->io_event == NULL((void*)0))
4358 {
4359 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
4360 ___free_mem (d);
4361 return e;
4362 }
4363
4364#endif
4365
4366 *dev = d;
4367
4368 return ___device_stream_setup
4369 (&d->base,
4370 dgroup,
4371 direction,
4372 0);
4373}
4374
4375
4376___SCMOBJlong ___device_tcp_client_setup_from_sockaddr
4377 ___P((___device_tcp_client **dev,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4378 ___device_group *dgroup,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4379 struct sockaddr *server_addr,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4380 SOCKET_LEN_TYPE server_addrlen,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4381 int options,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4382 int direction),(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4383 (dev,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4384 dgroup,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4385 server_addr,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4386 server_addrlen,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4387 options,(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4388 direction)(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4389___device_tcp_client **dev;(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4390___device_group *dgroup;(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4391struct sockaddr *server_addr;(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4392SOCKET_LEN_TYPE server_addrlen;(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4393int options;(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4394int direction;)(___device_tcp_client **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int options, int direction
)
4395{
4396 ___SCMOBJlong e;
4397 SOCKET_TYPEint s;
3
Within the expansion of the macro 'SOCKET_TYPE':
a
's' declared without an initial value
4398 ___device_tcp_client *d;
4399
4400 if ((e = create_tcp_socket (&s, options)) != ___FIX(___NO_ERR)(((long)(0))<<2))
4
Calling 'create_tcp_socket'
6
Returning from 'create_tcp_socket'
7
Taking false branch
4401 return e;
4402
4403 if ((e = ___device_tcp_client_setup_from_socket
8
Function call argument is an uninitialized value
4404 (&d,
4405 dgroup,
4406 s,
4407 server_addr,
4408 server_addrlen,
4409 1,
4410 direction))
4411 != ___FIX(___NO_ERR)(((long)(0))<<2))
4412 {
4413 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4414 return e;
4415 }
4416
4417 device_transfer_close_responsibility (___CAST(___device*,d)((___device*)(d)));
4418
4419 *dev = d;
4420
4421 if (try_connect (d) != 0)
4422 {
4423 e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4424 ___device_cleanup (&d->base.base); /* ignore error */
4425 return e;
4426 }
4427
4428 return ___FIX(___NO_ERR)(((long)(0))<<2);
4429}
4430
4431#endif
4432
4433
4434/*---------------------------------------------------------------------------*/
4435
4436#ifdef USE_NETWORKING
4437
4438/* TCP server device. */
4439
4440typedef struct ___device_tcp_server_struct
4441 {
4442 ___device base;
4443 SOCKET_TYPEint s;
4444
4445#ifdef USE_WIN32
4446
4447 HANDLE io_event; /* used by ___device_tcp_server_select_raw_virt */
4448
4449#endif
4450 } ___device_tcp_server;
4451
4452typedef struct ___device_tcp_server_vtbl_struct
4453 {
4454 ___device_vtbl base;
4455 } ___device_tcp_server_vtbl;
4456
4457___HIDDENstatic int ___device_tcp_server_kind
4458 ___P((___device *self),(___device *self)
4459 (self)(___device *self)
4460___device *self;)(___device *self)
4461{
4462 return ___TCP_SERVER_DEVICE_KIND(1 +512);
4463}
4464
4465___HIDDENstatic ___SCMOBJlong ___device_tcp_server_close_virt
4466 ___P((___device *self,(___device *self, int direction)
4467 int direction),(___device *self, int direction)
4468 (self,(___device *self, int direction)
4469 direction)(___device *self, int direction)
4470___device *self;(___device *self, int direction)
4471int direction;)(___device *self, int direction)
4472{
4473 ___device_tcp_server *d = ___CAST(___device_tcp_server*,self)((___device_tcp_server*)(self));
4474
4475 if (d->base.read_stage == ___STAGE_CLOSED3)
4476 return ___FIX(___NO_ERR)(((long)(0))<<2);
4477
4478 if (direction & ___DIRECTION_RD1)
4479 {
4480 d->base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */
4481
4482#ifdef USE_WIN32
4483
4484 if (d->io_event != NULL((void*)0))
4485 CloseHandle (d->io_event); /* ignore error */
4486
4487#endif
4488
4489 if ((d->base.close_direction & ___DIRECTION_RD1)
4490 == ___DIRECTION_RD1)
4491 {
4492 if (CLOSE_SOCKET(d->s)close_no_EINTR (d->s) != 0)
4493 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4494 }
4495 }
4496
4497 return ___FIX(___NO_ERR)(((long)(0))<<2);
4498}
4499
4500___HIDDENstatic ___SCMOBJlong ___device_tcp_server_select_virt
4501 ___P((___device *self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4502 ___BOOL for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4503 int i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4504 int pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4505 ___device_select_state *state),(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4506 (self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4507 for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4508 i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4509 pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4510 state)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4511___device *self;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4512___BOOL for_writing;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4513int i;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4514int pass;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4515___device_select_state *state;)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4516{
4517 ___device_tcp_server *d = ___CAST(___device_tcp_server*,self)((___device_tcp_server*)(self));
4518 int stage = (for_writing
4519 ? d->base.write_stage
4520 : d->base.read_stage);
4521
4522 if (pass == ___SELECT_PASS_11)
4523 {
4524 if (stage != ___STAGE_OPEN0)
4525 state->timeout = ___time_mod.time_neg_infinity;
4526 else
4527 {
4528#ifdef USE_POSIX
4529 ___device_select_add_fd (state, d->s, for_writing);
4530#endif
4531
4532#ifdef USE_WIN32
4533
4534 HANDLE wait_obj = d->io_event;
4535
4536 ResetEvent (wait_obj); /* ignore error */
4537
4538 WSAEventSelect (d->s, wait_obj, FD_ACCEPT);
4539
4540 ___device_select_add_wait_obj (state, i, wait_obj);
4541
4542#endif
4543 }
4544
4545 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
4546 }
4547
4548 /* pass == ___SELECT_PASS_CHECK */
4549
4550 if (stage != ___STAGE_OPEN0)
4551 state->devs[i] = NULL((void*)0);
4552 else
4553 {
4554#ifdef USE_POSIX
4555
4556 if (___FD_ISSET(d->s, &state->readfds)((((&state->readfds)->__fds_bits)[((d->s) / (8 *
(int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((
d->s) % (8 * (int) sizeof (__fd_mask))))) != 0)
)
4557 state->devs[i] = NULL((void*)0);
4558
4559#endif
4560
4561#ifdef USE_WIN32
4562
4563 if (state->devs_next[i] != -1)
4564 state->devs[i] = NULL((void*)0);
4565
4566#endif
4567 }
4568
4569 return ___FIX(___NO_ERR)(((long)(0))<<2);
4570}
4571
4572___HIDDENstatic ___SCMOBJlong ___device_tcp_server_release_virt
4573 ___P((___device *self),(___device *self)
4574 (self)(___device *self)
4575___device *self;)(___device *self)
4576{
4577 return ___FIX(___NO_ERR)(((long)(0))<<2);
4578}
4579
4580___HIDDENstatic ___SCMOBJlong ___device_tcp_server_force_output_virt
4581 ___P((___device *self,(___device *self, int level)
4582 int level),(___device *self, int level)
4583 (self,(___device *self, int level)
4584 level)(___device *self, int level)
4585___device *self;(___device *self, int level)
4586int level;)(___device *self, int level)
4587{
4588 return ___FIX(___NO_ERR)(((long)(0))<<2);
4589}
4590
4591___HIDDENstatic ___device_tcp_server_vtbl ___device_tcp_server_table =
4592{
4593 {
4594 ___device_tcp_server_kind,
4595 ___device_tcp_server_select_virt,
4596 ___device_tcp_server_release_virt,
4597 ___device_tcp_server_force_output_virt,
4598 ___device_tcp_server_close_virt
4599 }
4600};
4601
4602
4603___SCMOBJlong ___device_tcp_server_setup
4604 ___P((___device_tcp_server **dev,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4605 ___device_group *dgroup,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4606 struct sockaddr *server_addr,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4607 SOCKET_LEN_TYPE server_addrlen,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4608 int backlog,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4609 int options),(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4610 (dev,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4611 dgroup,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4612 server_addr,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4613 server_addrlen,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4614 backlog,(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4615 options)(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4616___device_tcp_server **dev;(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4617___device_group *dgroup;(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4618struct sockaddr *server_addr;(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4619SOCKET_LEN_TYPE server_addrlen;(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4620int backlog;(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4621int options;)(___device_tcp_server **dev, ___device_group *dgroup, struct sockaddr
*server_addr, socklen_t server_addrlen, int backlog, int options
)
4622{
4623 ___SCMOBJlong e;
4624 SOCKET_TYPEint s;
4625 ___device_tcp_server *d;
4626
4627 if ((e = create_tcp_socket (&s, options)) != ___FIX(___NO_ERR)(((long)(0))<<2))
4628 return e;
4629
4630 if (set_socket_non_blocking (s) != 0 || /* set nonblocking mode */
4631 bind (s, server_addr, server_addrlen) != 0 ||
4632 listen (s, backlog) != 0)
4633 {
4634 e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4635 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4636 return e;
4637 }
4638
4639 d = ___CAST(___device_tcp_server*,((___device_tcp_server*)(___alloc_mem (sizeof (___device_tcp_server
))))
4640 ___alloc_mem (sizeof (___device_tcp_server)))((___device_tcp_server*)(___alloc_mem (sizeof (___device_tcp_server
))))
;
4641
4642 if (d == NULL((void*)0))
4643 {
4644 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4645 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
4646 }
4647
4648 d->base.vtbl = &___device_tcp_server_table;
4649 d->base.refcount = 1;
4650 d->base.direction = ___DIRECTION_RD1;
4651 d->base.close_direction = 0; /* prevent closing on errors */
4652 d->base.read_stage = ___STAGE_OPEN0;
4653 d->base.write_stage = ___STAGE_CLOSED3;
4654
4655#ifdef USE_WIN32
4656
4657 d->io_event =
4658 CreateEvent (NULL((void*)0), /* can't inherit */
4659 TRUE, /* manual reset */
4660 FALSE, /* not signaled */
4661 NULL((void*)0)); /* no name */
4662
4663 if (d->io_event == NULL((void*)0))
4664 {
4665 ___SCMOBJlong e = err_code_from_GetLastError ()___err_code_from_GetLastError();
4666 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4667 ___free_mem (d);
4668 return e;
4669 }
4670
4671#endif
4672
4673 d->s = s;
4674
4675 device_transfer_close_responsibility (___CAST(___device*,d)((___device*)(d)));
4676
4677 *dev = d;
4678
4679 ___device_add_to_group (dgroup, &d->base);
4680
4681 return ___FIX(___NO_ERR)(((long)(0))<<2);
4682}
4683
4684
4685___SCMOBJlong ___device_tcp_server_read
4686 ___P((___device_tcp_server *dev,(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4687 ___device_group *dgroup,(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4688 ___device_tcp_client **client),(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4689 (dev,(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4690 dgroup,(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4691 client)(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4692___device_tcp_server *dev;(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4693___device_group *dgroup;(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4694___device_tcp_client **client;)(___device_tcp_server *dev, ___device_group *dgroup, ___device_tcp_client
**client)
4695{
4696 ___SCMOBJlong e;
4697 struct sockaddr_in addr;
4698 SOCKET_LEN_TYPEsocklen_t addrlen;
4699 SOCKET_TYPEint s;
4700
4701 if (dev->base.read_stage != ___STAGE_OPEN0)
4702 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
4703
4704 addrlen = sizeof (addr);
4705
4706 if (SOCKET_CALL_ERROR2(s = accept (dev->s,((s = accept (dev->s, ((struct sockaddr*)(&addr)), &
addrlen)) < 0)
4707 ___CAST(struct sockaddr*,&addr),((s = accept (dev->s, ((struct sockaddr*)(&addr)), &
addrlen)) < 0)
4708 &addrlen))((s = accept (dev->s, ((struct sockaddr*)(&addr)), &
addrlen)) < 0)
)
4709 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
4710
4711 if ((e = ___device_tcp_client_setup_from_socket
4712 (client,
4713 dgroup,
4714 s,
4715 ___CAST(struct sockaddr*,&addr)((struct sockaddr*)(&addr)),
4716 addrlen,
4717 0,
4718 ___DIRECTION_RD1|___DIRECTION_WR2))
4719 != ___FIX(___NO_ERR)(((long)(0))<<2))
4720 {
4721 CLOSE_SOCKET(s)close_no_EINTR (s); /* ignore error */
4722 return e;
4723 }
4724
4725 device_transfer_close_responsibility (___CAST(___device*,*client)((___device*)(*client)));
4726
4727 return ___FIX(___NO_ERR)(((long)(0))<<2);
4728}
4729
4730#endif
4731
4732
4733/*---------------------------------------------------------------------------*/
4734
4735/* Directory device. */
4736
4737typedef struct ___device_directory_struct
4738 {
4739 ___device base;
4740
4741 int ignore_hidden;
4742
4743#ifdef USE_opendir
4744 DIR *dir;
4745#endif
4746
4747#ifdef USE_FindFirstFile
4748 HANDLE h;
4749 WIN32_FIND_DATA fdata;
4750 ___BOOLint first_file;
4751#endif
4752 } ___device_directory;
4753
4754typedef struct ___device_directory_vtbl_struct
4755 {
4756 ___device_vtbl base;
4757 } ___device_directory_vtbl;
4758
4759___HIDDENstatic int ___device_directory_kind
4760 ___P((___device *self),(___device *self)
4761 (self)(___device *self)
4762___device *self;)(___device *self)
4763{
4764 return ___DIRECTORY_KIND(1 +1024);
4765}
4766
4767___HIDDENstatic ___SCMOBJlong ___device_directory_close_virt
4768 ___P((___device *self,(___device *self, int direction)
4769 int direction),(___device *self, int direction)
4770 (self,(___device *self, int direction)
4771 direction)(___device *self, int direction)
4772___device *self;(___device *self, int direction)
4773int direction;)(___device *self, int direction)
4774{
4775 ___device_directory *d = ___CAST(___device_directory*,self)((___device_directory*)(self));
4776
4777 if (d->base.read_stage == ___STAGE_CLOSED3)
4778 return ___FIX(___NO_ERR)(((long)(0))<<2);
4779
4780 if (direction & ___DIRECTION_RD1)
4781 {
4782 d->base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */
4783
4784 if ((d->base.close_direction & ___DIRECTION_RD1)
4785 == ___DIRECTION_RD1)
4786 {
4787
4788#ifdef USE_opendir
4789 if (closedir (d->dir) < 0)
4790 return err_code_from_errno ()___err_code_from_errno();
4791#endif
4792
4793#ifdef USE_FindFirstFile
4794 if (!FindClose (d->h))
4795 return err_code_from_GetLastError ()___err_code_from_GetLastError();
4796#endif
4797 }
4798 }
4799
4800 return ___FIX(___NO_ERR)(((long)(0))<<2);
4801}
4802
4803___HIDDENstatic ___SCMOBJlong ___device_directory_select_virt
4804 ___P((___device *self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4805 ___BOOL for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4806 int i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4807 int pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4808 ___device_select_state *state),(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4809 (self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4810 for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4811 i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4812 pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4813 state)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4814___device *self;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4815___BOOL for_writing;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4816int i;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4817int pass;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4818___device_select_state *state;)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
4819{
4820 if (pass == ___SELECT_PASS_11)
4821 {
4822 state->timeout = ___time_mod.time_neg_infinity;
4823 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
4824 }
4825
4826 /* pass == ___SELECT_PASS_CHECK */
4827
4828 state->devs[i] = NULL((void*)0);
4829
4830 return ___FIX(___NO_ERR)(((long)(0))<<2);
4831}
4832
4833___HIDDENstatic ___SCMOBJlong ___device_directory_release_virt
4834 ___P((___device *self),(___device *self)
4835 (self)(___device *self)
4836___device *self;)(___device *self)
4837{
4838 return ___FIX(___NO_ERR)(((long)(0))<<2);
4839}
4840
4841___HIDDENstatic ___SCMOBJlong ___device_directory_force_output_virt
4842 ___P((___device *self,(___device *self, int level)
4843 int level),(___device *self, int level)
4844 (self,(___device *self, int level)
4845 level)(___device *self, int level)
4846___device *self;(___device *self, int level)
4847int level;)(___device *self, int level)
4848{
4849 return ___FIX(___NO_ERR)(((long)(0))<<2);
4850}
4851
4852___HIDDENstatic ___device_directory_vtbl ___device_directory_table =
4853{
4854 {
4855 ___device_directory_kind,
4856 ___device_directory_select_virt,
4857 ___device_directory_release_virt,
4858 ___device_directory_force_output_virt,
4859 ___device_directory_close_virt
4860 }
4861};
4862
4863
4864#ifdef USE_opendir
4865#define ___DIR_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
4866#endif
4867
4868#ifdef USE_FindFirstFile
4869#ifdef _UNICODE
4870#define ___DIR_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native ucs2
4871#else
4872#define ___DIR_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
4873#endif
4874#endif
4875
4876
4877#ifdef ___DIR_OPEN_PATH_CE_SELECT
4878
4879___SCMOBJlong ___device_directory_setup
4880 ___P((___device_directory **dev,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4881 ___device_group *dgroup,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4882 ___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT) path,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4883 int ignore_hidden),(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4884 (dev,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4885 dgroup,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4886 path,(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4887 ignore_hidden)(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4888___device_directory **dev;(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4889___device_group *dgroup;(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4890___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT) path;(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4891int ignore_hidden;)(___device_directory **dev, ___device_group *dgroup, char* path
, int ignore_hidden)
4892{
4893 ___device_directory *d;
4894
4895 d = ___CAST(___device_directory*,((___device_directory*)(___alloc_mem (sizeof (___device_directory
))))
4896 ___alloc_mem (sizeof (___device_directory)))((___device_directory*)(___alloc_mem (sizeof (___device_directory
))))
;
4897
4898 if (d == NULL((void*)0))
4899 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
4900
4901 d->base.vtbl = &___device_directory_table;
4902 d->base.refcount = 1;
4903 d->base.direction = ___DIRECTION_RD1;
4904 d->base.close_direction = 0; /* prevent closing on errors */
4905 d->base.read_stage = ___STAGE_OPEN0;
4906 d->base.write_stage = ___STAGE_CLOSED3;
4907
4908#ifdef USE_opendir
4909
4910 d->ignore_hidden = ignore_hidden;
4911
4912 d->dir = opendir (path);
4913
4914 if (d->dir == NULL((void*)0))
4915 {
4916 ___SCMOBJlong e = fnf_or_err_code_from_errno ()___err_code_from_errno();
4917 ___free_mem (d);
4918 return e;
4919 }
4920
4921#endif
4922
4923#ifdef USE_FindFirstFile
4924
4925 {
4926 ___CHAR_TYPE(___DIR_OPEN_PATH_CE_SELECT)char dir[___PATH_MAX_LENGTH1024+2+1];
4927 int i = 0;
4928
4929 while (path[i] != '\0' && i < ___PATH_MAX_LENGTH1024)
4930 {
4931 dir[i] = path[i];
4932 i++;
4933 }
4934
4935 if (i == 0 || (dir[i-1] != '\\' && dir[i-1] != '/'))
4936 dir[i++] = '\\';
4937
4938 dir[i++] = '*';
4939 dir[i++] = '\0';
4940
4941 d->ignore_hidden = ignore_hidden;
4942 d->first_file = 1;
4943
4944 d->h = FindFirstFile (dir, &d->fdata);
4945
4946 if (d->h == INVALID_HANDLE_VALUE)
4947 {
4948 ___SCMOBJlong e = fnf_or_err_code_from_GetLastError ()___fnf_or_err_code_from_GetLastError();
4949 ___free_mem (d);
4950 return e;
4951 }
4952 }
4953
4954#endif
4955
4956 device_transfer_close_responsibility (___CAST(___device*,d)((___device*)(d)));
4957
4958 *dev = d;
4959
4960 ___device_add_to_group (dgroup, &d->base);
4961
4962 return ___FIX(___NO_ERR)(((long)(0))<<2);
4963}
4964
4965___SCMOBJlong ___device_directory_read
4966 ___P((___device_directory *dev,(___device_directory *dev, char* *name)
4967 ___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT) *name),(___device_directory *dev, char* *name)
4968 (dev,(___device_directory *dev, char* *name)
4969 name)(___device_directory *dev, char* *name)
4970___device_directory *dev;(___device_directory *dev, char* *name)
4971___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT) *name;)(___device_directory *dev, char* *name)
4972{
4973 ___SCMOBJlong e;
4974
4975 if (dev->base.read_stage != ___STAGE_OPEN0)
4976 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
4977
4978 for (;;)
4979 {
4980 ___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT)char* temp;
4981
4982#ifdef USE_opendir
4983
4984 struct dirent *de = readdir (dev->dir);
4985
4986 if (de == NULL((void*)0))
4987 {
4988#if 0
4989 /* this seems to be broken, at least under Linux */
4990 if (errno(*__errno_location ()) != 0)
4991 return err_code_from_errno ()___err_code_from_errno();
4992#endif
4993 *name = NULL((void*)0);
4994 e = ___FIX(___NO_ERR)(((long)(0))<<2);
4995 break;
4996 }
4997
4998 temp = de->d_name;
4999
5000 switch (dev->ignore_hidden)
5001 {
5002 default:
5003 case 2:
5004 if (temp[0] == '.')
5005 break;
5006
5007 case 1:
5008 if (temp[0] == '.' &&
5009 (temp[1] == '\0' ||
5010 (temp[1] == '.' && (temp[2] == '\0'))))
5011 break;
5012
5013 case 0:
5014 *name = temp;
5015 return ___FIX(___NO_ERR)(((long)(0))<<2);
5016 }
5017
5018#endif
5019
5020#ifdef USE_FindFirstFile
5021
5022 if (dev->first_file)
5023 dev->first_file = 0;
5024 else if (!FindNextFile (dev->h, &dev->fdata))
5025 {
5026 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
5027 *name = NULL((void*)0);
5028 if (e == ___FIX(___WIN32_ERR(ERROR_NO_MORE_FILES))(((long)((((HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))&~(~(
(int)(0))<<25)) | (((HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES
))&~((int)(0))<<27)>>2))))<<2)
)
5029 e = ___FIX(___NO_ERR)(((long)(0))<<2);
5030 break;
5031 }
5032
5033 temp = dev->fdata.cFileName;
5034
5035 if (temp[0] == '\0')
5036 temp = dev->fdata.cAlternateFileName; /* use 8.3 name */
5037
5038 switch (dev->ignore_hidden)
5039 {
5040 default:
5041 case 2:
5042 if (dev->fdata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
5043 break;
5044
5045 case 1:
5046 if (temp[0] == '.' &&
5047 (temp[1] == '\0' ||
5048 (temp[1] == '.' && (temp[2] == '\0'))))
5049 break;
5050
5051 case 0:
5052 *name = temp;
5053 return ___FIX(___NO_ERR)(((long)(0))<<2);
5054 }
5055
5056#endif
5057 }
5058
5059 return e;
5060}
5061
5062#endif
5063
5064
5065/*---------------------------------------------------------------------------*/
5066
5067/* Event-queue device. */
5068
5069typedef struct ___device_event_queue_struct
5070 {
5071 ___device base;
5072
5073 int index;
5074
5075#ifdef USE_WIN32
5076
5077 DWORD event_mask;
5078
5079#endif
5080 } ___device_event_queue;
5081
5082typedef struct ___device_event_queue_vtbl_struct
5083 {
5084 ___device_vtbl base;
5085 } ___device_event_queue_vtbl;
5086
5087___HIDDENstatic int ___device_event_queue_kind
5088 ___P((___device *self),(___device *self)
5089 (self)(___device *self)
5090___device *self;)(___device *self)
5091{
5092 return ___EVENT_QUEUE_KIND(1 +2048);
5093}
5094
5095___HIDDENstatic ___SCMOBJlong ___device_event_queue_close_virt
5096 ___P((___device *self,(___device *self, int direction)
5097 int direction),(___device *self, int direction)
5098 (self,(___device *self, int direction)
5099 direction)(___device *self, int direction)
5100___device *self;(___device *self, int direction)
5101int direction;)(___device *self, int direction)
5102{
5103 ___device_event_queue *d = ___CAST(___device_event_queue*,self)((___device_event_queue*)(self));
5104
5105 if (d->base.read_stage == ___STAGE_CLOSED3)
5106 return ___FIX(___NO_ERR)(((long)(0))<<2);
5107
5108 if (direction & ___DIRECTION_RD1)
5109 {
5110 d->base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */
5111 }
5112
5113 return ___FIX(___NO_ERR)(((long)(0))<<2);
5114}
5115
5116___HIDDENstatic ___SCMOBJlong ___device_event_queue_select_virt
5117 ___P((___device *self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5118 ___BOOL for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5119 int i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5120 int pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5121 ___device_select_state *state),(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5122 (self,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5123 for_writing,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5124 i,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5125 pass,(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5126 state)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5127___device *self;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5128___BOOL for_writing;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5129int i;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5130int pass;(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5131___device_select_state *state;)(___device *self, int for_writing, int i, int pass, ___device_select_state
*state)
5132{
5133 ___device_event_queue *d = ___CAST(___device_event_queue*,self)((___device_event_queue*)(self));
5134 int stage = (for_writing
5135 ? d->base.write_stage
5136 : d->base.read_stage);
5137
5138 if (pass == ___SELECT_PASS_11)
5139 {
5140 if (stage != ___STAGE_OPEN0)
5141 state->timeout = ___time_mod.time_neg_infinity;
5142 else
5143 {
5144#ifdef USE_WIN32
5145
5146 state->message_queue_mask = d->event_mask;
5147 state->message_queue_dev_pos = i;
5148
5149#endif
5150 }
5151
5152 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
5153 }
5154
5155 /* pass == ___SELECT_PASS_CHECK */
5156
5157 if (stage != ___STAGE_OPEN0)
5158 state->devs[i] = NULL((void*)0);
5159 else
5160 {
5161#ifdef USE_WIN32
5162
5163 if (state->devs_next[i] != -1)
5164 state->devs[i] = NULL((void*)0);
5165
5166#endif
5167 }
5168
5169 return ___FIX(___NO_ERR)(((long)(0))<<2);
5170}
5171
5172___HIDDENstatic ___SCMOBJlong ___device_event_queue_release_virt
5173 ___P((___device *self),(___device *self)
5174 (self)(___device *self)
5175___device *self;)(___device *self)
5176{
5177 return ___FIX(___NO_ERR)(((long)(0))<<2);
5178}
5179
5180___HIDDENstatic ___SCMOBJlong ___device_event_queue_force_output_virt
5181 ___P((___device *self,(___device *self, int level)
5182 int level),(___device *self, int level)
5183 (self,(___device *self, int level)
5184 level)(___device *self, int level)
5185___device *self;(___device *self, int level)
5186int level;)(___device *self, int level)
5187{
5188 return ___FIX(___NO_ERR)(((long)(0))<<2);
5189}
5190
5191___HIDDENstatic ___device_event_queue_vtbl ___device_event_queue_table =
5192{
5193 {
5194 ___device_event_queue_kind,
5195 ___device_event_queue_select_virt,
5196 ___device_event_queue_release_virt,
5197 ___device_event_queue_force_output_virt,
5198 ___device_event_queue_close_virt
5199 }
5200};
5201
5202
5203___SCMOBJlong ___device_event_queue_setup
5204 ___P((___device_event_queue **dev,(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5205 ___device_group *dgroup,(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5206 ___SCMOBJ selector),(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5207 (dev,(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5208 dgroup,(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5209 selector)(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5210___device_event_queue **dev;(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5211___device_group *dgroup;(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5212___SCMOBJ selector;)(___device_event_queue **dev, ___device_group *dgroup, long selector
)
5213{
5214 ___device_event_queue *d;
5215
5216 d = ___CAST(___device_event_queue*,((___device_event_queue*)(___alloc_mem (sizeof (___device_event_queue
))))
5217 ___alloc_mem (sizeof (___device_event_queue)))((___device_event_queue*)(___alloc_mem (sizeof (___device_event_queue
))))
;
5218
5219 if (d == NULL((void*)0))
5220 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
5221
5222 d->base.vtbl = &___device_event_queue_table;
5223 d->base.refcount = 1;
5224 d->base.direction = ___DIRECTION_RD1;
5225 d->base.close_direction = 0; /* prevent closing on errors */
5226 d->base.read_stage = ___STAGE_OPEN0;
5227 d->base.write_stage = ___STAGE_CLOSED3;
5228
5229#ifdef USE_WIN32
5230
5231 d->event_mask = ___INT(selector)((selector)>>2);
5232
5233#endif
5234
5235 *dev = d;
5236
5237 ___device_add_to_group (dgroup, &d->base);
5238
5239 return ___FIX(___NO_ERR)(((long)(0))<<2);
5240}
5241
5242
5243___HIDDENstatic ___SCMOBJlong ___release_event
5244 ___P((void *x),(void *x)
5245 (x)(void *x)
5246void *x;)(void *x)
5247{
5248 ___release_rc (x);
5249 return ___FIX(___NO_ERR)(((long)(0))<<2);
5250}
5251
5252
5253___SCMOBJlong ___device_event_queue_read
5254 ___P((___device_event_queue *dev,(___device_event_queue *dev, long *event)
5255 ___SCMOBJ *event),(___device_event_queue *dev, long *event)
5256 (dev,(___device_event_queue *dev, long *event)
5257 event)(___device_event_queue *dev, long *event)
5258___device_event_queue *dev;(___device_event_queue *dev, long *event)
5259___SCMOBJ *event;)(___device_event_queue *dev, long *event)
5260{
5261 if (dev->base.read_stage != ___STAGE_OPEN0)
5262 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
5263
5264#ifdef USE_WIN32
5265
5266 {
5267 MSG *msg = ___CAST(MSG*, ___alloc_rc (sizeof (MSG)))((MSG*)(___alloc_rc (sizeof (MSG))));
5268
5269 if (msg == 0)
5270 return ___FIX(___STOC_HEAP_OVERFLOW_ERR+___RETURN_POS)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+(61<<7))+127))<<2)
;
5271
5272 if (GetQueueStatus (dev->event_mask) != 0 &&
5273 PeekMessage (msg,
5274 NULL((void*)0), /* retrieve messages for window and thread */
5275 0, /* no constraint on the message type */
5276 0,
5277 PM_REMOVE)) /* remove message */
5278 return ___NONNULLPOINTER_to_SCMOBJ
5279 (___CAST(void*,msg)((void*)(msg)),
5280 ___FAL((((long)(-1))<<2)+2),
5281 ___release_event,
5282 event,
5283 ___RETURN_POS127);
5284
5285 ___release_rc (msg);
5286 }
5287
5288#endif
5289
5290 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
5291}
5292
5293
5294/*---------------------------------------------------------------------------*/
5295
5296/* File stream device */
5297
5298typedef struct ___device_file_struct
5299 {
5300 ___device_stream base;
5301
5302#ifndef USE_POSIX
5303#ifndef USE_WIN32
5304
5305 ___FILE *stream;
5306
5307#endif
5308#endif
5309
5310#ifdef USE_POSIX
5311 int fd;
5312#endif
5313
5314#ifdef USE_WIN32
5315 HANDLE h;
5316 int flags;
5317#endif
5318 } ___device_file;
5319
5320typedef struct ___device_file_vtbl_struct
5321 {
5322 ___device_stream_vtbl base;
5323 } ___device_file_vtbl;
5324
5325___HIDDENstatic int ___device_file_kind
5326 ___P((___device *self),(___device *self)
5327 (self)(___device *self)
5328___device *self;)(___device *self)
5329{
5330 return ___FILE_DEVICE_KIND(15 +16);
5331}
5332
5333#if 0
5334
5335___HIDDENstatic void ___device_file_restore_initial_mode
5336 ___P((___device_file *d),(___device_file *d)
5337 (d)(___device_file *d)
5338___device_file *d;)(___device_file *d)
5339{
5340#ifdef USE_POSIX
5341
5342 /* set blocking mode */
5343
5344 set_fd_blocking_mode (d->fd, 1); /* ignore error */
5345
5346#endif
5347}
5348
5349#endif
5350
5351___HIDDENstatic ___SCMOBJlong ___device_file_close_raw_virt
5352 ___P((___device_stream *self,(___device_stream *self, int direction)
5353 int direction),(___device_stream *self, int direction)
5354 (self,(___device_stream *self, int direction)
5355 direction)(___device_stream *self, int direction)
5356___device_stream *self;(___device_stream *self, int direction)
5357int direction;)(___device_stream *self, int direction)
5358{
5359 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5360 int is_not_closed = 0;
5361
5362 if (d->base.base.read_stage != ___STAGE_CLOSED3)
5363 is_not_closed |= ___DIRECTION_RD1;
5364
5365 if (d->base.base.write_stage != ___STAGE_CLOSED3)
5366 is_not_closed |= ___DIRECTION_WR2;
5367
5368 if (is_not_closed == 0)
5369 return ___FIX(___NO_ERR)(((long)(0))<<2);
5370
5371 if ((is_not_closed & ~direction) == 0)
5372 {
5373 /* Close file when both sides are closed. */
5374
5375 d->base.base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */
5376 d->base.base.write_stage = ___STAGE_CLOSED3;
5377
5378 if ((d->base.base.close_direction & d->base.base.direction)
5379 == d->base.base.direction)
5380 {
5381#if 0
5382 ___device_file_restore_initial_mode (d);
5383#endif
5384
5385#ifndef USE_POSIX
5386#ifndef USE_WIN32
5387
5388 if (d->stream != 0)
5389 if (___fclose (d->stream) != 0)
5390 return err_code_from_errno ()___err_code_from_errno();
5391
5392#endif
5393#endif
5394
5395#ifdef USE_POSIX
5396 if (close_no_EINTR (d->fd) < 0)
5397 return err_code_from_errno ()___err_code_from_errno();
5398#endif
5399
5400#ifdef USE_WIN32
5401 if (!CloseHandle (d->h))
5402 return err_code_from_GetLastError ()___err_code_from_GetLastError();
5403#endif
5404 }
5405 }
5406 else if (is_not_closed & direction & ___DIRECTION_RD1)
5407 d->base.base.read_stage = ___STAGE_CLOSED3;
5408 else if (is_not_closed & direction & ___DIRECTION_WR2)
5409 d->base.base.write_stage = ___STAGE_CLOSED3;
5410
5411 return ___FIX(___NO_ERR)(((long)(0))<<2);
5412}
5413
5414___HIDDENstatic ___SCMOBJlong ___device_file_select_raw_virt
5415 ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5416 ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5417 int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5418 int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5419 ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5420 (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5421 for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5422 i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5423 pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5424 state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5425___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5426___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5427int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5428int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5429___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state
*state)
5430{
5431 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5432 int stage = (for_writing
5433 ? d->base.base.write_stage
5434 : d->base.base.read_stage);
5435
5436 if (pass == ___SELECT_PASS_11)
5437 {
5438 if (stage != ___STAGE_OPEN0)
5439 state->timeout = ___time_mod.time_neg_infinity;
5440 else
5441 {
5442#ifndef USE_POSIX
5443#ifndef USE_WIN32
5444
5445 state->timeout = ___time_mod.time_neg_infinity;
5446
5447#endif
5448#endif
5449
5450#ifdef USE_POSIX
5451 ___device_select_add_fd (state, d->fd, for_writing);
5452#endif
5453 }
5454 return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+14)))<<2)
;
5455 }
5456
5457 /* pass == ___SELECT_PASS_CHECK */
5458
5459 if (stage != ___STAGE_OPEN0)
5460 state->devs[i] = NULL((void*)0);
5461 else
5462 {
5463#ifndef USE_POSIX
5464#ifndef USE_WIN32
5465
5466 state->devs[i] = NULL((void*)0);
5467
5468#endif
5469#endif
5470
5471#ifdef USE_POSIX
5472
5473 if (for_writing
5474 ? ___FD_ISSET(d->fd, &state->writefds)((((&state->writefds)->__fds_bits)[((d->fd) / (8
* (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << (
(d->fd) % (8 * (int) sizeof (__fd_mask))))) != 0)
5475 : ___FD_ISSET(d->fd, &state->readfds)((((&state->readfds)->__fds_bits)[((d->fd) / (8 *
(int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((
d->fd) % (8 * (int) sizeof (__fd_mask))))) != 0)
)
5476 state->devs[i] = NULL((void*)0);
5477
5478#endif
5479
5480#ifdef USE_WIN32
5481
5482 if (state->devs_next[i] != -1)
5483 state->devs[i] = NULL((void*)0);
5484
5485#endif
5486 }
5487
5488 return ___FIX(___NO_ERR)(((long)(0))<<2);
5489}
5490
5491___HIDDENstatic ___SCMOBJlong ___device_file_release_raw_virt
5492 ___P((___device_stream *self),(___device_stream *self)
5493 (self)(___device_stream *self)
5494___device_stream *self;)(___device_stream *self)
5495{
5496#if 0
5497
5498 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5499
5500 if (d->base.base.read_stage != ___STAGE_CLOSED3 ||
5501 d->base.base.write_stage != ___STAGE_CLOSED3)
5502 ___device_file_restore_initial_mode (d);
5503
5504#endif
5505
5506 return ___FIX(___NO_ERR)(((long)(0))<<2);
5507}
5508
5509___HIDDENstatic ___SCMOBJlong ___device_file_force_output_raw_virt
5510 ___P((___device_stream *self,(___device_stream *self, int level)
5511 int level),(___device_stream *self, int level)
5512 (self,(___device_stream *self, int level)
5513 level)(___device_stream *self, int level)
5514___device_stream *self;(___device_stream *self, int level)
5515int level;)(___device_stream *self, int level)
5516{
5517 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5518
5519 if (d->base.base.write_stage == ___STAGE_OPEN0)
5520 {
5521#ifndef USE_POSIX
5522#ifndef USE_WIN32
5523
5524 if (level > 0)
5525 {
5526 ___FILE *stream = d->stream;
5527
5528 if (stream == 0)
5529 stream = ___stdoutstdout;
5530
5531 ___fflush (stream); /* ignore error */
5532 }
5533
5534#endif
5535#endif
5536
5537#ifdef USE_POSIX
5538
5539 switch (level)
5540 {
5541 case 2:
5542 case 3:
5543
5544#ifdef USE_fcntl
5545#ifdef F_FULLFSYNC
5546
5547 if (fcntl (d->fd, F_FULLFSYNC, 0) < 0)
5548 return err_code_from_errno ()___err_code_from_errno();
5549 break;
5550
5551#endif
5552#endif
5553
5554 case 1:
5555
5556 if (fsync (d->fd) < 0)
5557 return err_code_from_errno ()___err_code_from_errno();
5558 break;
5559
5560 }
5561
5562#endif
5563 }
5564
5565 return ___FIX(___NO_ERR)(((long)(0))<<2);
5566}
5567
5568___HIDDENstatic ___SCMOBJlong ___device_file_seek_raw_virt
5569 ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence)
5570 ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence)
5571 int whence),(___device_stream *self, ___stream_index *pos, int whence)
5572 (self,(___device_stream *self, ___stream_index *pos, int whence)
5573 pos,(___device_stream *self, ___stream_index *pos, int whence)
5574 whence)(___device_stream *self, ___stream_index *pos, int whence)
5575___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence)
5576___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence)
5577int whence;)(___device_stream *self, ___stream_index *pos, int whence)
5578{
5579 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5580
5581 if (d->base.base.read_stage == ___STAGE_OPEN0 ||
5582 d->base.base.write_stage == ___STAGE_OPEN0)
5583 {
5584#ifndef USE_POSIX
5585#ifndef USE_WIN32
5586
5587 int new_pos;
5588 ___FILE *stream = d->stream;
5589
5590 if (stream == 0)
5591 stream = ___stdoutstdout;
5592
5593 if (fseek (stream, *pos, whence) < 0 ||
5594 (new_pos = ftell (stream)) < 0)
5595 return err_code_from_errno ()___err_code_from_errno();
5596
5597 *pos = new_pos;
5598
5599#endif
5600#endif
5601
5602#ifdef USE_POSIX
5603
5604 int new_pos;
5605
5606 if ((new_pos = lseek (d->fd, *pos, whence)) < 0)
5607 return err_code_from_errno ()___err_code_from_errno();
5608
5609 *pos = new_pos;
5610
5611#endif
5612
5613#ifdef USE_WIN32
5614
5615 LARGE_INTEGER new_pos;
5616
5617 new_pos.QuadPart = *pos;
5618
5619 new_pos.LowPart = SetFilePointer (d->h,
5620 new_pos.LowPart,
5621 &new_pos.HighPart,
5622 whence);
5623
5624 if (new_pos.LowPart == 0xFFFFFFFF
5625 && GetLastError () != NO_ERROR)
5626 return err_code_from_GetLastError ()___err_code_from_GetLastError();
5627
5628 *pos = new_pos.LowPart; /************* incomplete... support large offsets */
5629
5630#endif
5631 }
5632
5633 return ___FIX(___NO_ERR)(((long)(0))<<2);
5634}
5635
5636___HIDDENstatic ___SCMOBJlong ___device_file_read_raw_virt
5637 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5638 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5639 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5640 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5641 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5642 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5643 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5644 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5645___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5646___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5647___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5648___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5649{
5650 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5651
5652 if (d->base.base.read_stage != ___STAGE_OPEN0)
5653 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
5654
5655#ifndef USE_POSIX
5656#ifndef USE_WIN32
5657
5658 {
5659 int n;
5660 ___FILE *stream = d->stream;
5661
5662 if (stream == 0)
5663 stream = ___stdinstdin;
5664
5665 if (stream == ___stdinstdin)
5666 len = 1; /* only read 1 byte at a time to prevent blocking on tty */
5667
5668 if ((n = fread (buf, 1, len, stream)) == 0)
5669 {
5670 if (ferror (stream))
5671 {
5672 clearerr (stream);
5673 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
5674 }
5675 clearerr (stream);
5676 }
5677
5678 *len_done = n;
5679 }
5680
5681#endif
5682#endif
5683
5684#ifdef USE_POSIX
5685
5686 {
5687 int n;
5688
5689 if ((n = read (d->fd, buf, len)) < 0)
5690 return err_code_from_errno ()___err_code_from_errno();
5691
5692 *len_done = n;
5693 }
5694
5695#endif
5696
5697#ifdef USE_WIN32
5698
5699 {
5700 DWORD n;
5701
5702 if (!ReadFile (d->h, buf, len, &n, NULL((void*)0)))
5703 return err_code_from_GetLastError ()___err_code_from_GetLastError();
5704
5705 *len_done = n;
5706 }
5707
5708#endif
5709
5710 return ___FIX(___NO_ERR)(((long)(0))<<2);
5711}
5712
5713___HIDDENstatic ___SCMOBJlong ___device_file_write_raw_virt
5714 ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5715 ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5716 ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5717 ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5718 (self,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5719 buf,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5720 len,(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5721 len_done)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5722___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5723___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5724___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5725___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len
, ___stream_index *len_done)
5726{
5727 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5728
5729 if (d->base.base.write_stage != ___STAGE_OPEN0)
5730 return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+6)))<<2)
;
5731
5732#ifndef USE_POSIX
5733#ifndef USE_WIN32
5734
5735 {
5736 int n;
5737 ___FILE *stream = d->stream;
5738
5739 if (stream == 0)
5740 stream = ___stdoutstdout;
5741
5742 if ((n = fwrite (buf, 1, len, stream)) == 0)
5743 {
5744 if (ferror (stream))
5745 {
5746 clearerr (stream);
5747 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
5748 }
5749 }
5750
5751 *len_done = n;
5752 }
5753
5754#endif
5755#endif
5756
5757#ifdef USE_POSIX
5758
5759 {
5760 int n;
5761
5762 if ((n = write (d->fd, buf, len)) < 0)
5763 return err_code_from_errno ()___err_code_from_errno();
5764
5765 *len_done = n;
5766 }
5767
5768#endif
5769
5770#ifdef USE_WIN32
5771
5772 {
5773 DWORD n;
5774
5775 if (d->flags & (1 << 3))
5776 {
5777 ___stream_index pos = 0; /* end of file */
5778 ___SCMOBJlong e = ___device_file_seek_raw_virt (self, &pos, FILE_END);
5779 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
5780 return e;
5781 }
5782
5783 if (!WriteFile (d->h, buf, len, &n, NULL((void*)0)))
5784 return err_code_from_GetLastError ()___err_code_from_GetLastError();
5785
5786 *len_done = n;
5787 }
5788
5789#endif
5790
5791 return ___FIX(___NO_ERR)(((long)(0))<<2);
5792}
5793
5794
5795___HIDDENstatic ___SCMOBJlong ___device_file_width_virt
5796 ___P((___device_stream *self),(___device_stream *self)
5797 (self)(___device_stream *self)
5798___device_stream *self;)(___device_stream *self)
5799{
5800 return ___FIX(80)(((long)(80))<<2);
5801}
5802
5803
5804___HIDDENstatic ___SCMOBJlong ___device_file_default_options_virt
5805 ___P((___device_stream *self),(___device_stream *self)
5806 (self)(___device_stream *self)
5807___device_stream *self;)(___device_stream *self)
5808{
5809 int settings = ___setup_params.file_settings;
5810 int char_encoding_errors = ___CHAR_ENCODING_ERRORS(settings)((settings)&(3<<5));
5811 int char_encoding = ___CHAR_ENCODING(settings)((settings)&(31<<0));
5812 int eol_encoding = ___EOL_ENCODING(settings)((settings)&(3<<7));
5813 int buffering = ___BUFFERING(settings)((settings)&(3<<9));
5814
5815 if (char_encoding_errors == 0)
5816 char_encoding_errors = ___CHAR_ENCODING_ERRORS_ON(1<<5);
5817
5818 if (char_encoding == 0)
5819 char_encoding = ___CHAR_ENCODING_ISO_8859_1(2<<0);
5820
5821 if (eol_encoding == 0)
5822 eol_encoding = ___EOL_ENCODING_LF(1<<7);
5823
5824#ifdef USE_WIN32
5825
5826 if (buffering == 0)
5827 {
5828 ___device_file *d = ___CAST(___device_file*,self)((___device_file*)(self));
5829
5830 if (GetFileType (d->h) == FILE_TYPE_PIPE)
5831 buffering = ___NO_BUFFERING(1<<9);
5832 else
5833 buffering = ___FULL_BUFFERING(3<<9);
5834 }
5835
5836#else
5837
5838 if (buffering == 0)
5839 buffering = ___FULL_BUFFERING(3<<9);
5840
5841#endif
5842
5843#ifdef ___DEBUG
5844
5845 ___printf ("file char_encoding_errors=%d char_encoding=%d eol_encoding=%d buffering=%d\n",
5846 char_encoding_errors,
5847 char_encoding,
5848 eol_encoding,
5849 buffering);
5850
5851#endif
5852
5853 return ___FIX(___STREAM_OPTIONS(char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5854 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5855 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5856 buffering,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5857 char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5858 char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5859 eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
5860 buffering))(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering
)+((char_encoding_errors+char_encoding+eol_encoding+buffering
)<<15)))<<2)
;
5861}
5862
5863
5864___HIDDENstatic ___SCMOBJlong ___device_file_options_set_virt
5865 ___P((___device_stream *self,(___device_stream *self, long options)
5866 ___SCMOBJ options),(___device_stream *self, long options)
5867 (self,(___device_stream *self, long options)
5868 options)(___device_stream *self, long options)
5869___device_stream *self;(___device_stream *self, long options)
5870___SCMOBJ options;)(___device_stream *self, long options)
5871{
5872 return ___FIX(___NO_ERR)(((long)(0))<<2);
5873}
5874
5875
5876___HIDDENstatic ___device_file_vtbl ___device_file_table =
5877{
5878 {
5879 {
5880 ___device_file_kind,
5881 ___device_stream_select_virt,
5882 ___device_stream_release_virt,
5883 ___device_stream_force_output_virt,
5884 ___device_stream_close_virt
5885 },
5886 ___device_file_select_raw_virt,
5887 ___device_file_release_raw_virt,
5888 ___device_file_force_output_raw_virt,
5889 ___device_file_close_raw_virt,
5890 ___device_file_seek_raw_virt,
5891 ___device_file_read_raw_virt,
5892 ___device_file_write_raw_virt,
5893 ___device_file_width_virt,
5894 ___device_file_default_options_virt,
5895 ___device_file_options_set_virt
5896 }
5897};
5898
5899
5900#ifndef USE_POSIX
5901#ifndef USE_WIN32
5902
5903___HIDDENstatic ___SCMOBJlong ___device_file_setup_from_stream
5904 ___P((___device_file **dev,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5905 ___device_group *dgroup,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5906 ___FILE *stream,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5907 int direction),(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5908 (dev,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5909 dgroup,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5910 stream,(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5911 direction)(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5912___device_file **dev;(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5913___device_group *dgroup;(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5914___FILE *stream;(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5915int direction;)(___device_file **dev, ___device_group *dgroup, ___FILE *stream
, int direction)
5916{
5917 ___device_file *d;
5918
5919 d = ___CAST(___device_file*,((___device_file*)(___alloc_mem (sizeof (___device_file))))
5920 ___alloc_mem (sizeof (___device_file)))((___device_file*)(___alloc_mem (sizeof (___device_file))));
5921
5922 if (d == NULL((void*)0))
5923 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
5924
5925 d->base.base.vtbl = &___device_file_table;
5926 d->stream = stream;
5927
5928 *dev = d;
5929
5930 return ___device_stream_setup
5931 (&d->base,
5932 dgroup,
5933 direction,
5934 0);
5935}
5936
5937#endif
5938#endif
5939
5940
5941#ifdef USE_POSIX
5942
5943___HIDDENstatic ___SCMOBJlong ___device_file_setup_from_fd
5944 ___P((___device_file **dev,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5945 ___device_group *dgroup,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5946 int fd,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5947 int direction),(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5948 (dev,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5949 dgroup,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5950 fd,(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5951 direction)(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5952___device_file **dev;(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5953___device_group *dgroup;(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5954int fd;(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5955int direction;)(___device_file **dev, ___device_group *dgroup, int fd, int direction
)
5956{
5957 ___device_file *d;
5958
5959 d = ___CAST(___device_file*,((___device_file*)(___alloc_mem (sizeof (___device_file))))
5960 ___alloc_mem (sizeof (___device_file)))((___device_file*)(___alloc_mem (sizeof (___device_file))));
5961
5962 if (d == NULL((void*)0))
5963 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
5964
5965 d->base.base.vtbl = &___device_file_table;
5966 d->fd = fd;
5967
5968 *dev = d;
5969
5970 return ___device_stream_setup
5971 (&d->base,
5972 dgroup,
5973 direction,
5974 0);
5975}
5976
5977#endif
5978
5979
5980#ifdef USE_WIN32
5981
5982___HIDDENstatic ___SCMOBJlong ___device_file_setup_from_handle
5983 ___P((___device_file **dev,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5984 ___device_group *dgroup,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5985 HANDLE h,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5986 int flags,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5987 int direction,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5988 int pumps_on),(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5989 (dev,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5990 dgroup,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5991 h,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5992 flags,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5993 direction,(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5994 pumps_on)(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5995___device_file **dev;(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5996___device_group *dgroup;(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5997HANDLE h;(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5998int flags;(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
5999int direction;(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
6000int pumps_on;)(___device_file **dev, ___device_group *dgroup, HANDLE h, int
flags, int direction, int pumps_on)
6001{
6002 ___device_file *d;
6003
6004 d = ___CAST(___device_file*,((___device_file*)(___alloc_mem (sizeof (___device_file))))
6005 ___alloc_mem (sizeof (___device_file)))((___device_file*)(___alloc_mem (sizeof (___device_file))));
6006
6007 if (d == NULL((void*)0))
6008 return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
6009
6010 d->base.base.vtbl = &___device_file_table;
6011 d->h = h;
6012 d->flags = flags;
6013
6014 *dev = d;
6015
6016 return ___device_stream_setup
6017 (&d->base,
6018 dgroup,
6019 direction,
6020 pumps_on);
6021}
6022
6023#endif
6024
6025
6026/*---------------------------------------------------------------------------*/
6027
6028#ifndef USE_POSIX
6029#ifndef USE_WIN32
6030
6031___SCMOBJlong ___device_stream_setup_from_stream
6032 ___P((___device_stream **dev,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6033 ___device_group *dgroup,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6034 ___FILE *stream,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6035 int kind,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6036 int direction),(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6037 (dev,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6038 dgroup,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6039 ___FILE *stream,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6040 kind,(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6041 direction)(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6042___device_stream **dev;(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6043___device_group *dgroup;(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6044___FILE *stream;(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6045int kind;(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6046int direction;)(___device_stream **dev, ___device_group *dgroup, ___FILE *stream
, int kind, int direction)
6047{
6048 ___SCMOBJlong e;
6049 ___device_file *d;
6050
6051 if ((e = ___device_file_setup_from_stream
6052 (&d,
6053 dgroup,
6054 stream,
6055 direction))
6056 == ___FIX(___NO_ERR)(((long)(0))<<2))
6057 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6058
6059 return e;
6060}
6061
6062
6063___HIDDENstatic void device_translate_flags
6064 ___P((int flags,(int flags, char **mode, int *direction)
6065 char **mode,(int flags, char **mode, int *direction)
6066 int *direction),(int flags, char **mode, int *direction)
6067 (flags,(int flags, char **mode, int *direction)
6068 mode,(int flags, char **mode, int *direction)
6069 direction)(int flags, char **mode, int *direction)
6070int flags;(int flags, char **mode, int *direction)
6071char **mode;(int flags, char **mode, int *direction)
6072int *direction;)(int flags, char **mode, int *direction)
6073{
6074 switch ((flags >> 4) & 3)
6075 {
6076 default:
6077 case 1:
6078 *mode = "rb";
6079 *direction = ___DIRECTION_RD1;
6080 break;
6081 case 2:
6082 *mode = "wb";
6083 *direction = ___DIRECTION_WR2;
6084 break;
6085 case 3:
6086 *mode = "w+b";
6087 *direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6088 break;
6089 }
6090}
6091
6092#endif
6093#endif
6094
6095
6096#ifdef USE_POSIX
6097
6098___HIDDENstatic int ___device_stream_kind_from_fd
6099 ___P((int fd),(int fd)
6100 (fd)(int fd)
6101int fd;)(int fd)
6102{
6103 /*
6104 * Determine what kind of device is attached to the file descriptor
6105 * (tty, socket, or regular file).
6106 */
6107
6108 if (isatty (fd))
6109 return ___TTY_DEVICE_KIND(15 +64);
6110
6111#ifdef USE_stat
6112
6113 {
6114 ___struct_statstruct stat s;
6115
6116 if (___fstatfstat (fd, &s) < 0)
6117 return ___NONE_KIND0;
6118
6119 if (S_ISREG(s.st_mode)((((s.st_mode)) & 0170000) == (0100000)))
6120 return ___FILE_DEVICE_KIND(15 +16);
6121
6122#if 0
6123
6124 if (S_ISDIR(s.st_mode)((((s.st_mode)) & 0170000) == (0040000)))
6125 return ???;
6126
6127 if (S_ISLNK(s.st_mode)((((s.st_mode)) & 0170000) == (0120000)))
6128 return ???;
6129
6130#endif
6131
6132 if (S_ISCHR(s.st_mode)((((s.st_mode)) & 0170000) == (0020000)))
6133 return ___FILE_DEVICE_KIND(15 +16);
6134
6135 if (S_ISBLK(s.st_mode)((((s.st_mode)) & 0170000) == (0060000)))
6136 return ___FILE_DEVICE_KIND(15 +16);
6137
6138 if (S_ISFIFO(s.st_mode)((((s.st_mode)) & 0170000) == (0010000)))
6139 return ___FILE_DEVICE_KIND(15 +16);
6140
6141#ifdef USE_NETWORKING
6142 if (S_ISSOCK(s.st_mode)((((s.st_mode)) & 0170000) == (0140000)))
6143 return ___TCP_CLIENT_DEVICE_KIND(15 +256);
6144#endif
6145 }
6146
6147 return ___NONE_KIND0;
6148
6149#else
6150
6151 return ___FILE_DEVICE_KIND(15 +16);
6152
6153#endif
6154}
6155
6156
6157___HIDDENstatic int ___device_stream_direction_from_fd
6158 ___P((int fd),(int fd)
6159 (fd)(int fd)
6160int fd;)(int fd)
6161{
6162 int direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6163 char buf[1];
6164
6165 /*
6166 * A "read" and "write" of 0 bytes is attempted to tell which
6167 * directions the file descriptor supports.
6168 */
6169
6170 if (read (fd, buf, 0) < 0)
6171 direction &= ~___DIRECTION_RD1;
6172
6173 if (write (fd, buf, 0) < 0)
6174 direction &= ~___DIRECTION_WR2;
6175
6176 /*
6177 * It is likely that on some systems a zero length "read" and
6178 * "write" will return an error, regardless of the possible
6179 * operations. In this case assume that both operations are
6180 * possible.
6181 */
6182
6183 if (direction == 0)
6184 direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6185
6186 return direction;
6187}
6188
6189
6190___SCMOBJlong ___device_stream_setup_from_fd
6191 ___P((___device_stream **dev,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6192 ___device_group *dgroup,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6193 int fd,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6194 int kind,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6195 int direction),(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6196 (dev,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6197 dgroup,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6198 fd,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6199 kind,(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6200 direction)(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6201___device_stream **dev;(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6202___device_group *dgroup;(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6203int fd;(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6204int kind;(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6205int direction;)(___device_stream **dev, ___device_group *dgroup, int fd, int
kind, int direction)
6206{
6207 ___SCMOBJlong e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
6208
6209 if (kind == ___NONE_KIND0)
6210 kind = ___device_stream_kind_from_fd (fd);
6211
6212 if (direction == 0)
6213 direction = ___device_stream_direction_from_fd (fd);
6214
6215#ifdef ___DEBUG
6216 ___printf ("fd=%d kind=%d direction=%d\n", fd, kind, direction);
6217#endif
6218
6219 if (kind == ___TTY_DEVICE_KIND(15 +64))
6220 {
6221 /*
6222 * No need to setup the file descriptor to perform nonblocking
6223 * I/O because that is done by os_tty.c in a way that restores
6224 * the blocking mode to its original mode when the process
6225 * exits. Restoring the original mode avoids some issues when
6226 * running under a shell in emacs (which gives a "Process
6227 * shell finished" error when the program terminates).
6228 */
6229
6230 ___device_tty *d;
6231
6232 if ((e = ___device_tty_setup_from_fd
6233 (&d,
6234 dgroup,
6235 fd,
6236 direction))
6237 == ___FIX(___NO_ERR)(((long)(0))<<2))
6238 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6239 }
6240 else
6241 {
6242 switch (kind)
6243 {
6244
6245#ifdef USE_NETWORKING
6246
6247 case ___TCP_CLIENT_DEVICE_KIND(15 +256):
6248 {
6249 ___device_tcp_client *d;
6250 struct sockaddr server_addr;
6251
6252 if ((e = ___device_tcp_client_setup_from_socket
6253 (&d,
6254 dgroup,
6255 fd,
6256 &server_addr,
6257 0,
6258 0,
6259 direction))
6260 == ___FIX(___NO_ERR)(((long)(0))<<2))
6261 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6262
6263 break;
6264 }
6265
6266#endif
6267
6268 case ___FILE_DEVICE_KIND(15 +16):
6269 {
6270 ___device_file *d;
6271
6272#ifdef USE_NONBLOCKING_FILE_IO
6273
6274 /*
6275 * Setup file descriptor to perform nonblocking I/O.
6276 */
6277
6278 if (set_fd_blocking_mode (fd, 0) != 0) /* set nonblocking mode */
6279 return err_code_from_errno ()___err_code_from_errno();
6280
6281#endif
6282
6283 if ((e = ___device_file_setup_from_fd
6284 (&d,
6285 dgroup,
6286 fd,
6287 direction))
6288 == ___FIX(___NO_ERR)(((long)(0))<<2))
6289 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6290
6291 break;
6292 }
6293
6294 default:
6295 {
6296 e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
6297 break;
6298 }
6299 }
6300 }
6301
6302 return e;
6303}
6304
6305
6306___HIDDENstatic void device_translate_flags
6307 ___P((int flags,(int flags, int *fl, int *direction)
6308 int *fl,(int flags, int *fl, int *direction)
6309 int *direction),(int flags, int *fl, int *direction)
6310 (flags,(int flags, int *fl, int *direction)
6311 fl,(int flags, int *fl, int *direction)
6312 direction)(int flags, int *fl, int *direction)
6313int flags;(int flags, int *fl, int *direction)
6314int *fl;(int flags, int *fl, int *direction)
6315int *direction;)(int flags, int *fl, int *direction)
6316{
6317 int f;
6318
6319 switch ((flags >> 4) & 3)
6320 {
6321 default:
6322 case 1:
6323 f = O_RDONLY00;
6324 *direction = ___DIRECTION_RD1;
6325 break;
6326 case 2:
6327 f = O_WRONLY01;
6328 *direction = ___DIRECTION_WR2;
6329 break;
6330 case 3:
6331 f = O_RDWR02;
6332 *direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6333 break;
6334 }
6335
6336 if (flags & (1 << 3))
6337 f |= O_APPEND02000;
6338
6339 switch ((flags >> 1) & 3)
6340 {
6341 default:
6342 case 0: break;
6343 case 1: f |= O_CREAT0100; break;
6344 case 2: f |= O_CREAT0100|O_EXCL0200; break;
6345 }
6346
6347 if (flags & 1)
6348 f |= O_TRUNC01000;
6349
6350 /*
6351 * The O_NONBLOCK flag is not needed here because the file
6352 * descriptor will be set to nonblocking mode later on. But we do
6353 * it anyway so there is no moment in time when it is in blocking
6354 * mode.
6355 */
6356
6357 f |= O_NONBLOCK04000;
6358
6359 *fl = f;
6360}
6361
6362#endif
6363
6364
6365#ifdef USE_WIN32
6366
6367___HIDDENstatic int ___device_stream_kind_from_handle
6368 ___P((HANDLE h),(HANDLE h)
6369 (h)(HANDLE h)
6370HANDLE h;)(HANDLE h)
6371{
6372 DWORD n;
6373 CONSOLE_CURSOR_INFO cinfo;
6374 DCB dcb;
6375 BY_HANDLE_FILE_INFORMATION finfo;
6376
6377#ifdef ___DEBUG
6378 ___printf ("GetFileType -> %d\n", ___CAST(int,GetFileType (h))((int)(GetFileType (h))));
6379#endif
6380
6381 if (GetNumberOfConsoleInputEvents (h, &n))
6382 return ___TTY_DEVICE_KIND(15 +64);
6383
6384 if (GetConsoleCursorInfo (h, &cinfo))
6385 return ___TTY_DEVICE_KIND(15 +64);
6386
6387 if (GetCommState (h, &dcb))
6388 return ___SERIAL_DEVICE_KIND(15 +128);
6389
6390 if (GetFileType (h) == FILE_TYPE_PIPE)
6391 return ___PIPE_DEVICE_KIND(15 +32);
6392
6393 if (GetFileType (h) == FILE_TYPE_CHAR)
6394 return ___FILE_DEVICE_KIND(15 +16);
6395
6396 if (GetFileInformationByHandle (h, &finfo))
6397 return ___FILE_DEVICE_KIND(15 +16);
6398
6399 return ___NONE_KIND0;
6400}
6401
6402
6403___HIDDENstatic int ___device_stream_direction_from_handle
6404 ___P((HANDLE h),(HANDLE h)
6405 (h)(HANDLE h)
6406HANDLE h;)(HANDLE h)
6407{
6408 DWORD n;
6409 int direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6410
6411 /*
6412 * A "ReadFile" and "WriteFile" of 0 bytes is attempted to tell which
6413 * directions the file handle supports.
6414 */
6415
6416 if (!ReadFile (h, NULL((void*)0), 0, &n, NULL((void*)0)))
6417 direction &= ~___DIRECTION_RD1;
6418
6419 if (!WriteFile (h, NULL((void*)0), 0, &n, NULL((void*)0)))
6420 direction &= ~___DIRECTION_WR2;
6421
6422 /*
6423 * It is likely that on some systems a zero length "ReadFile" and
6424 * "WriteFile" will return an error, regardless of the possible
6425 * operations. In this case assume that both operations are
6426 * possible.
6427 */
6428
6429 if (direction == 0)
6430 direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6431
6432 return direction;
6433}
6434
6435
6436___SCMOBJlong ___device_stream_setup_from_handle
6437 ___P((___device_stream **dev,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6438 ___device_group *dgroup,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6439 HANDLE h,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6440 int flags,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6441 int kind,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6442 int direction),(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6443 (dev,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6444 dgroup,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6445 h,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6446 flags,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6447 kind,(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6448 direction)(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6449___device_stream **dev;(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6450___device_group *dgroup;(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6451HANDLE h;(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6452int flags;(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6453int kind;(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6454int direction;)(___device_stream **dev, ___device_group *dgroup, HANDLE h, int
flags, int kind, int direction)
6455{
6456 ___SCMOBJlong e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
6457
6458 if (kind == ___NONE_KIND0)
6459 kind = ___device_stream_kind_from_handle (h);
6460
6461 if (direction == 0)
6462 direction = ___device_stream_direction_from_handle (h);
6463
6464#ifdef ___DEBUG
6465 ___printf ("kind=%d direction=%d\n", kind, direction);
6466#endif
6467
6468 switch (kind)
6469 {
6470 case ___TTY_DEVICE_KIND(15 +64):
6471 {
6472 ___device_tty *d;
6473 if ((e = ___device_tty_setup_from_console
6474 (&d,
6475 dgroup,
6476 direction))
6477 == ___FIX(___NO_ERR)(((long)(0))<<2))
6478 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6479 break;
6480 }
6481
6482 case ___SERIAL_DEVICE_KIND(15 +128):
6483 {
6484 ___device_serial *d;
6485 if ((e = ___device_serial_setup_from_handle
6486 (&d,
6487 dgroup,
6488 h,
6489 direction))
6490 == ___FIX(___NO_ERR)(((long)(0))<<2))
6491 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6492 break;
6493 }
6494
6495 case ___FILE_DEVICE_KIND(15 +16):
6496 {
6497 ___device_file *d;
6498 if ((e = ___device_file_setup_from_handle
6499 (&d,
6500 dgroup,
6501 h,
6502 flags,
6503 direction,
6504 0))
6505 == ___FIX(___NO_ERR)(((long)(0))<<2))
6506 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6507 break;
6508 }
6509
6510 case ___PIPE_DEVICE_KIND(15 +32):
6511 {
6512 ___device_pipe *d;
6513 if ((e = ___device_pipe_setup_from_handle
6514 (&d,
6515 dgroup,
6516 h,
6517 h,
6518 direction,
6519 0))
6520 == ___FIX(___NO_ERR)(((long)(0))<<2))
6521 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
6522 break;
6523 }
6524
6525 default:
6526 {
6527 e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
6528 break;
6529 }
6530 }
6531
6532 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
6533 device_transfer_close_responsibility (___CAST(___device*,*dev)((___device*)(*dev)));
6534
6535 return e;
6536}
6537
6538
6539___HIDDENstatic void device_translate_flags
6540 ___P((int flags,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6541 DWORD *access_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6542 DWORD *share_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6543 DWORD *creation_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6544 DWORD *attributes,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6545 int *direction),(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6546 (flags,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6547 access_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6548 share_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6549 creation_mode,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6550 attributes,(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6551 direction)(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6552int flags;(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6553DWORD *access_mode;(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6554DWORD *share_mode;(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6555DWORD *creation_mode;(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6556DWORD *attributes;(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6557int *direction;)(int flags, DWORD *access_mode, DWORD *share_mode, DWORD *creation_mode
, DWORD *attributes, int *direction)
6558{
6559 DWORD am;
6560 DWORD cm;
6561
6562 switch ((flags >> 4) & 3)
6563 {
6564 default:
6565 case 1:
6566 am = GENERIC_READ;
6567 *direction = ___DIRECTION_RD1;
6568 break;
6569 case 2:
6570 am = GENERIC_WRITE;
6571 *direction = ___DIRECTION_WR2;
6572 break;
6573 case 3:
6574 am = GENERIC_READ|GENERIC_WRITE;
6575 *direction = ___DIRECTION_RD1|___DIRECTION_WR2;
6576 break;
6577 }
6578
6579 switch ((flags >> 1) & 3)
6580 {
6581 default:
6582 case 0:
6583 if (flags & 1)
6584 cm = TRUNCATE_EXISTING;
6585 else
6586 cm = OPEN_EXISTING;
6587 break;
6588
6589 case 1:
6590 if (flags & 1)
6591 cm = CREATE_ALWAYS;
6592 else
6593 cm = OPEN_ALWAYS;
6594 break;
6595
6596 case 2:
6597 cm = CREATE_NEW;
6598 break;
6599 }
6600
6601 *access_mode = am;
6602 *share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
6603 *creation_mode = cm;
6604 *attributes = FILE_ATTRIBUTE_NORMAL;
6605}
6606
6607#endif
6608
6609
6610/*---------------------------------------------------------------------------*/
6611
6612#ifdef USE_execvp
6613#define ___STREAM_OPEN_PROCESS_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
6614#ifndef USE_openpty
6615#ifndef USE_ptsname
6616#undef ___STREAM_OPEN_PROCESS_CE_SELECT
6617#endif
6618#endif
6619#endif
6620
6621#ifdef USE_CreateProcess
6622#ifdef _UNICODE
6623#define ___STREAM_OPEN_PROCESS_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native ucs2
6624#define CP_ENV_FLAGS CREATE_UNICODE_ENVIRONMENT
6625#else
6626#define ___STREAM_OPEN_PROCESS_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
6627#define CP_ENV_FLAGS 0
6628#endif
6629#endif
6630
6631
6632#ifdef ___STREAM_OPEN_PROCESS_CE_SELECT
6633
6634#ifdef USE_execvp
6635
6636/**********************************/
6637#define USE_pipe
6638
6639typedef struct half_duplex_pipe
6640 {
6641 int reading_fd;
6642 int writing_fd;
6643 } half_duplex_pipe;
6644
6645typedef struct full_duplex_pipe
6646 {
6647 half_duplex_pipe input;
6648 half_duplex_pipe output;
6649 } full_duplex_pipe;
6650
6651
6652___HIDDENstatic int open_half_duplex_pipe
6653 ___P((half_duplex_pipe *hdp),(half_duplex_pipe *hdp)
6654 (hdp)(half_duplex_pipe *hdp)
6655half_duplex_pipe *hdp;)(half_duplex_pipe *hdp)
6656{
6657 int fds[2];
6658
6659#ifdef USE_pipe
6660 if (pipe (fds) < 0)
6661 return -1;
6662#endif
6663
6664#ifdef USE_socketpair
6665 if (socketpair (AF_UNIX1, SOCK_STREAMSOCK_STREAM, 0, fds) < 0)
6666 return -1;
6667#endif
6668
6669 hdp->reading_fd = fds[0];
6670 hdp->writing_fd = fds[1];
6671
6672 return 0;
6673}
6674
6675___HIDDENstatic void close_half_duplex_pipe
6676 ___P((half_duplex_pipe *hdp,(half_duplex_pipe *hdp, int end)
6677 int end),(half_duplex_pipe *hdp, int end)
6678 (hdp,(half_duplex_pipe *hdp, int end)
6679 end)(half_duplex_pipe *hdp, int end)
6680half_duplex_pipe *hdp;(half_duplex_pipe *hdp, int end)
6681int end;)(half_duplex_pipe *hdp, int end)
6682{
6683 if (end != 1 && hdp->reading_fd >= 0)
6684 {
6685 close_no_EINTR (hdp->reading_fd); /* ignore error */
6686 hdp->reading_fd = -1;
6687 }
6688
6689 if (end != 0 && hdp->writing_fd >= 0)
6690 {
6691 close_no_EINTR (hdp->writing_fd); /* ignore error */
6692 hdp->writing_fd = -1;
6693 }
6694}
6695
6696___HIDDENstatic int open_pseudo_terminal_master
6697 ___P((int *master_fd_ptr,(int *master_fd_ptr, int *slave_fd_ptr)
6698 int *slave_fd_ptr),(int *master_fd_ptr, int *slave_fd_ptr)
6699 (master_fd_ptr,(int *master_fd_ptr, int *slave_fd_ptr)
6700 slave_fd_ptr)(int *master_fd_ptr, int *slave_fd_ptr)
6701int *master_fd_ptr;(int *master_fd_ptr, int *slave_fd_ptr)
6702int *slave_fd_ptr;)(int *master_fd_ptr, int *slave_fd_ptr)
6703{
6704#ifdef USE_openpty
6705
6706 return openpty (master_fd_ptr, slave_fd_ptr, NULL((void*)0), NULL((void*)0), NULL((void*)0));
6707
6708#else
6709#ifdef USE_getpt
6710
6711 *slave_fd_ptr = -1;
6712 return *master_fd_ptr = getpt ();
6713
6714#else
6715
6716 *slave_fd_ptr = -1;
6717 return *master_fd_ptr = open ("/dev/ptmx", O_RDWR02 | O_NOCTTY0400);
6718
6719#endif
6720#endif
6721}
6722
6723
6724#if 0
6725#ifndef USE_openpty
6726/***************************/
6727#define __USE_XOPEN
6728#define __USE_GNU
6729#include <stdlib.h>
6730#include <stropts.h>
6731extern char *ptsname (int __fd);
6732#endif
6733#endif
6734
6735___HIDDENstatic int setup_terminal_slave
6736 ___P((int slave_fd),(int slave_fd)
6737 (slave_fd)(int slave_fd)
6738int slave_fd;)(int slave_fd)
6739{
6740 struct termios tios;
6741
6742 if (tcgetattr (slave_fd, &tios) >= 0)
6743 {
6744 tios.c_lflag &= ~(ECHO0000010 | ECHOCTL0001000 | ICANON0000002 | IEXTEN0100000 | ISIG0000001);
6745 tios.c_iflag &= ~(BRKINT0000002 | INLCR0000100 | ICRNL0000400 | INPCK0000020 | ISTRIP0000040 | IXON0002000 | IXOFF0010000);
6746 tios.c_cflag &= ~(CSIZE0000060 | PARENB0000400 | CLOCAL0004000);
6747 tios.c_cflag |= (CS80000060 | HUPCL0002000);
6748#ifndef OCRNL0000010
6749#define OCRNL0000010 0
6750#endif
6751 tios.c_oflag &= ~(OPOST0000001 | ONLCR0000004 | OCRNL0000010);
6752
6753 if (tcsetattr (slave_fd, TCSANOW0, &tios) >= 0)
6754 return 0;
6755 }
6756
6757 return -1;
6758}
6759
6760
6761___HIDDENstatic int open_pseudo_terminal_slave
6762 ___P((int master_fd,(int master_fd, int *slave_fd)
6763 int *slave_fd),(int master_fd, int *slave_fd)
6764 (master_fd,(int master_fd, int *slave_fd)
6765 slave_fd)(int master_fd, int *slave_fd)
6766int master_fd;(int master_fd, int *slave_fd)
6767int *slave_fd;)(int master_fd, int *slave_fd)
6768{
6769#ifndef USE_openpty
6770#ifndef USE_ptsname
6771
6772 errno(*__errno_location ()) = xxx;/********************/
6773 return -1;
6774
6775#endif
6776#endif
6777
6778#ifdef USE_openpty
6779
6780 return 0;
6781
6782#endif
6783
6784#ifdef USE_ptsname
6785
6786 int fd;
6787 char *name;
6788
6789 if (grantpt (master_fd) >= 0 &&
6790 unlockpt (master_fd) >= 0 &&
6791 (name = ptsname (master_fd)) != NULL((void*)0) &&
6792 (fd = open (name, O_RDWR02)) >= 0)
6793 {
6794 int tmp;
6795
6796 if (
6797#ifndef HAVE_isastream
6798 1
6799#else
6800 !isastream (fd)
6801#ifdef I_PUSH
6802 || (ioctl (fd, I_PUSH, "ptem") >= 0 &&
6803 ioctl (fd, I_PUSH, "ldterm") >= 0)
6804#endif
6805#endif
6806 )
6807 {
6808 *slave_fd = fd;
6809 return 0;
6810 }
6811
6812 tmp = errno(*__errno_location ());
6813 close_no_EINTR (fd); /* ignore error */
6814 errno(*__errno_location ()) = tmp;
6815 }
6816
6817 return -1;
6818
6819#endif
6820}
6821
6822
6823___HIDDENstatic int open_full_duplex_pipe1
6824 ___P((full_duplex_pipe *fdp,(full_duplex_pipe *fdp, int use_pty)
6825 ___BOOL use_pty),(full_duplex_pipe *fdp, int use_pty)
6826 (fdp,(full_duplex_pipe *fdp, int use_pty)
6827 use_pty)(full_duplex_pipe *fdp, int use_pty)
6828full_duplex_pipe *fdp;(full_duplex_pipe *fdp, int use_pty)
6829___BOOL use_pty;)(full_duplex_pipe *fdp, int use_pty)
6830{
6831 fdp->input.reading_fd = -1;
6832 fdp->input.writing_fd = -1;
6833 fdp->output.reading_fd = -1;
6834 fdp->output.writing_fd = -1;
6835
6836 if (use_pty)
6837 {
6838 int master_fd;
6839 int slave_fd;
6840 if (open_pseudo_terminal_master (&master_fd, &slave_fd) >= 0)
6841 {
6842 int master_fd_dup;
6843 int tmp;
6844 if ((master_fd_dup = dup_no_EINTR (master_fd)) >= 0)
6845 {
6846 fdp->input.writing_fd = master_fd;
6847 fdp->output.reading_fd = master_fd_dup;
6848 fdp->input.reading_fd = slave_fd;
6849 return 0;
6850 }
6851 tmp = errno(*__errno_location ());
6852 close_no_EINTR (master_fd); /* ignore error */
6853 if (slave_fd >= 0)
6854 close_no_EINTR (slave_fd); /* ignore error */
6855 errno(*__errno_location ()) = tmp;
6856 }
6857 }
6858 else
6859 {
6860 if (open_half_duplex_pipe (&fdp->input) >= 0)
6861 {
6862 if (open_half_duplex_pipe (&fdp->output) >= 0)
6863 return 0;
6864 close_half_duplex_pipe (&fdp->input, 2);
6865 }
6866 }
6867
6868 return -1;
6869}
6870
6871
6872___HIDDENstatic int open_full_duplex_pipe2
6873 ___P((full_duplex_pipe *fdp,(full_duplex_pipe *fdp, int use_pty)
6874 ___BOOL use_pty),(full_duplex_pipe *fdp, int use_pty)
6875 (fdp,(full_duplex_pipe *fdp, int use_pty)
6876 use_pty)(full_duplex_pipe *fdp, int use_pty)
6877full_duplex_pipe *fdp;(full_duplex_pipe *fdp, int use_pty)
6878___BOOL use_pty;)(full_duplex_pipe *fdp, int use_pty)
6879{
6880 if (use_pty)
6881 {
6882 if (setsid () >= 0 &&
6883#ifdef TIOCSCTTY0x540E
6884 ioctl (fdp->input.reading_fd, TIOCSCTTY0x540E, 0) >= 0 &&
6885#endif
6886 open_pseudo_terminal_slave (fdp->input.writing_fd,
6887 &fdp->input.reading_fd) >= 0)
6888 {
6889 int tmp;
6890 if (setup_terminal_slave (fdp->input.reading_fd) >= 0 &&
6891 (fdp->output.writing_fd = dup_no_EINTR (fdp->input.reading_fd)) >= 0)
6892 return 0;
6893 tmp = errno(*__errno_location ());
6894 close_no_EINTR (fdp->input.reading_fd); /* ignore error */
6895 errno(*__errno_location ()) = tmp;
6896 }
6897 }
6898 else
6899 return 0;
6900
6901 return -1;
6902}
6903
6904#endif
6905
6906
6907#ifdef USE_CreateProcess
6908
6909#define ___ESCAPE_PROCESS_ARGS
6910
6911___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* argv_to_ccmd
6912 ___P((___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *argv),(char* *argv)
6913 (argv)(char* *argv)
6914___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *argv;)(char* *argv)
6915{
6916 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* ccmd;
6917 int ccmd_len = 0;
6918 int i = 0;
6919 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* arg;
6920
6921 while ((arg = argv[i]) != NULL((void*)0))
6922 {
6923 int j = 0;
6924
6925 while (arg[j] != ___UNICODE_NUL0)
6926 j++;
6927
6928 ccmd_len += j + 1;
6929
6930#ifdef ___ESCAPE_PROCESS_ARGS
6931
6932 {
6933 ___BOOLint double_backslash = TRUE;
6934
6935 while (--j >= 0)
6936 {
6937 ___CHAR_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char c = arg[j];
6938 if (c == ___UNICODE_DOUBLEQUOTE34 ||
6939 (double_backslash && c == ___UNICODE_BACKSLASH92))
6940 {
6941 double_backslash = TRUE;
6942 ccmd_len++;
6943 }
6944 else
6945 double_backslash = FALSE;
6946 }
6947
6948 ccmd_len += 2;
6949 }
6950
6951#endif
6952
6953 i++;
6954 }
6955
6956 ccmd = ___CAST(___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT),((char*)(___alloc_mem (ccmd_len * sizeof (*ccmd))))
6957 ___alloc_mem (ccmd_len * sizeof (*ccmd)))((char*)(___alloc_mem (ccmd_len * sizeof (*ccmd))));
6958
6959 if (ccmd != NULL((void*)0))
6960 {
6961 ccmd[--ccmd_len] = ___UNICODE_NUL0;
6962
6963 while (--i >= 0)
6964 {
6965 int j = 0;
6966
6967 arg = argv[i];
6968
6969 while (arg[j] != ___UNICODE_NUL0)
6970 j++;
6971
6972#ifdef ___ESCAPE_PROCESS_ARGS
6973
6974 {
6975 ___BOOLint double_backslash = TRUE;
6976
6977 ccmd[--ccmd_len] = ___UNICODE_DOUBLEQUOTE34;
6978
6979 while (--j >= 0)
6980 {
6981 ___CHAR_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char c = arg[j];
6982 ccmd[--ccmd_len] = c;
6983 if (c == ___UNICODE_DOUBLEQUOTE34 ||
6984 (double_backslash && c == ___UNICODE_BACKSLASH92))
6985 {
6986 ccmd[--ccmd_len] = ___UNICODE_BACKSLASH92;
6987 double_backslash = TRUE;
6988 }
6989 else
6990 double_backslash = FALSE;
6991 }
6992
6993 ccmd[--ccmd_len] = ___UNICODE_DOUBLEQUOTE34;
6994 }
6995
6996#else
6997
6998 while (--j >= 0)
6999 {
7000 ___CHAR_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char c = arg[j];
7001 ccmd[--ccmd_len] = c;
7002 }
7003
7004#endif
7005
7006 if (i > 0)
7007 ccmd[--ccmd_len] = ___UNICODE_SPACE32;
7008 }
7009 }
7010
7011 return ccmd;
7012}
7013
7014___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* env_to_cenv
7015 ___P((___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *env),(char* *env)
7016 (env)(char* *env)
7017___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *env;)(char* *env)
7018{
7019 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* cenv;
7020 int cenv_len = 0;
7021 int i = 0;
7022 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* varval;
7023
7024 while ((varval = env[i++]) != NULL((void*)0))
7025 {
7026 int j = 0;
7027 while (varval[j++] != ___UNICODE_NUL0)
7028 ;
7029 cenv_len += j;
7030 }
7031
7032 cenv_len++;
7033
7034 cenv = ___CAST(___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT),((char*)(___alloc_mem (cenv_len * sizeof (*cenv))))
7035 ___alloc_mem (cenv_len * sizeof (*cenv)))((char*)(___alloc_mem (cenv_len * sizeof (*cenv))));
7036
7037 if (cenv != NULL((void*)0))
7038 {
7039 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* p = cenv;
7040 i = 0;
7041
7042 while ((varval = env[i++]) != NULL((void*)0))
7043 {
7044 int j = 0;
7045 while ((*p++ = varval[j++]) != ___UNICODE_NUL0)
7046 ;
7047 }
7048
7049 *p++ = ___UNICODE_NUL0;
7050 }
7051
7052 return cenv;
7053}
7054
7055#endif
7056
7057
7058___SCMOBJlong ___device_stream_setup_from_process
7059 ___P((___device_stream **dev,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7060 ___device_group *dgroup,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7061 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *argv,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7062 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *env,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7063 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) dir,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7064 int options),(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7065 (dev,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7066 dgroup,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7067 argv,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7068 env,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7069 dir,(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7070 options)(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7071___device_stream **dev;(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7072___device_group *dgroup;(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7073___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *argv;(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7074___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) *env;(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7075___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT) dir;(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7076int options;)(___device_stream **dev, ___device_group *dgroup, char* *argv
, char* *env, char* dir, int options)
7077{
7078#define STDIN_REDIR1 1
7079#define STDOUT_REDIR2 2
7080#define STDERR_REDIR4 4
7081#define PSEUDO_TERM8 8
7082#define SHOW_CONSOLE16 16
7083
7084#ifdef USE_execvp
7085
7086 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
7087 int direction;
7088 ___device_process *d;
7089 pid_t pid = 0;
7090 half_duplex_pipe hdp_errno;
7091 full_duplex_pipe fdp;
7092 int execvp_errno;
7093 int n;
7094
7095 /*
7096 * Block SIGCHLD so that if the process is created the
7097 * sigchld_signal_handler will find it in the device group.
7098 */
7099
7100 sigset_type oldmask = block_signal (SIGCHLD17);
7101
7102 fdp.input.writing_fd = -1;
7103 fdp.output.reading_fd = -1;
7104
7105 if (open_half_duplex_pipe (&hdp_errno) < 0)
7106 e = err_code_from_errno ()___err_code_from_errno();
7107 else
7108 {
7109 if ((options & (STDIN_REDIR1 | STDOUT_REDIR2 | STDERR_REDIR4)) &&
7110 open_full_duplex_pipe1 (&fdp, options & PSEUDO_TERM8) < 0)
7111 e = err_code_from_errno ()___err_code_from_errno();
7112 else
7113 {
7114 ___disable_os_interrupts ();
7115
7116 if ((pid = fork ()) < 0)
7117 {
7118 e = err_code_from_errno ()___err_code_from_errno();
7119 if (options & (STDIN_REDIR1 | STDOUT_REDIR2 | STDERR_REDIR4))
7120 {
7121 close_half_duplex_pipe (&fdp.input, 2);
7122 close_half_duplex_pipe (&fdp.output, 2);
7123 }
7124 }
7125
7126 if (pid > 0)
7127 ___enable_os_interrupts ();
7128 }
7129
7130 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
7131 close_half_duplex_pipe (&hdp_errno, 2);
7132 }
7133
7134 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
7135 {
7136 if (pid == 0)
7137 {
7138 /* child process */
7139
7140 restore_sigmask (oldmask);
7141
7142 ___cleanup_os_interrupt_handling ();
7143
7144 if (options & (STDIN_REDIR1 | STDOUT_REDIR2 | STDERR_REDIR4))
7145 {
7146 if (open_full_duplex_pipe2 (&fdp, options & PSEUDO_TERM8) < 0 ||
7147 ((options & STDIN_REDIR1) &&
7148 dup2_no_EINTR (fdp.input.reading_fd, STDIN_FILENO0) < 0) ||
7149 ((options & STDOUT_REDIR2) &&
7150 dup2_no_EINTR (fdp.output.writing_fd, STDOUT_FILENO1) < 0) ||
7151 ((options & (STDERR_REDIR4 | PSEUDO_TERM8)) &&
7152 dup2_no_EINTR (fdp.output.writing_fd, STDERR_FILENO2) < 0))
7153 goto return_errno;
7154 }
7155
7156#ifdef USE_fcntl
7157#ifdef FD_CLOEXEC1
7158
7159 if (fcntl (hdp_errno.writing_fd, F_SETFD2, FD_CLOEXEC1) < 0)
7160 goto return_errno;
7161
7162#endif
7163#endif
7164
7165 close_half_duplex_pipe (&fdp.input, 1);
7166 close_half_duplex_pipe (&fdp.output, 0);
7167 close_half_duplex_pipe (&hdp_errno, 0);
7168
7169 {
7170 /* Close all file descriptors that aren't used. */
7171
7172 int fd = sysconf (_SC_OPEN_MAX_SC_OPEN_MAX) - 1;
7173
7174 while (fd >= 0)
7175 {
7176 if (fd != STDIN_FILENO0 &&
7177 fd != STDOUT_FILENO1 &&
7178 fd != STDERR_FILENO2 &&
7179 fd != hdp_errno.writing_fd)
7180 close_no_EINTR (fd); /* ignore error */
7181 fd--;
7182 }
7183 }
7184
7185 if (dir == NULL((void*)0) || chdir (dir) == 0)
7186 {
7187#ifdef USE_environ
7188 if (env != NULL((void*)0))
7189 environ = env;
7190#endif
7191 execvp (argv[0], argv);
7192 /* the exec failed, errno will be returned to parent */
7193 }
7194
7195 return_errno:
7196
7197 /* return the errno to the parent process */
7198
7199 execvp_errno = errno(*__errno_location ());
7200
7201 write (hdp_errno.writing_fd, &execvp_errno, sizeof (execvp_errno));
7202
7203 close_half_duplex_pipe (&fdp.input, 0);
7204 close_half_duplex_pipe (&fdp.output, 1);
7205 close_half_duplex_pipe (&hdp_errno, 1);
7206
7207 _exit (1);
7208 }
7209
7210 /* parent process */
7211
7212 if (options & (STDIN_REDIR1 | STDOUT_REDIR2 | STDERR_REDIR4))
7213 {
7214 close_half_duplex_pipe (&fdp.input, 0);
7215 close_half_duplex_pipe (&fdp.output, 1);
7216 }
7217
7218 close_half_duplex_pipe (&hdp_errno, 1);
7219
7220 /*
7221 * The following call to read has been known to fail with EINTR,
7222 * in particular on OpenBSD 4.5. This is probably because the
7223 * child process that is started terminates before the parent
7224 * process doing the read has time to wakeup. So the parent
7225 * process receives a SIGCHLD signal which interrupts the read.
7226 */
7227
7228 n = read_no_EINTR (hdp_errno.reading_fd,
7229 &execvp_errno,
7230 sizeof (execvp_errno));
7231
7232 if (n < 0)
7233 e = err_code_from_errno ()___err_code_from_errno();
7234 else if (n == sizeof (execvp_errno))
7235 {
7236 errno(*__errno_location ()) = execvp_errno;
7237 e = err_code_from_errno ()___err_code_from_errno();
7238 }
7239 else if (n != 0)
7240 e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
7241 else
7242 {
7243 direction = ___DIRECTION_RD1|___DIRECTION_WR2;
7244
7245 e = ___device_process_setup_from_pid
7246 (&d,
7247 dgroup,
7248 pid,
7249 fdp.input.writing_fd,
7250 fdp.output.reading_fd,
7251 direction);
7252
7253 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
7254
7255 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
7256 device_transfer_close_responsibility (___CAST(___device*,d)((___device*)(d)));
7257 }
7258
7259 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
7260 if (options & (STDIN_REDIR1 | STDOUT_REDIR2 | STDERR_REDIR4))
7261 {
7262 close_half_duplex_pipe (&fdp.input, 1);
7263 close_half_duplex_pipe (&fdp.output, 0);
7264 }
7265
7266 close_half_duplex_pipe (&hdp_errno, 0);
7267 }
7268
7269 restore_sigmask (oldmask);
7270
7271 return e;
7272
7273#endif
7274
7275#ifdef USE_CreateProcess
7276
7277 ___SCMOBJlong e;
7278 int direction;
7279 ___device_process *d;
7280
7281 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* ccmd;
7282 ___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)char* cenv = NULL((void*)0);
7283
7284 HANDLE hstdin_rd = NULL((void*)0);
7285 HANDLE hstdin_wr = NULL((void*)0);
7286 HANDLE hstdout_rd = NULL((void*)0);
7287 HANDLE hstdout_wr = NULL((void*)0);
7288
7289 SECURITY_ATTRIBUTES sa;
7290 PROCESS_INFORMATION pi;
7291 STARTUPINFO si;
7292
7293 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
7294 sa.bInheritHandle = TRUE;
7295 sa.lpSecurityDescriptor = NULL((void*)0);
7296
7297 if ((ccmd = argv_to_ccmd (argv)) == NULL((void*)0) ||
7298 (env != NULL((void*)0) && (cenv = env_to_cenv (env)) == NULL((void*)0)))
7299 e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+5)))<<2)
;
7300 else
7301 {
7302 ZeroMemory (&pi, sizeof (pi));
7303
7304 ZeroMemory (&si, sizeof (si));
7305 si.cb = sizeof (si);
7306
7307 si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
7308 si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
7309 si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
7310
7311 if (options & STDIN_REDIR1)
7312 {
7313 if (!CreatePipe (&hstdin_rd, &hstdin_wr, &sa, 0))
7314 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
7315 else
7316 {
7317 SetHandleInformation (hstdin_wr, HANDLE_FLAG_INHERIT, 0);
7318 si.hStdInput = hstdin_rd;
7319 }
7320 }
7321
7322 if (options & (STDOUT_REDIR2 | STDERR_REDIR4))
7323 {
7324 if (!CreatePipe (&hstdout_rd, &hstdout_wr, &sa, 0))
7325 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
7326 else
7327 {
7328 SetHandleInformation (hstdout_rd, HANDLE_FLAG_INHERIT, 0);
7329 if (options & STDOUT_REDIR2)
7330 si.hStdOutput = hstdout_wr;
7331 if (options & STDERR_REDIR4)
7332 si.hStdError = hstdout_wr;
7333 }
7334 }
7335
7336 si.dwFlags |= STARTF_USESTDHANDLES;
7337
7338#if 0
7339 if (hstdin_wr != NULL((void*)0))
7340 {
7341 HANDLE h_wr;
7342 if (DuplicateHandle (GetCurrentProcess (),
7343 hstdin_wr,
7344 GetCurrentProcess (),
7345 &h_wr,
7346 0,
7347 FALSE,
7348 DUPLICATE_SAME_ACCESS))
7349 {
7350 CloseHandle (hstdin_wr);
7351 hstdin_wr = h_wr;
7352 }
7353 }
7354
7355 if (hstdout_rd != NULL((void*)0))
7356 {
7357 HANDLE h_rd;
7358 if (DuplicateHandle (GetCurrentProcess (),
7359 hstdout_rd,
7360 GetCurrentProcess (),
7361 &h_rd,
7362 0,
7363 FALSE,
7364 DUPLICATE_SAME_ACCESS))
7365 {
7366 CloseHandle (hstdout_rd);
7367 hstdout_rd = h_rd;
7368 }
7369 }
7370#endif
7371
7372 if (si.hStdError == INVALID_HANDLE_VALUE ||
7373 !CreateProcess
7374 (NULL((void*)0), /* module name */
7375 ccmd, /* command line */
7376 NULL((void*)0), /* process handle not inheritable */
7377 NULL((void*)0), /* thread handle not inheritable */
7378 TRUE, /* set handle inheritance to TRUE */
7379 (CP_ENV_FLAGS | ((options & SHOW_CONSOLE16) ? 0 : CREATE_NO_WINDOW)), /* creation flags */
7380 cenv, /* child's environment */
7381 dir, /* child's starting directory */
7382 &si, /* pointer to STARTUPINFO structure */
7383 &pi)) /* pointer to PROCESS_INFORMATION structure */
7384 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
7385 else
7386 {
7387 direction = ___DIRECTION_RD1|___DIRECTION_WR2;
7388
7389 e = ___device_process_setup_from_process
7390 (&d,
7391 dgroup,
7392 pi,
7393 hstdin_wr,
7394 hstdout_rd,
7395 direction);
7396
7397 *dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
7398
7399 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
7400 device_transfer_close_responsibility (___CAST(___device*,d)((___device*)(d)));
7401 }
7402 }
7403
7404 if (hstdout_rd != NULL((void*)0))
7405 CloseHandle (hstdout_wr); /* ignore error */
7406
7407 if (hstdin_rd != NULL((void*)0))
7408 CloseHandle (hstdin_rd); /* ignore error */
7409
7410 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
7411 {
7412 if (hstdout_rd != NULL((void*)0))
7413 CloseHandle (hstdout_rd); /* ignore error */
7414
7415 if (hstdin_rd != NULL((void*)0))
7416 CloseHandle (hstdin_wr); /* ignore error */
7417 }
7418
7419 if (cenv != NULL((void*)0))
7420 ___free_mem (cenv);
7421
7422 if (ccmd != NULL((void*)0))
7423 ___free_mem (ccmd);
7424
7425 return e;
7426
7427#endif
7428}
7429
7430#endif
7431
7432
7433___SCMOBJlong ___os_device_process_pid
7434 ___P((___SCMOBJ dev),(long dev)
7435 (dev)(long dev)
7436___SCMOBJ dev;)(long dev)
7437{
7438 ___device_process *d =
7439 ___CAST(___device_process*,___FIELD(dev,___FOREIGN_PTR))((___device_process*)((*((((long*)((dev)-(1)))+1)+2))));
7440
7441#ifndef USE_POSIX
7442#ifndef USE_WIN32
7443
7444 return ___FIX(0)(((long)(0))<<2);
7445
7446#endif
7447#endif
7448
7449#ifdef USE_POSIX
7450
7451 return ___FIX(d->pid)(((long)(d->pid))<<2);
7452
7453#endif
7454
7455#ifdef USE_WIN32
7456
7457 return ___FIX(d->pi.dwProcessId)(((long)(d->pi.dwProcessId))<<2);
7458
7459#endif
7460}
7461
7462
7463___SCMOBJlong ___os_device_process_status
7464 ___P((___SCMOBJ dev),(long dev)
7465 (dev)(long dev)
7466___SCMOBJ dev;)(long dev)
7467{
7468 ___device_process *d =
7469 ___CAST(___device_process*,___FIELD(dev,___FOREIGN_PTR))((___device_process*)((*((((long*)((dev)-(1)))+1)+2))));
7470 ___SCMOBJlong e;
7471
7472 if ((e = ___device_process_status_poll (d)) != ___FIX(___NO_ERR)(((long)(0))<<2))
7473 return e;
7474
7475 if (!d->got_status)
7476 return ___FAL((((long)(-1))<<2)+2);
7477
7478 return ___FIX(d->status)(((long)(d->status))<<2);
7479}
7480
7481
7482/*---------------------------------------------------------------------------*/
7483
7484#ifndef USE_POSIX
7485#ifndef USE_WIN32
7486#define ___STREAM_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
7487#endif
7488#endif
7489
7490#ifdef USE_POSIX
7491#define ___STREAM_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
7492#endif
7493
7494#ifdef USE_WIN32
7495#ifdef _UNICODE
7496#define ___STREAM_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native ucs2
7497#else
7498#define ___STREAM_OPEN_PATH_CE_SELECT(latin1,utf8,ucs2,ucs4,wchar,native)native native
7499#endif
7500#endif
7501
7502
7503#ifdef ___STREAM_OPEN_PATH_CE_SELECT
7504
7505___SCMOBJlong ___device_stream_setup_from_path
7506 ___P((___device_stream **dev,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7507 ___device_group *dgroup,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7508 ___STRING_TYPE(___STREAM_OPEN_PATH_CE_SELECT) path,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7509 int flags,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7510 int mode),(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7511 (dev,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7512 dgroup,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7513 path,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7514 flags,(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7515 mode)(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7516___device_stream **dev;(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7517___device_group *dgroup;(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7518___STRING_TYPE(___STREAM_OPEN_PATH_CE_SELECT) path;(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7519int flags;(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7520int mode;)(___device_stream **dev, ___device_group *dgroup, char* path,
int flags, int mode)
7521{
7522 ___SCMOBJlong e;
7523
7524#ifndef USE_POSIX
7525#ifndef USE_WIN32
7526
7527 char *mod;
7528 int direction;
7529 ___FILE *stream;
7530
7531 device_translate_flags (flags,
7532 &mod,
7533 &direction);
7534
7535#ifdef ___DEBUG
7536 ___printf ("path=\"%s\" mode=%s\n", path, mod);
7537#endif
7538
7539 if ((stream = ___fopen (path, mod)) == 0)
7540 return fnf_or_err_code_from_errno ()___err_code_from_errno();
7541
7542 if ((e = ___device_stream_setup_from_stream
7543 (dev,
7544 dgroup,
7545 stream,
7546 ___NONE_KIND0,
7547 direction))
7548 != ___FIX(___NO_ERR)(((long)(0))<<2))
7549 ___fclose (stream); /* ignore error */
7550
7551#endif
7552#endif
7553
7554#ifdef USE_POSIX
7555
7556 int fl;
7557 int direction;
7558 int fd;
7559
7560 device_translate_flags (flags,
7561 &fl,
7562 &direction);
7563
7564#ifdef ___DEBUG
7565 ___printf ("path=\"%s\" fl=%d\n", path, fl);
7566#endif
7567
7568 if ((fd = open (path,
7569 fl,
7570#ifdef O_BINARY
7571 O_BINARY|
7572#endif
7573 mode))
7574 < 0)
7575 return fnf_or_err_code_from_errno ()___err_code_from_errno();
7576
7577 if ((e = ___device_stream_setup_from_fd
7578 (dev,
7579 dgroup,
7580 fd,
7581 ___NONE_KIND0,
7582 direction))
7583 != ___FIX(___NO_ERR)(((long)(0))<<2))
7584 close_no_EINTR (fd); /* ignore error */
7585
7586#endif
7587
7588#ifdef USE_WIN32
7589
7590 DWORD access_mode;
7591 DWORD share_mode;
7592 DWORD creation_mode;
7593 DWORD attributes;
7594 int direction;
7595 HANDLE h;
7596
7597 device_translate_flags (flags,
7598 &access_mode,
7599 &share_mode,
7600 &creation_mode,
7601 &attributes,
7602 &direction);
7603
7604 h = CreateFile (path,
7605 access_mode,
7606 share_mode,
7607 NULL((void*)0),
7608 creation_mode,
7609 attributes,
7610 NULL((void*)0));
7611
7612 if (h == INVALID_HANDLE_VALUE)
7613 return fnf_or_err_code_from_GetLastError ()___fnf_or_err_code_from_GetLastError();
7614
7615 if ((e = ___device_stream_setup_from_handle
7616 (dev,
7617 dgroup,
7618 h,
7619 flags,
7620 ___NONE_KIND0,
7621 direction))
7622 != ___FIX(___NO_ERR)(((long)(0))<<2))
7623 CloseHandle (h); /* ignore error */
7624
7625#endif
7626
7627 if (e == ___FIX(___NO_ERR)(((long)(0))<<2))
7628 device_transfer_close_responsibility (___CAST(___device*,*dev)((___device*)(*dev)));
7629
7630 return e;
7631}
7632
7633#endif
7634
7635
7636/*---------------------------------------------------------------------------*/
7637
7638/* Device operations. */
7639
7640___SCMOBJlong ___os_device_kind
7641 ___P((___SCMOBJ dev),(long dev)
7642 (dev)(long dev)
7643___SCMOBJ dev;)(long dev)
7644{
7645 ___device *d = ___CAST(___device*,___FIELD(dev,___FOREIGN_PTR))((___device*)((*((((long*)((dev)-(1)))+1)+2))));
7646
7647 return ___FIX(___device_kind (d))(((long)(((___device_vtbl*)((d)->vtbl))->kind(d)))<<
2)
;
7648}
7649
7650
7651___SCMOBJlong ___os_device_force_output
7652 ___P((___SCMOBJ dev,(long dev, long level)
7653 ___SCMOBJ level),(long dev, long level)
7654 (dev,(long dev, long level)
7655 level)(long dev, long level)
7656___SCMOBJ dev;(long dev, long level)
7657___SCMOBJ level;)(long dev, long level)
7658{
7659 ___device *d = ___CAST(___device*,___FIELD(dev,___FOREIGN_PTR))((___device*)((*((((long*)((dev)-(1)))+1)+2))));
7660
7661 return ___device_force_output (d, ___INT(level)((level)>>2));
7662}
7663
7664
7665___SCMOBJlong ___os_device_close
7666 ___P((___SCMOBJ dev,(long dev, long direction)
7667 ___SCMOBJ direction),(long dev, long direction)
7668 (dev,(long dev, long direction)
7669 direction)(long dev, long direction)
7670___SCMOBJ dev;(long dev, long direction)
7671___SCMOBJ direction;)(long dev, long direction)
7672{
7673 ___device *d = ___CAST(___device*,___FIELD(dev,___FOREIGN_PTR))((___device*)((*((((long*)((dev)-(1)))+1)+2))));
7674
7675 return ___device_close (d, ___INT(direction)((direction)>>2));
7676}
7677
7678
7679/* - - - - - - - - - - - - - - - - - - */
7680
7681/* Stream device operations. */
7682
7683___SCMOBJlong ___os_device_stream_seek
7684 ___P((___SCMOBJ dev,(long dev, long pos, long whence)
7685 ___SCMOBJ pos,(long dev, long pos, long whence)
7686 ___SCMOBJ whence),(long dev, long pos, long whence)
7687 (dev,(long dev, long pos, long whence)
7688 pos,(long dev, long pos, long whence)
7689 whence)(long dev, long pos, long whence)
7690___SCMOBJ dev;(long dev, long pos, long whence)
7691___SCMOBJ pos;(long dev, long pos, long whence)
7692___SCMOBJ whence;)(long dev, long pos, long whence)
7693{
7694 ___device_stream *d =
7695 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7696 ___S32int p;
7697 ___SCMOBJlong e;
7698 ___SCMOBJlong result;
7699
7700 if ((e = ___SCMOBJ_to_S32 (pos, &p, 2)) == ___FIX(___NO_ERR)(((long)(0))<<2))
7701 e = ___device_stream_seek (d, &p, ___INT(whence)((whence)>>2));
7702
7703 if (e != ___FIX(___NO_ERR)(((long)(0))<<2) ||
7704 (e = ___S32_to_SCMOBJ (p, &result, ___RETURN_POS127)) != ___FIX(___NO_ERR)(((long)(0))<<2))
7705 result = e;
7706
7707 return result;
7708}
7709
7710
7711___SCMOBJlong ___os_device_stream_read
7712 ___P((___SCMOBJ dev,(long dev, long buffer, long lo, long hi)
7713 ___SCMOBJ buffer,(long dev, long buffer, long lo, long hi)
7714 ___SCMOBJ lo,(long dev, long buffer, long lo, long hi)
7715 ___SCMOBJ hi),(long dev, long buffer, long lo, long hi)
7716 (dev,(long dev, long buffer, long lo, long hi)
7717 buffer,(long dev, long buffer, long lo, long hi)
7718 lo,(long dev, long buffer, long lo, long hi)
7719 hi)(long dev, long buffer, long lo, long hi)
7720___SCMOBJ dev;(long dev, long buffer, long lo, long hi)
7721___SCMOBJ buffer;(long dev, long buffer, long lo, long hi)
7722___SCMOBJ lo;(long dev, long buffer, long lo, long hi)
7723___SCMOBJ hi;)(long dev, long buffer, long lo, long hi)
7724{
7725 ___device_stream *d =
7726 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7727 ___stream_index len_done;
7728 ___SCMOBJlong e;
7729
7730 if ((e = ___device_stream_read
7731 (d,
7732 ___CAST(___U8*,___BODY_AS(buffer,___tSUBTYPED))((unsigned char*)((((long*)((buffer)-(1)))+1))) + ___INT(lo)((lo)>>2),
7733 ___INT(hi)((hi)>>2) - ___INT(lo)((lo)>>2),
7734 &len_done))
7735 == ___FIX(___NO_ERR)(((long)(0))<<2))
7736 return ___FIX(len_done)(((long)(len_done))<<2);
7737
7738 return e;
7739}
7740
7741
7742___SCMOBJlong ___os_device_stream_write
7743 ___P((___SCMOBJ dev,(long dev, long buffer, long lo, long hi)
7744 ___SCMOBJ buffer,(long dev, long buffer, long lo, long hi)
7745 ___SCMOBJ lo,(long dev, long buffer, long lo, long hi)
7746 ___SCMOBJ hi),(long dev, long buffer, long lo, long hi)
7747 (dev,(long dev, long buffer, long lo, long hi)
7748 buffer,(long dev, long buffer, long lo, long hi)
7749 lo,(long dev, long buffer, long lo, long hi)
7750 hi)(long dev, long buffer, long lo, long hi)
7751___SCMOBJ dev;(long dev, long buffer, long lo, long hi)
7752___SCMOBJ buffer;(long dev, long buffer, long lo, long hi)
7753___SCMOBJ lo;(long dev, long buffer, long lo, long hi)
7754___SCMOBJ hi;)(long dev, long buffer, long lo, long hi)
7755{
7756 ___device_stream *d =
7757 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7758 ___stream_index len_done;
7759 ___SCMOBJlong e;
7760
7761 if ((e = ___device_stream_write
7762 (d,
7763 ___CAST(___U8*,___BODY_AS(buffer,___tSUBTYPED))((unsigned char*)((((long*)((buffer)-(1)))+1))) + ___INT(lo)((lo)>>2),
7764 ___INT(hi)((hi)>>2) - ___INT(lo)((lo)>>2),
7765 &len_done))
7766 == ___FIX(___NO_ERR)(((long)(0))<<2))
7767 return ___FIX(len_done)(((long)(len_done))<<2);
7768
7769 return e;
7770}
7771
7772
7773___SCMOBJlong ___os_device_stream_width
7774 ___P((___SCMOBJ dev),(long dev)
7775 (dev)(long dev)
7776___SCMOBJ dev;)(long dev)
7777{
7778 ___device_stream *d =
7779 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7780
7781 return ___device_stream_width (d)((___device_stream_vtbl*)((d)->base.vtbl))->width(d);
7782}
7783
7784
7785___SCMOBJlong ___os_device_stream_default_options
7786 ___P((___SCMOBJ dev),(long dev)
7787 (dev)(long dev)
7788___SCMOBJ dev;)(long dev)
7789{
7790 ___device_stream *d =
7791 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7792
7793 return ___device_stream_default_options (d)((___device_stream_vtbl*)((d)->base.vtbl))->default_options
(d)
;
7794}
7795
7796
7797___SCMOBJlong ___os_device_stream_options_set
7798 ___P((___SCMOBJ dev,(long dev, long options)
7799 ___SCMOBJ options),(long dev, long options)
7800 (dev,(long dev, long options)
7801 options)(long dev, long options)
7802___SCMOBJ dev;(long dev, long options)
7803___SCMOBJ options;)(long dev, long options)
7804{
7805 ___device_stream *d =
7806 ___CAST(___device_stream*,___FIELD(dev,___FOREIGN_PTR))((___device_stream*)((*((((long*)((dev)-(1)))+1)+2))));
7807
7808 return ___device_stream_options_set (d, options)((___device_stream_vtbl*)((d)->base.vtbl))->options_set
(d,options)
;
7809}
7810
7811
7812/* - - - - - - - - - - - - - - - - - - */
7813
7814/* Opening a predefined device (stdin, stdout, stderr, console, etc). */
7815
7816___SCMOBJlong ___os_device_stream_open_predefined
7817 ___P((___SCMOBJ index,(long index, long flags)
7818 ___SCMOBJ flags),(long index, long flags)
7819 (index,(long index, long flags)
7820 flags)(long index, long flags)
7821___SCMOBJ index;(long index, long flags)
7822___SCMOBJ flags;)(long index, long flags)
7823{
7824 /*
7825 * The parameter "index" identifies the stream which is to be
7826 * associated with the returned device. The stream must be
7827 * currently open. The responsibility for closing the stream is not
7828 * transferred to the runtime system because the client may have to
7829 * do I/O on the stream after the runtime system terminates (for
7830 * example output on stdout).
7831 */
7832
7833 ___SCMOBJlong e;
7834 ___device_stream *dev;
7835 ___SCMOBJlong result;
7836
7837#ifndef USE_POSIX
7838#ifndef USE_WIN32
7839
7840 char *mode;
7841 int direction;
7842 ___FILE *stream;
7843
7844 device_translate_flags (___INT(flags)((flags)>>2),
7845 &mode,
7846 &direction);
7847
7848 switch (___INT(index)((index)>>2))
7849 {
7850 default:
7851 {
7852 switch (___INT(index)((index)>>2))
7853 {
7854 case -1:
7855 stream = ___stdinstdin;
7856 break;
7857 case -2:
7858 stream = ___stdoutstdout;
7859 break;
7860 case -3:
7861 stream = ___stderrstderr;
7862 break;
7863 case -4:
7864 stream = 0;
7865 break;
7866 default:
7867 stream = fdopen (___INT(index)((index)>>2), mode);
7868 break;
7869 }
7870
7871 if ((e = ___device_stream_setup_from_stream
7872 (&dev,
7873 ___global_device_group (),
7874 stream,
7875 ___NONE_KIND0,
7876 direction))
7877 != ___FIX(___NO_ERR)(((long)(0))<<2))
7878 return e;
7879
7880 break;
7881 }
7882 }
7883
7884#endif
7885#endif
7886
7887#ifdef USE_POSIX
7888
7889 int fl;
7890 int direction;
7891 int fd;
7892
7893 device_translate_flags (___INT(flags)((flags)>>2),
7894 &fl,
7895 &direction);
7896
7897 switch (___INT(index)((index)>>2))
7898 {
7899 case -4:
7900 {
7901 ___device_tty *d;
7902
7903 if ((e = ___device_tty_setup_console
7904 (&d,
7905 ___global_device_group (),
7906 direction))
7907 != ___FIX(___NO_ERR)(((long)(0))<<2))
7908 return e;
7909
7910 dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
7911
7912 break;
7913 }
7914
7915 default:
7916 {
7917 switch (___INT(index)((index)>>2))
7918 {
7919 case -1:
7920 fd = STDIN_FILENO0;
7921 break;
7922 case -2:
7923 fd = STDOUT_FILENO1;
7924 break;
7925 case -3:
7926 fd = STDERR_FILENO2;
7927 break;
7928 default:
7929 fd = ___INT(index)((index)>>2);
7930 break;
7931 }
7932
7933 if ((e = ___device_stream_setup_from_fd
7934 (&dev,
7935 ___global_device_group (),
7936 fd,
7937 ___NONE_KIND0,
7938 direction))
7939 != ___FIX(___NO_ERR)(((long)(0))<<2))
7940 return e;
7941
7942 break;
7943 }
7944 }
7945
7946#endif
7947
7948#ifdef USE_WIN32
7949
7950 DWORD access_mode;
7951 DWORD share_mode;
7952 DWORD creation_mode;
7953 DWORD attributes;
7954 int direction;
7955 HANDLE h;
7956
7957 device_translate_flags (___INT(flags)((flags)>>2),
7958 &access_mode,
7959 &share_mode,
7960 &creation_mode,
7961 &attributes,
7962 &direction);
7963
7964 switch (___INT(index)((index)>>2))
7965 {
7966 case -4:
7967 open_console:
7968 {
7969 ___device_tty *d;
7970
7971 if ((e = ___device_tty_setup_console
7972 (&d,
7973 ___global_device_group (),
7974 direction))
7975 != ___FIX(___NO_ERR)(((long)(0))<<2))
7976 return e;
7977
7978 dev = ___CAST(___device_stream*,d)((___device_stream*)(d));
7979
7980 break;
7981 }
7982
7983 default:
7984 {
7985 switch (___INT(index)((index)>>2))
7986 {
7987 default:
7988 case -1:
7989 h = GetStdHandle (STD_INPUT_HANDLE);
7990 break;
7991 case -2:
7992 h = GetStdHandle (STD_OUTPUT_HANDLE);
7993 break;
7994 case -3:
7995 h = GetStdHandle (STD_ERROR_HANDLE);
7996 break;
7997 }
7998
7999 if (h == INVALID_HANDLE_VALUE)
8000 return err_code_from_GetLastError ()___err_code_from_GetLastError();
8001
8002 if (GetFileType (h) == FILE_TYPE_UNKNOWN)
8003 goto open_console;
8004
8005 if ((e = ___device_stream_setup_from_handle
8006 (&dev,
8007 ___global_device_group (),
8008 h,
8009 0,
8010 ___NONE_KIND0,
8011 direction))
8012 != ___FIX(___NO_ERR)(((long)(0))<<2))
8013 return e;
8014
8015 break;
8016 }
8017 }
8018
8019#endif
8020
8021 e = ___NONNULLPOINTER_to_SCMOBJ
8022 (dev,
8023 ___FAL((((long)(-1))<<2)+2),
8024 ___device_cleanup_from_ptr,
8025 &result,
8026 ___RETURN_POS127);
8027
8028 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
8029 {
8030 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8031 return e;
8032 }
8033
8034 ___release_scmobj (result);
8035
8036 return result;
8037}
8038
8039
8040/* - - - - - - - - - - - - - - - - - - */
8041
8042/* Opening a path. */
8043
8044___SCMOBJlong ___os_device_stream_open_path
8045 ___P((___SCMOBJ path,(long path, long flags, long mode)
8046 ___SCMOBJ flags,(long path, long flags, long mode)
8047 ___SCMOBJ mode),(long path, long flags, long mode)
8048 (path,(long path, long flags, long mode)
8049 flags,(long path, long flags, long mode)
8050 mode)(long path, long flags, long mode)
8051___SCMOBJ path;(long path, long flags, long mode)
8052___SCMOBJ flags;(long path, long flags, long mode)
8053___SCMOBJ mode;)(long path, long flags, long mode)
8054{
8055#ifndef ___STREAM_OPEN_PATH_CE_SELECT
8056
8057 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8058
8059#else
8060
8061 ___SCMOBJlong e;
8062 ___SCMOBJlong result;
8063 ___device_stream *dev;
8064 void *cpath;
8065
8066 if ((e = ___SCMOBJ_to_NONNULLSTRING
8067 (path,
8068 &cpath,
8069 1,
8070 ___CE(___STREAM_OPEN_PATH_CE_SELECT)(20<<0),
8071 0))
8072 != ___FIX(___NO_ERR)(((long)(0))<<2))
8073 result = e;
8074 else
8075 {
8076 ___STRING_TYPE(___STREAM_OPEN_PATH_CE_SELECT)char* p =
8077 ___CAST(___STRING_TYPE(___STREAM_OPEN_PATH_CE_SELECT),cpath)((char*)(cpath));
8078
8079 if ((e = ___device_stream_setup_from_path
8080 (&dev,
8081 ___global_device_group (),
8082 p,
8083 ___INT(flags)((flags)>>2),
8084 ___INT(mode)((mode)>>2)))
8085 != ___FIX(___NO_ERR)(((long)(0))<<2))
8086 result = e;
8087 else
8088 {
8089 if ((e = ___NONNULLPOINTER_to_SCMOBJ
8090 (dev,
8091 ___FAL((((long)(-1))<<2)+2),
8092 ___device_cleanup_from_ptr,
8093 &result,
8094 ___RETURN_POS127))
8095 != ___FIX(___NO_ERR)(((long)(0))<<2))
8096 {
8097 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8098 result = e;
8099 }
8100 }
8101
8102 ___release_string (cpath);
8103 }
8104
8105 ___release_scmobj (result);
8106
8107 return result;
8108
8109#endif
8110}
8111
8112
8113/* - - - - - - - - - - - - - - - - - - */
8114
8115/* Opening a process. */
8116
8117___SCMOBJlong ___os_device_stream_open_process
8118 ___P((___SCMOBJ path_and_args,(long path_and_args, long environment, long directory, long options
)
8119 ___SCMOBJ environment,(long path_and_args, long environment, long directory, long options
)
8120 ___SCMOBJ directory,(long path_and_args, long environment, long directory, long options
)
8121 ___SCMOBJ options),(long path_and_args, long environment, long directory, long options
)
8122 (path_and_args,(long path_and_args, long environment, long directory, long options
)
8123 environment,(long path_and_args, long environment, long directory, long options
)
8124 directory,(long path_and_args, long environment, long directory, long options
)
8125 options)(long path_and_args, long environment, long directory, long options
)
8126___SCMOBJ path_and_args;(long path_and_args, long environment, long directory, long options
)
8127___SCMOBJ environment;(long path_and_args, long environment, long directory, long options
)
8128___SCMOBJ directory;(long path_and_args, long environment, long directory, long options
)
8129___SCMOBJ options;)(long path_and_args, long environment, long directory, long options
)
8130{
8131#ifndef ___STREAM_OPEN_PROCESS_CE_SELECT
8132
8133 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8134
8135#else
8136
8137 ___SCMOBJlong e;
8138 ___device_stream *dev;
8139 ___SCMOBJlong result;
8140 void *argv = NULL((void*)0);
8141 void *env = NULL((void*)0);
8142 void *dir = NULL((void*)0);
8143
8144 if ((e = ___SCMOBJ_to_NONNULLSTRINGLIST
8145 (path_and_args,
8146 &argv,
8147 1,
8148 ___CE(___STREAM_OPEN_PROCESS_CE_SELECT)(20<<0)))
8149 != ___FIX(___NO_ERR)(((long)(0))<<2) ||
8150 (environment != ___FAL((((long)(-1))<<2)+2) &&
8151 (e = ___SCMOBJ_to_NONNULLSTRINGLIST
8152 (environment,
8153 &env,
8154 2,
8155 ___CE(___STREAM_OPEN_PROCESS_CE_SELECT)(20<<0)))
8156 != ___FIX(___NO_ERR)(((long)(0))<<2)) ||
8157 (directory != ___FAL((((long)(-1))<<2)+2) &&
8158 (e = ___SCMOBJ_to_NONNULLSTRING
8159 (directory,
8160 &dir,
8161 3,
8162 ___CE(___STREAM_OPEN_PROCESS_CE_SELECT)(20<<0),
8163 0))
8164 != ___FIX(___NO_ERR)(((long)(0))<<2)) ||
8165 (e = ___device_stream_setup_from_process
8166 (&dev,
8167 ___global_device_group (),
8168 ___CAST(___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)*,argv)((char**)(argv)),
8169 ___CAST(___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT)*,env)((char**)(env)),
8170 ___CAST(___STRING_TYPE(___STREAM_OPEN_PROCESS_CE_SELECT),dir)((char*)(dir)),
8171 ___INT(options)((options)>>2)))
8172 != ___FIX(___NO_ERR)(((long)(0))<<2))
8173 result = e;
8174 else
8175 {
8176 if ((e = ___NONNULLPOINTER_to_SCMOBJ
8177 (dev,
8178 ___FAL((((long)(-1))<<2)+2),
8179 ___device_cleanup_from_ptr,
8180 &result,
8181 ___RETURN_POS127))
8182 == ___FIX(___NO_ERR)(((long)(0))<<2))
8183 ___release_scmobj (result);
8184 }
8185
8186 if (argv != NULL((void*)0))
8187 ___release_string_list (argv);
8188
8189 if (env != NULL((void*)0))
8190 ___release_string_list (env);
8191
8192 if (dir != NULL((void*)0))
8193 ___release_string (dir);
8194
8195 return result;
8196
8197#endif
8198}
8199
8200
8201#ifdef USE_POSIX
8202
8203___HIDDENstatic void sigchld_signal_handler
8204 ___P((int sig),(int sig)
8205 (sig)(int sig)
8206int sig;)(int sig)
8207{
8208#ifdef USE_signal
8209 ___set_signal_handler (SIGCHLD17, sigchld_signal_handler);
8210#endif
8211
8212 /*
8213 * A SIGCHLD signal indicates that at least one child has changed
8214 * status. There may be more than one because signals are not
8215 * queued. For example during a period when the SIGCHLD signal is
8216 * blocked several child processes can terminate and only one call
8217 * to the SIGCHLD handler will occur when the SIGCHLD signal is
8218 * unblocked. For this reason we must call waitpid in a loop, until
8219 * the last call indicates that no other child process is available.
8220 */
8221
8222 for (;;)
8223 {
8224 int status;
8225 ___device *head;
8226 pid_t pid = waitpid_no_EINTR (-1, &status, WNOHANG1);
8227
8228 if (pid <= 0)
8229 break;
8230
8231 /*
8232 * Find the process device structure for the process which
8233 * terminated, and save the exit status with the process device.
8234 */
8235
8236 head = ___global_device_group ()->list;
8237
8238 if (head != NULL((void*)0))
8239 {
8240 ___device *d = head->prev;
8241
8242 do
8243 {
8244 if (___device_kind (d)((___device_vtbl*)((d)->vtbl))->kind(d) == ___PROCESS_DEVICE_KIND((15 +32)+65536))
8245 {
8246 ___device_process *dev = ___CAST(___device_process*,d)((___device_process*)(d));
8247
8248 if (dev->pid == pid)
8249 {
8250 if (WIFEXITED(status)((((__extension__ (((union { __typeof(status) __in; int __i; }
) { .__in = (status) }).__i))) & 0x7f) == 0)
|| WIFSIGNALED(status)(((signed char) ((((__extension__ (((union { __typeof(status)
__in; int __i; }) { .__in = (status) }).__i))) & 0x7f) +
1) >> 1) > 0)
)
8251 ___device_process_status_set (dev, status); /* ignore error */
8252 break;
8253 }
8254 }
8255 d = d->prev;
8256 } while (d != head);
8257 }
8258 }
8259}
8260
8261#endif
8262
8263
8264/* - - - - - - - - - - - - - - - - - - */
8265
8266/* Opening a TCP client. */
8267
8268___SCMOBJlong ___os_device_tcp_client_open
8269 ___P((___SCMOBJ server_addr,(long server_addr, long port_num, long options)
8270 ___SCMOBJ port_num,(long server_addr, long port_num, long options)
8271 ___SCMOBJ options),(long server_addr, long port_num, long options)
8272 (server_addr,(long server_addr, long port_num, long options)
8273 port_num,(long server_addr, long port_num, long options)
8274 options)(long server_addr, long port_num, long options)
8275___SCMOBJ server_addr;(long server_addr, long port_num, long options)
8276___SCMOBJ port_num;(long server_addr, long port_num, long options)
8277___SCMOBJ options;)(long server_addr, long port_num, long options)
8278{
8279#ifndef USE_NETWORKING
8280
8281 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8282
8283#else
8284
8285 ___SCMOBJlong e;
8286 ___device_tcp_client *dev;
8287 ___SCMOBJlong result;
8288 struct sockaddr sa;
8289 int salen;
8290
8291 if ((e = ___SCMOBJ_to_sockaddr (server_addr, port_num, &sa, &salen, 1))
1
Taking false branch
8292 != ___FIX(___NO_ERR)(((long)(0))<<2))
8293 return e;
8294
8295 if ((e = ___device_tcp_client_setup_from_sockaddr
2
Calling '___device_tcp_client_setup_from_sockaddr'
8296 (&dev,
8297 ___global_device_group (),
8298 &sa,
8299 salen,
8300 ___INT(options)((options)>>2),
8301 ___DIRECTION_RD1|___DIRECTION_WR2))
8302 != ___FIX(___NO_ERR)(((long)(0))<<2))
8303 return e;
8304
8305 if ((e = ___NONNULLPOINTER_to_SCMOBJ
8306 (dev,
8307 ___FAL((((long)(-1))<<2)+2),
8308 ___device_cleanup_from_ptr,
8309 &result,
8310 ___RETURN_POS127))
8311 != ___FIX(___NO_ERR)(((long)(0))<<2))
8312 {
8313 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8314 return e;
8315 }
8316
8317 ___release_scmobj (result);
8318
8319 return result;
8320
8321#endif
8322}
8323
8324
8325___SCMOBJlong ___os_device_tcp_client_socket_info
8326 ___P((___SCMOBJ dev,(long dev, long peer)
8327 ___SCMOBJ peer),(long dev, long peer)
8328 (dev,(long dev, long peer)
8329 peer)(long dev, long peer)
8330___SCMOBJ dev;(long dev, long peer)
8331___SCMOBJ peer;)(long dev, long peer)
8332{
8333#ifndef USE_NETWORKING
8334
8335 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8336
8337#else
8338
8339 ___device_tcp_client *d =
8340 ___CAST(___device_tcp_client*,___FIELD(dev,___FOREIGN_PTR))((___device_tcp_client*)((*((((long*)((dev)-(1)))+1)+2))));
8341 struct sockaddr sa;
8342 SOCKET_LEN_TYPEsocklen_t salen;
8343
8344 if (d->try_connect_again != 0)
8345 {
8346 if (try_connect (d) == 0)
8347 {
8348 if (d->try_connect_again != 0)
8349 return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
8350 }
8351 else
8352 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
8353 }
8354
8355 salen = sizeof (sa);
8356
8357 if (((peer == ___FAL((((long)(-1))<<2)+2))
8358 ? getsockname (d->s, &sa, &salen)
8359 : getpeername (d->s, &sa, &salen)) < 0)
8360 {
8361 ___SCMOBJlong e = ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
8362 if (NOT_CONNECTED(e)((e) == (((long)(((107)==0?0:((((int)(-1))<<29)+(((int)
(320))<<16)+(107)))))<<2))
&& !d->connect_done)
8363 e = ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<<
16)+(11)))))<<2)
;
8364 return e;
8365 }
8366
8367 return ___sockaddr_to_SCMOBJ (&sa, salen, ___RETURN_POS127);
8368
8369#endif
8370}
8371
8372
8373/* - - - - - - - - - - - - - - - - - - */
8374
8375/* Opening and reading a TCP server. */
8376
8377___SCMOBJlong ___os_device_tcp_server_open
8378 ___P((___SCMOBJ server_addr,(long server_addr, long port_num, long backlog, long options)
8379 ___SCMOBJ port_num,(long server_addr, long port_num, long backlog, long options)
8380 ___SCMOBJ backlog,(long server_addr, long port_num, long backlog, long options)
8381 ___SCMOBJ options),(long server_addr, long port_num, long backlog, long options)
8382 (server_addr,(long server_addr, long port_num, long backlog, long options)
8383 port_num,(long server_addr, long port_num, long backlog, long options)
8384 backlog,(long server_addr, long port_num, long backlog, long options)
8385 options)(long server_addr, long port_num, long backlog, long options)
8386___SCMOBJ server_addr;(long server_addr, long port_num, long backlog, long options)
8387___SCMOBJ port_num;(long server_addr, long port_num, long backlog, long options)
8388___SCMOBJ backlog;(long server_addr, long port_num, long backlog, long options)
8389___SCMOBJ options;)(long server_addr, long port_num, long backlog, long options)
8390{
8391#ifndef USE_NETWORKING
8392
8393 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8394
8395#else
8396
8397 ___SCMOBJlong e;
8398 ___device_tcp_server *dev;
8399 ___SCMOBJlong result;
8400 struct sockaddr sa;
8401 int salen;
8402
8403 if ((e = ___SCMOBJ_to_sockaddr (server_addr, port_num, &sa, &salen, 1))
8404 != ___FIX(___NO_ERR)(((long)(0))<<2))
8405 return e;
8406
8407 e = ___device_tcp_server_setup
8408 (&dev,
8409 ___global_device_group (),
8410 &sa,
8411 salen,
8412 ___INT(backlog)((backlog)>>2),
8413 ___INT(options)((options)>>2));
8414
8415 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
8416 return e;
8417
8418 e = ___NONNULLPOINTER_to_SCMOBJ
8419 (dev,
8420 ___FAL((((long)(-1))<<2)+2),
8421 ___device_cleanup_from_ptr,
8422 &result,
8423 ___RETURN_POS127);
8424
8425 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
8426 {
8427 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8428 return e;
8429 }
8430
8431 ___release_scmobj (result);
8432
8433 return result;
8434
8435#endif
8436}
8437
8438
8439___SCMOBJlong ___os_device_tcp_server_read
8440 ___P((___SCMOBJ dev),(long dev)
8441 (dev)(long dev)
8442___SCMOBJ dev;)(long dev)
8443{
8444#ifndef USE_NETWORKING
8445
8446 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8447
8448#else
8449
8450 ___device_tcp_server *d =
8451 ___CAST(___device_tcp_server*,___FIELD(dev,___FOREIGN_PTR))((___device_tcp_server*)((*((((long*)((dev)-(1)))+1)+2))));
8452 ___SCMOBJlong e;
8453 ___device_tcp_client *client;
8454 ___SCMOBJlong result;
8455
8456 if ((e = ___device_tcp_server_read (d, ___global_device_group (), &client))
8457 != ___FIX(___NO_ERR)(((long)(0))<<2))
8458 return e;
8459
8460 e = ___NONNULLPOINTER_to_SCMOBJ
8461 (client,
8462 ___FAL((((long)(-1))<<2)+2),
8463 ___device_cleanup_from_ptr,
8464 &result,
8465 ___RETURN_POS127);
8466
8467 if (e != ___FIX(___NO_ERR)(((long)(0))<<2))
8468 {
8469 ___device_cleanup (___CAST(___device*,d)((___device*)(d))); /* ignore error */
8470 return e;
8471 }
8472
8473 ___release_scmobj (result);
8474
8475 return result;
8476
8477#endif
8478}
8479
8480
8481___SCMOBJlong ___os_device_tcp_server_socket_info
8482 ___P((___SCMOBJ dev),(long dev)
8483 (dev)(long dev)
8484___SCMOBJ dev;)(long dev)
8485{
8486#ifndef USE_NETWORKING
8487
8488 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8489
8490#else
8491
8492 ___device_tcp_server *d =
8493 ___CAST(___device_tcp_server*,___FIELD(dev,___FOREIGN_PTR))((___device_tcp_server*)((*((((long*)((dev)-(1)))+1)+2))));
8494 struct sockaddr sa;
8495 SOCKET_LEN_TYPEsocklen_t salen;
8496
8497 salen = sizeof (sa);
8498
8499 if (getsockname (d->s, &sa, &salen) < 0)
8500 return ERR_CODE_FROM_SOCKET_CALL___err_code_from_errno();
8501
8502 return ___sockaddr_to_SCMOBJ (&sa, salen, ___RETURN_POS127);
8503
8504#endif
8505}
8506
8507
8508/* - - - - - - - - - - - - - - - - - - */
8509
8510/* Opening and reading a directory. */
8511
8512___SCMOBJlong ___os_device_directory_open_path
8513 ___P((___SCMOBJ path,(long path, long ignore_hidden)
8514 ___SCMOBJ ignore_hidden),(long path, long ignore_hidden)
8515 (path,(long path, long ignore_hidden)
8516 ignore_hidden)(long path, long ignore_hidden)
8517___SCMOBJ path;(long path, long ignore_hidden)
8518___SCMOBJ ignore_hidden;)(long path, long ignore_hidden)
8519{
8520#ifndef ___DIR_OPEN_PATH_CE_SELECT
8521
8522 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8523
8524#else
8525
8526 ___SCMOBJlong e;
8527 ___SCMOBJlong result;
8528 ___device_directory *dev;
8529 void *cpath;
8530
8531 if ((e = ___SCMOBJ_to_NONNULLSTRING
8532 (path,
8533 &cpath,
8534 1,
8535 ___CE(___DIR_OPEN_PATH_CE_SELECT)(20<<0),
8536 0))
8537 != ___FIX(___NO_ERR)(((long)(0))<<2))
8538 result = e;
8539 else
8540 {
8541 ___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT)char* p =
8542 ___CAST(___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT),cpath)((char*)(cpath));
8543
8544 if ((e = ___device_directory_setup
8545 (&dev,
8546 ___global_device_group (),
8547 p,
8548 ___INT(ignore_hidden)((ignore_hidden)>>2)))
8549 != ___FIX(___NO_ERR)(((long)(0))<<2))
8550 result = e;
8551 else
8552 {
8553 if ((e = ___NONNULLPOINTER_to_SCMOBJ
8554 (dev,
8555 ___FAL((((long)(-1))<<2)+2),
8556 ___device_cleanup_from_ptr,
8557 &result,
8558 ___RETURN_POS127))
8559 != ___FIX(___NO_ERR)(((long)(0))<<2))
8560 {
8561 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8562 result = e;
8563 }
8564 }
8565
8566 ___release_string (cpath);
8567 }
8568
8569 ___release_scmobj (result);
8570
8571 return result;
8572
8573#endif
8574}
8575
8576
8577___SCMOBJlong ___os_device_directory_read
8578 ___P((___SCMOBJ dev),(long dev)
8579 (dev)(long dev)
8580___SCMOBJ dev;)(long dev)
8581{
8582#ifndef ___DIR_OPEN_PATH_CE_SELECT
8583
8584 return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+4)))<<2)
;
8585
8586#else
8587
8588 ___device_directory *d =
8589 ___CAST(___device_directory*,___FIELD(dev,___FOREIGN_PTR))((___device_directory*)((*((((long*)((dev)-(1)))+1)+2))));
8590 ___SCMOBJlong e;
8591 ___STRING_TYPE(___DIR_OPEN_PATH_CE_SELECT)char* name;
8592 ___SCMOBJlong result;
8593
8594 if ((e = ___device_directory_read (d, &name)) != ___FIX(___NO_ERR)(((long)(0))<<2))
8595 return e;
8596
8597 if (name == NULL((void*)0))
8598 return ___EOF((((long)(-4))<<2)+2);
8599
8600 if ((e = ___STRING_to_SCMOBJ (name, &result, ___RETURN_POS127, ___CE(___DIR_OPEN_PATH_CE_SELECT)(20<<0) ))
8601 != ___FIX(___NO_ERR)(((long)(0))<<2))
8602 return e;
8603
8604 ___release_scmobj (result);
8605
8606 return result;
8607
8608#endif
8609}
8610
8611
8612/* - - - - - - - - - - - - - - - - - - */
8613
8614/* Opening an event-queue. */
8615
8616___SCMOBJlong ___os_device_event_queue_open
8617 ___P((___SCMOBJ selector),(long selector)
8618 (selector)(long selector)
8619___SCMOBJ selector;)(long selector)
8620{
8621 ___SCMOBJlong e;
8622 ___SCMOBJlong result;
8623 ___device_event_queue *dev;
8624
8625 if ((e = ___device_event_queue_setup
8626 (&dev,
8627 ___global_device_group (),
8628 selector))
8629 != ___FIX(___NO_ERR)(((long)(0))<<2))
8630 result = e;
8631 else
8632 {
8633 if ((e = ___NONNULLPOINTER_to_SCMOBJ
8634 (dev,
8635 ___FAL((((long)(-1))<<2)+2),
8636 ___device_cleanup_from_ptr,
8637 &result,
8638 ___RETURN_POS127))
8639 != ___FIX(___NO_ERR)(((long)(0))<<2))
8640 {
8641 ___device_cleanup (___CAST(___device*,dev)((___device*)(dev))); /* ignore error */
8642 result = e;
8643 }
8644 }
8645
8646 ___release_scmobj (result);
8647
8648 return result;
8649}
8650
8651
8652___SCMOBJlong ___os_device_event_queue_read
8653 ___P((___SCMOBJ dev),(long dev)
8654 (dev)(long dev)
8655___SCMOBJ dev;)(long dev)
8656{
8657 ___device_event_queue *d =
8658 ___CAST(___device_event_queue*,___FIELD(dev,___FOREIGN_PTR))((___device_event_queue*)((*((((long*)((dev)-(1)))+1)+2))));
8659 ___SCMOBJlong e;
8660 ___SCMOBJlong result;
8661
8662 if ((e = ___device_event_queue_read (d, &result)) != ___FIX(___NO_ERR)(((long)(0))<<2))
8663 return e;
8664
8665 ___release_scmobj (result);
8666
8667 return result;
8668}
8669
8670
8671/* - - - - - - - - - - - - - - - - - - */
8672
8673/* Waiting for I/O to become possible on a set of devices. */
8674
8675___SCMOBJlong ___os_condvar_select
8676 ___P((___SCMOBJ run_queue,(long run_queue, long timeout)
8677 ___SCMOBJ timeout),(long run_queue, long timeout)
8678 (run_queue,(long run_queue, long timeout)
8679 timeout)(long run_queue, long timeout)
8680___SCMOBJ run_queue;(long run_queue, long timeout)
8681___SCMOBJ timeout;)(long run_queue, long timeout)
8682{
8683/******************/
8684#define ___BTQ_DEQ_NEXT1 1
8685#define ___BTQ_DEQ_PREV2 2
8686#define ___BTQ_COLOR3 3
8687#define ___BTQ_PARENT4 4
8688#define ___BTQ_LEFT5 5
8689#define ___BTQ_RIGHT6 6
8690#define ___BTQ_LEFTMOST6 6
8691#define ___BTQ_OWNER7 7
8692#define ___CONDVAR_NAME8 8
8693
8694 ___SCMOBJlong e;
8695 ___time to;
8696 ___device *devs[MAX_CONDVARS8192];
8697 ___SCMOBJlong condvars[MAX_CONDVARS8192];
8698 int read_pos;
8699 int write_pos;
8700 ___SCMOBJlong condvar;
8701 int i;
8702 int j;
8703
8704 if (timeout == ___FAL((((long)(-1))<<2)+2))
8705 to = ___time_mod.time_neg_infinity;
8706 else if (timeout == ___TRU((((long)(-2))<<2)+2))
8707 to = ___time_mod.time_pos_infinity;
8708 else
8709 ___time_from_seconds (&to, ___F64VECTORREF(timeout,___FIX(0))*(double*)(((long)(((long*)((timeout)-(1)))+1))+(((((long)(0)
)<<2))<<(3-2)))
);
8710
8711 read_pos = 0;
8712 write_pos = MAX_CONDVARS8192;
8713 condvar = ___FIELD(run_queue,___BTQ_DEQ_NEXT)(*((((long*)((run_queue)-(1)))+1)+1));
8714
8715 while (condvar != run_queue)
8716 {
8717 ___SCMOBJlong owner = ___FIELD(condvar,___BTQ_OWNER)(*((((long*)((condvar)-(1)))+1)+7));
8718 if (read_pos < write_pos)
8719 {
8720 if (owner & ___FIX(2)(((long)(2))<<2))
8721 condvars[--write_pos] = condvar;
8722 else
8723 condvars[read_pos++] = condvar;
8724 ___FIELD(condvar,___BTQ_OWNER)(*((((long*)((condvar)-(1)))+1)+7)) = owner & ~___FIX(1)(((long)(1))<<2);
8725 }
8726 else
8727 {
8728 to = ___time_mod.time_neg_infinity;
8729 ___FIELD(condvar,___BTQ_OWNER)(*((((long*)((condvar)-(1)))+1)+7)) = owner | ___FIX(1)(((long)(1))<<2);
8730 }
8731 condvar = ___FIELD(condvar,___BTQ_DEQ_NEXT)(*((((long*)((condvar)-(1)))+1)+1));
8732 }
8733
8734 i = 0;
8735
8736 while (i < read_pos)
8737 {
8738 devs[i] = ___CAST(___device*,((___device*)((*((((long*)(((*((((long*)((condvars[i])-(1)))+
1)+8)))-(1)))+1)+2))))
8739 ___FIELD(___FIELD(condvars[i],___CONDVAR_NAME),((___device*)((*((((long*)(((*((((long*)((condvars[i])-(1)))+
1)+8)))-(1)))+1)+2))))
8740 ___FOREIGN_PTR))((___device*)((*((((long*)(((*((((long*)((condvars[i])-(1)))+
1)+8)))-(1)))+1)+2))))
;
8741 i++;
8742 }
8743
8744 j = MAX_CONDVARS8192;
8745
8746 while (j > write_pos)
8747 {
8748 j--;
8749 devs[i] = ___CAST(___device*,((___device*)((*((((long*)(((*((((long*)((condvars[j])-(1)))+
1)+8)))-(1)))+1)+2))))
8750 ___FIELD(___FIELD(condvars[j],___CONDVAR_NAME),((___device*)((*((((long*)(((*((((long*)((condvars[j])-(1)))+
1)+8)))-(1)))+1)+2))))
8751 ___FOREIGN_PTR))((___device*)((*((((long*)(((*((((long*)((condvars[j])-(1)))+
1)+8)))-(1)))+1)+2))))
;
8752 i++;
8753 }
8754
8755 e = ___device_select (devs, read_pos, MAX_CONDVARS8192-write_pos, to);
8756
8757 i = 0;
8758
8759 while (i < read_pos)
8760 {
8761 if (devs[i] == NULL((void*)0))
8762 {
8763 condvar = condvars[i];
8764 ___FIELD(condvar,___BTQ_OWNER)(*((((long*)((condvar)-(1)))+1)+7)) |= ___FIX(1)(((long)(1))<<2);
8765 }
8766 i++;
8767 }
8768
8769 j = MAX_CONDVARS8192;
8770
8771 while (j > write_pos)
8772 {
8773 j--;
8774 if (devs[i] == NULL((void*)0))
8775 {
8776 condvar = condvars[j];
8777 ___FIELD(condvar,___BTQ_OWNER)(*((((long*)((condvar)-(1)))+1)+7)) |= ___FIX(1)(((long)(1))<<2);
8778 }
8779 i++;
8780 }
8781
8782 return e;
8783}
8784
8785
8786/* - - - - - - - - - - - - - - - - - - */
8787
8788/*
8789 * Decoding and encoding of a buffer of Scheme characters to a buffer
8790 * of bytes.
8791 */
8792
8793/*
8794 * The following definitions must match the structure of ports defined
8795 * in _io#.scm .
8796 */
8797
8798#define ___PORT_MUTEX1 1
8799#define ___PORT_RKIND2 2
8800#define ___PORT_WKIND3 3
8801#define ___PORT_NAME4 4
8802#define ___PORT_READ_DATUM5 5
8803#define ___PORT_WRITE_DATUM6 6
8804#define ___PORT_NEWLINE7 7
8805#define ___PORT_FORCE_OUTPUT8 8
8806#define ___PORT_CLOSE9 9
8807#define ___PORT_ROPTIONS10 10
8808#define ___PORT_RTIMEOUT11 11
8809#define ___PORT_RTIMEOUT_THUNK12 12
8810#define ___PORT_SET_RTIMEOUT13 13
8811#define ___PORT_WOPTIONS14 14
8812#define ___PORT_WTIMEOUT15 15
8813#define ___PORT_WTIMEOUT_THUNK16 16
8814#define ___PORT_SET_WTIMEOUT17 17
8815#define ___PORT_IO_EXCEPTION_HANDLER18 18
8816
8817#define ___PORT_OBJECT_OTHER119 19
8818#define ___PORT_OBJECT_OTHER220 20
8819#define ___PORT_OBJECT_OTHER321 21
8820
8821#define ___PORT_CHAR_RBUF19 19
8822#define ___PORT_CHAR_RLO20 20
8823#define ___PORT_CHAR_RHI21 21
8824#define ___PORT_CHAR_RCHARS22 22
8825#define ___PORT_CHAR_RLINES23 23
8826#define ___PORT_CHAR_RCURLINE24 24
8827#define ___PORT_CHAR_RBUF_FILL25 25
8828#define ___PORT_CHAR_PEEK_EOFP26 26
8829
8830#define ___PORT_CHAR_WBUF27 27
8831#define ___PORT_CHAR_WLO28 28
8832#define ___PORT_CHAR_WHI29 29
8833#define ___PORT_CHAR_WCHARS30 30
8834#define ___PORT_CHAR_WLINES31 31
8835#define ___PORT_CHAR_WCURLINE32 32
8836#define ___PORT_CHAR_WBUF_DRAIN33 33
8837#define ___PORT_INPUT_READTABLE34 34
8838#define ___PORT_OUTPUT_READTABLE35 35
8839#define ___PORT_OUTPUT_WIDTH36 36
8840
8841#define ___PORT_CHAR_OTHER137 37
8842#define ___PORT_CHAR_OTHER238 38
8843#define ___PORT_CHAR_OTHER339 39
8844#define ___PORT_CHAR_OTHER440 40
8845#define ___PORT_CHAR_OTHER541 41
8846
8847#define ___PORT_BYTE_RBUF37 37
8848#define ___PORT_BYTE_RLO38 38
8849#define ___PORT_BYTE_RHI39 39
8850#define ___PORT_BYTE_RBUF_FILL40 40
8851
8852#define ___PORT_BYTE_WBUF41 41
8853#define ___PORT_BYTE_WLO42 42
8854#define ___PORT_BYTE_WHI43 43
8855#define ___PORT_BYTE_WBUF_DRAIN44 44
8856
8857#define ___PORT_BYTE_OTHER145 45
8858#define ___PORT_BYTE_OTHER246 46
8859
8860#define ___PORT_RDEVICE_CONDVAR45 45
8861#define ___PORT_WDEVICE_CONDVAR46 46
8862
8863#define ___PORT_DEVICE_OTHER147 47
8864#define ___PORT_DEVICE_OTHER248 48
8865
8866#define ___Cunsigned int ___CS_SELECT(___U8,___U16,___U32)unsigned int
8867
8868___SCMOBJlong ___os_port_decode_chars
8869 ___P((___SCMOBJ port,(long port, long want, long eof)
8870 ___SCMOBJ want,(long port, long want, long eof)
8871 ___SCMOBJ eof),(long port, long want, long eof)
8872 (port,(long port, long want, long eof)
8873 want,(long port, long want, long eof)
8874 eof)(long port, long want, long eof)
8875___SCMOBJ port;(long port, long want, long eof)
8876___SCMOBJ want;(long port, long want, long eof)
8877___SCMOBJ eof;)(long port, long want, long eof)
8878{
8879 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
8880 ___SCMOBJlong cbuf = ___FIELD(port,___PORT_CHAR_RBUF)(*((((long*)((port)-(1)))+1)+19));
8881 int chi = ___INT(___FIELD(port,___PORT_CHAR_RHI))(((*((((long*)((port)-(1)))+1)+21)))>>2);
8882 int cend = ___INT(___STRINGLENGTH(cbuf))(((((long)(((((unsigned long)((*((long*)((cbuf)-(1))))))>>
(3 +5))>>2)))<<2))>>2)
;
8883 ___SCMOBJlong bbuf = ___FIELD(port,___PORT_BYTE_RBUF)(*((((long*)((port)-(1)))+1)+37));
8884 int blo = ___INT(___FIELD(port,___PORT_BYTE_RLO))(((*((((long*)((port)-(1)))+1)+38)))>>2);
8885 int bhi = ___INT(___FIELD(port,___PORT_BYTE_RHI))(((*((((long*)((port)-(1)))+1)+39)))>>2);
8886 int options = ___INT(___FIELD(port,___PORT_ROPTIONS))(((*((((long*)((port)-(1)))+1)+10)))>>2);
8887 ___Cunsigned int *cbuf_ptr = ___CAST(___C*,___BODY_AS(cbuf,___tSUBTYPED))((unsigned int*)((((long*)((cbuf)-(1)))+1)));
8888 ___U8unsigned char *bbuf_ptr = ___CAST(___U8*,___BODY_AS(bbuf,___tSUBTYPED))((unsigned char*)((((long*)((bbuf)-(1)))+1)));
8889 int cbuf_avail;
8890 int bbuf_avail;
8891 int code;
8892
8893 if (want != ___FAL((((long)(-1))<<2)+2))
8894 {
8895 int w = ___INT(want)((want)>>2);
8896 if (chi+w < cend)
8897 cend = chi+w;
8898 }
8899
8900 cbuf_avail = cend - chi;
8901 bbuf_avail = bhi - blo;
8902
8903 code = chars_from_bytes (cbuf_ptr + chi,
8904 &cbuf_avail,
8905 bbuf_ptr + blo,
8906 &bbuf_avail,
8907 &options);
8908
8909 /*
8910 * either the character buffer is full (cbuf_avail == 0) or no more
8911 * characters can be extracted from the byte buffer either because
8912 * the remaining bytes are not long enough to form a character or
8913 * don't form a valid character.
8914 */
8915
8916 if (cbuf_avail == cend - chi)
8917 {
8918 if (code == ___INCOMPLETE_CHAR1 && eof != ___FAL((((long)(-1))<<2)+2))
8919 {
8920 bbuf_avail = 0; /* skip bytes up to end-of-file */
8921 code = ___ILLEGAL_CHAR2;
8922 }
8923
8924 if (code == ___ILLEGAL_CHAR2)
8925 {
8926 if (___CHAR_ENCODING_ERRORS(options)((options)&(3<<5)) != ___CHAR_ENCODING_ERRORS_OFF(2<<5))
8927 e = err_code_from_char_encoding (___CHAR_ENCODING(options)((options)&(31<<0)), 1, 0, 0);
8928 else
8929 {
8930 if (___CHAR_ENCODING_SUPPORTS_BMP(___CHAR_ENCODING(options))((((options)&(31<<0))) >= (3<<0) &&
(((options)&(31<<0))) <= (18<<0))
)
8931 cbuf_ptr[chi] = ___UNICODE_REPLACEMENT0xfffd;
8932 else
8933 cbuf_ptr[chi] = ___UNICODE_QUESTION63;
8934
8935 cbuf_avail--;
8936 }
8937 }
8938 }
8939
8940 ___FIELD(port,___PORT_CHAR_RHI)(*((((long*)((port)-(1)))+1)+21)) = ___FIX(cend - cbuf_avail)(((long)(cend - cbuf_avail))<<2);
8941 ___FIELD(port,___PORT_BYTE_RLO)(*((((long*)((port)-(1)))+1)+38)) = ___FIX(bhi - bbuf_avail)(((long)(bhi - bbuf_avail))<<2);
8942 ___FIELD(port,___PORT_ROPTIONS)(*((((long*)((port)-(1)))+1)+10)) = ___FIX(options)(((long)(options))<<2);
8943
8944 return e;
8945}
8946
8947
8948___SCMOBJlong ___os_port_encode_chars
8949 ___P((___SCMOBJ port),(long port)
8950 (port)(long port)
8951___SCMOBJ port;)(long port)
8952{
8953 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
8954 ___SCMOBJlong cbuf = ___FIELD(port,___PORT_CHAR_WBUF)(*((((long*)((port)-(1)))+1)+27));
8955 int clo = ___INT(___FIELD(port,___PORT_CHAR_WLO))(((*((((long*)((port)-(1)))+1)+28)))>>2);
8956 int chi = ___INT(___FIELD(port,___PORT_CHAR_WHI))(((*((((long*)((port)-(1)))+1)+29)))>>2);
8957 ___SCMOBJlong bbuf = ___FIELD(port,___PORT_BYTE_WBUF)(*((((long*)((port)-(1)))+1)+41));
8958 int bhi = ___INT(___FIELD(port,___PORT_BYTE_WHI))(((*((((long*)((port)-(1)))+1)+43)))>>2);
8959 int bend = ___INT(___U8VECTORLENGTH(bbuf))(((((long)((((unsigned long)((*((long*)((bbuf)-(1))))))>>
(3 +5))))<<2))>>2)
;
8960 int options = ___INT(___FIELD(port,___PORT_WOPTIONS))(((*((((long*)((port)-(1)))+1)+14)))>>2);
8961 ___Cunsigned int *cbuf_ptr = ___CAST(___C*,___BODY_AS(cbuf,___tSUBTYPED))((unsigned int*)((((long*)((cbuf)-(1)))+1)));
8962 ___U8unsigned char *bbuf_ptr = ___CAST(___U8*,___BODY_AS(bbuf,___tSUBTYPED))((unsigned char*)((((long*)((bbuf)-(1)))+1)));
8963 int cbuf_avail;
8964 int bbuf_avail;
8965 int code;
8966
8967 cbuf_avail = chi - clo;
8968 bbuf_avail = bend - bhi;
8969
8970 code = chars_to_bytes (cbuf_ptr + clo,
8971 &cbuf_avail,
8972 bbuf_ptr + bhi,
8973 &bbuf_avail,
8974 &options);
8975
8976 /*
8977 * either the character buffer is empty (cbuf_avail == 0) or there
8978 * is not enough space left in the byte buffer for encoding the next
8979 * character, or the next character is illegal for the given
8980 * encoding.
8981 */
8982
8983 if (cbuf_avail == chi - clo)
8984 if (code == ___ILLEGAL_CHAR2)
8985 {
8986 if (___CHAR_ENCODING_ERRORS(options)((options)&(3<<5)) != ___CHAR_ENCODING_ERRORS_OFF(2<<5))
8987 {
8988 cbuf_avail--; /* skip illegal char */
8989 e = err_code_from_char_encoding (___CHAR_ENCODING(options)((options)&(31<<0)), 0, 0, 0);
8990 }
8991 else
8992 {
8993 ___Cunsigned int replacement_cbuf[1];
8994 int replacement_cbuf_avail = 1;
8995
8996 if (___CHAR_ENCODING_SUPPORTS_BMP(___CHAR_ENCODING(options))((((options)&(31<<0))) >= (3<<0) &&
(((options)&(31<<0))) <= (18<<0))
)
8997 replacement_cbuf[0] = ___UNICODE_REPLACEMENT0xfffd;
8998 else
8999 replacement_cbuf[0] = ___UNICODE_QUESTION63;
9000
9001 code = chars_to_bytes (replacement_cbuf,
9002 &replacement_cbuf_avail,
9003 bbuf_ptr + bend - bbuf_avail,
9004 &bbuf_avail,
9005 &options);
9006
9007 /*
9008 * skip over the illegal character if the replacement
9009 * character was encoded
9010 */
9011
9012 cbuf_avail = cbuf_avail - 1 + replacement_cbuf_avail;
9013 }
9014 }
9015
9016 ___FIELD(port,___PORT_CHAR_WLO)(*((((long*)((port)-(1)))+1)+28)) = ___FIX(chi - cbuf_avail)(((long)(chi - cbuf_avail))<<2);
9017 ___FIELD(port,___PORT_BYTE_WHI)(*((((long*)((port)-(1)))+1)+43)) = ___FIX(bend - bbuf_avail)(((long)(bend - bbuf_avail))<<2);
9018 ___FIELD(port,___PORT_WOPTIONS)(*((((long*)((port)-(1)))+1)+14)) = ___FIX(options)(((long)(options))<<2);
9019
9020 return e;
9021}
9022
9023
9024/*---------------------------------------------------------------------------*/
9025
9026/* I/O module initialization/finalization. */
9027
9028
9029___HIDDENstatic ___SCMOBJlong io_module_setup ___PVOID(void)
9030{
9031 ___SCMOBJlong e;
9032
9033 if ((e = ___device_group_setup (&___io_mod.dgroup)) == ___FIX(___NO_ERR)(((long)(0))<<2))
9034 {
9035#ifdef USE_POSIX
9036
9037 ___set_signal_handler (SIGCHLD17, sigchld_signal_handler);
9038
9039#endif
9040
9041#ifdef USE_WIN32
9042
9043#define WINSOCK_MAJOR 1
9044#define WINSOCK_MINOR 1
9045
9046 WSADATA winsock_data;
9047
9048 if (!WSAStartup (MAKEWORD(WINSOCK_MAJOR, WINSOCK_MINOR), &winsock_data))
9049 {
9050 if (LOBYTE(winsock_data.wVersion) == WINSOCK_MINOR &&
9051 HIBYTE(winsock_data.wVersion) == WINSOCK_MAJOR)
9052 return ___FIX(___NO_ERR)(((long)(0))<<2);
9053 WSACleanup (); /* ignore error */
9054 }
9055
9056 e = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
9057
9058 ___device_group_cleanup (___io_mod.dgroup);
9059
9060#endif
9061 }
9062
9063 return e;
9064}
9065
9066
9067___HIDDENstatic void io_module_cleanup ___PVOID(void)
9068{
9069#ifdef USE_POSIX
9070
9071 ___set_signal_handler (SIGCHLD17, SIG_DFL((__sighandler_t) 0));
9072
9073#endif
9074
9075#ifdef USE_WIN32
9076
9077 WSACleanup (); /* ignore error */
9078
9079#endif
9080
9081 ___device_group_cleanup (___io_mod.dgroup);
9082}
9083
9084
9085
9086___SCMOBJlong ___setup_io_module ___PVOID(void)
9087{
9088 if (!___io_mod.setup)
9089 {
9090#ifdef USE_WIN32
9091
9092 ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2);
9093
9094 ___io_mod.always_signaled = NULL((void*)0);
9095 ___io_mod.abort_select = NULL((void*)0);
9096
9097 ___io_mod.always_signaled =
9098 CreateEvent (NULL((void*)0), /* can't inherit */
9099 TRUE, /* manual reset */
9100 TRUE, /* signaled */
9101 NULL((void*)0)); /* no name */
9102
9103 if (___io_mod.always_signaled == NULL((void*)0))
9104 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
9105 else
9106 {
9107 ___io_mod.abort_select =
9108 CreateEvent (NULL((void*)0), /* can't inherit */
9109 TRUE, /* manual reset */
9110 FALSE, /* not signaled */
9111 NULL((void*)0)); /* no name */
9112
9113 if (___io_mod.abort_select == NULL((void*)0))
9114 {
9115 CloseHandle (___io_mod.always_signaled); /* ignore error */
9116 e = err_code_from_GetLastError ()___err_code_from_GetLastError();
9117 }
9118 }
9119
9120#endif
9121
9122 io_module_setup ();/*****************************/
9123 ___io_mod.setup = 1;
9124 return ___FIX(___NO_ERR)(((long)(0))<<2);
9125 }
9126
9127 return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+(
0))+3)))<<2)
;
9128}
9129
9130
9131void ___cleanup_io_module ___PVOID(void)
9132{
9133 if (___io_mod.setup)
9134 {
9135 io_module_cleanup ();/*****************************/
9136#ifdef USE_WIN32
9137 CloseHandle (___io_mod.abort_select); /* ignore error */
9138 CloseHandle (___io_mod.always_signaled); /* ignore error */
9139#endif
9140 ___io_mod.setup = 0;
9141 }
9142}
9143
9144
9145/*---------------------------------------------------------------------------*/