/
os_io.h
887 lines (674 loc) · 24.1 KB
/
os_io.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
/* File: "os_io.h" */
/* Copyright (c) 1994-2017 by Marc Feeley, All Rights Reserved. */
#ifndef ___OS_IO_H
#define ___OS_IO_H
#include "os.h"
#include "os_time.h"
/*---------------------------------------------------------------------------*/
typedef struct ___device_group_struct
{
struct ___device_struct *list; /* list of devices in this group */
} ___device_group;
#define ___NONE_KIND 0
#define ___WAITABLE_KIND 1
#define ___OBJECT_KIND 3
#define ___CHARACTER_KIND 7
#define ___BYTE_KIND 15
#define ___DEVICE_KIND 31
#define ___FILE_DEVICE_KIND (___DEVICE_KIND+32)
#define ___PIPE_DEVICE_KIND (___DEVICE_KIND+64)
#define ___PROCESS_DEVICE_KIND (___PIPE_DEVICE_KIND+131072)
#define ___TTY_DEVICE_KIND (___DEVICE_KIND+128)
#define ___SERIAL_DEVICE_KIND (___DEVICE_KIND+256)
#define ___TCP_CLIENT_DEVICE_KIND (___DEVICE_KIND+512)
#define ___TCP_SERVER_DEVICE_KIND (___OBJECT_KIND+1024)
#define ___DIRECTORY_KIND (___OBJECT_KIND+2048)
#define ___EVENT_QUEUE_KIND (___OBJECT_KIND+4096)
#define ___TIMER_KIND (___OBJECT_KIND+8192)
#define ___VECTOR_KIND (___OBJECT_KIND+16384)
#define ___STRING_KIND (___CHARACTER_KIND+32768)
#define ___U8VECTOR_KIND (___BYTE_KIND+65536)
#define ___RAW_DEVICE_KIND (___WAITABLE_KIND+262144)
#define ___OPEN_STATE(x) ((x)&(1<<12))
#define ___OPEN_STATE_MASK(x) ((x)&~(1<<12))
#define ___OPEN_STATE_OPEN (0<<12)
#define ___OPEN_STATE_CLOSED (1<<12)
#define ___DIRECTION_RD 1
#define ___DIRECTION_WR 2
#define ___STAGE_OPEN 0
#define ___STAGE_CLOSING1 1
#define ___STAGE_CLOSING2 2
#define ___STAGE_CLOSED 3
#define ___SELECT_PASS_CHECK 0
#define ___SELECT_PASS_1 1
#define ___SELECT_PASS_2 2
#define ___SELECT_PASS_3 3
#define ___STREAM_OPTIONS(icee,ice,iee,ib,ocee,oce,oee,ob) \
(icee+ice+iee+ib)+((ocee+oce+oee+ob)<<15)
#define ___STREAM_OPTIONS_INPUT(options) ((options)&((1<<15)-1))
#define ___STREAM_OPTIONS_OUTPUT(options) (((options)>>15)&((1<<15)-1))
#ifdef USE_OPENSSL
#define ___TLS_OPTION_SERVER_MODE 1
#define ___TLS_OPTION_USE_DIFFIE_HELLMAN 1<<1
#define ___TLS_OPTION_USE_ELLIPTIC_CURVES 1<<2
#define ___TLS_OPTION_REQUEST_CLIENT_AUTHENTICATION 1<<3
#define ___TLS_OPTION_INSERT_EMPTY_FRAGMENTS 1<<8
#endif
typedef struct ___device_struct
{
void *vtbl;
#ifdef USE_PUMPS
LONG refcount; /* device structure is released when zero */
#else
int refcount; /* device structure is released when zero */
#endif
___device_group *group; /* device group this device belongs to */
struct ___device_struct *prev; /* bidirectional list pointer to previous */
struct ___device_struct *next; /* bidirectional list pointer to next */
int direction; /* ___DIRECTION_RD and/or ___DIRECTION_WR */
int close_direction; /* ___DIRECTION_RD and/or ___DIRECTION_WR */
int read_stage; /* ___STAGE_OPEN ... ___STAGE_CLOSED */
int write_stage; /* ___STAGE_OPEN ... ___STAGE_CLOSED */
} ___device;
#ifndef MAX_CONDVARS
#define MAX_CONDVARS 8192
#endif
#ifdef USE_select_or_poll
typedef ___UWORD ___fdbits;
#define ___FDBITS ___WORD_WIDTH
#define ___FD_ELT(fd) ((fd) >> ___LOG_WORD_WIDTH)
#define ___FD_MASK(fd) ((___fdbits) 1 << ((fd) % ___WORD_WIDTH))
#define ___FD_ZERO(set, sz) \
memset ((set), 0, sz/8)
#define ___FD_SET(fd, set) \
((set)[___FD_ELT (fd)] |= ___FD_MASK (fd))
#define ___FD_CLR(fd, set) \
((set)[___FD_ELT (fd)] &= ~___FD_MASK (fd))
#define ___FD_ISSET(fd, set) \
((set)[___FD_ELT (fd)] & ___FD_MASK (fd))
#endif
typedef struct ___device_select_state_struct
{
___device **devs; /* devices to select on */
___time timeout; /* absolute timeout of the select */
___F64 relative_timeout; /* relative timeout of the select in seconds */
___BOOL timeout_reached; /* did select reach the timeout? */
int devs_next[MAX_CONDVARS];
#ifdef USE_select_or_poll
#ifdef USE_select
int highest_fd_plus_1;
___fdbits *readfds;
___fdbits *writefds;
___fdbits *exceptfds;
#endif
#ifdef USE_poll
struct pollfd pollfds[MAX_CONDVARS];
int pollfd_count;
/* active set bitmaps */
___fdbits *readfds;
___fdbits *writefds;
#endif
#endif
#ifdef USE_MsgWaitForMultipleObjects
DWORD message_queue_mask;
int message_queue_dev_pos;
DWORD nb_wait_objs;
HANDLE wait_objs_buffer[MAXIMUM_WAIT_OBJECTS];
int wait_obj_to_dev_pos[MAXIMUM_WAIT_OBJECTS];
#endif
#ifdef USE_MACOS
/*********************/
#endif
} ___device_select_state;
#ifdef USE_FDSET_RESIZING
extern void ___fdset_resize_pstate
___P((___processor_state ___ps,
int maxfd),
());
extern ___BOOL ___fdset_resize
___P((int fd1,
int fd2),
());
#endif
extern void ___device_select_add_relative_timeout
___P((___device_select_state *state,
int i,
___F64 seconds),
());
void ___device_select_add_timeout
___P((___device_select_state *state,
int i,
___time timeout),
());
#ifdef USE_POSIX
extern void ___device_select_add_fd
___P((___device_select_state *state,
int fd,
___BOOL for_writing),
());
#endif
#ifdef USE_MsgWaitForMultipleObjects
extern void ___device_select_add_wait_obj
___P((___device_select_state *state,
int i,
HANDLE wait_obj),
());
#endif
typedef struct ___device_vtbl_struct
{
#define ___device_kind(self) \
___CAST(___device_vtbl*,(self)->vtbl)->kind(self)
int (*kind) ___P((___device *self),());
#define ___device_select_virt(self,for_writing,i,pass,state) \
___CAST(___device_vtbl*,(self)->vtbl)->select_virt(self,for_writing,i,pass,state)
___SCMOBJ (*select_virt)
___P((___device *self,
___BOOL for_writing,
int i,
int pass,
___device_select_state *state),
());
#define ___device_release_virt(self) \
___CAST(___device_vtbl*,(self)->vtbl)->release_virt(self)
___SCMOBJ (*release_virt)
___P((___device *self),
());
#define ___device_force_output_virt(self,level) \
___CAST(___device_vtbl*,(self)->vtbl)->force_output_virt(self,level)
___SCMOBJ (*force_output_virt)
___P((___device *self,
int level),
());
#define ___device_close_virt(self,direction) \
___CAST(___device_vtbl*,(self)->vtbl)->close_virt(self,direction)
___SCMOBJ (*close_virt)
___P((___device *self,
int direction),
());
} ___device_vtbl;
/*---------------------------------------------------------------------------*/
typedef struct ___io_module_struct
{
___BOOL setup;
___device_group *dgroup;
#ifdef USE_POSIX
#define ___IO_MODULE_INIT
#endif
#ifdef USE_WIN32
HANDLE always_signaled; /* this event is always signaled */
#define ___IO_MODULE_INIT , 0
#endif
} ___io_module;
extern ___io_module ___io_mod;
/*---------------------------------------------------------------------------*/
/* Device groups. */
extern ___SCMOBJ ___device_group_setup
___P((___device_group **dgroup),
());
extern void ___device_group_cleanup
___P((___device_group *dgroup),
());
extern void ___device_add_to_group
___P((___device_group *dgroup,
___device *dev),
());
extern void ___device_remove_from_group
___P((___device *dev),
());
extern ___device_group *___global_device_group ___PVOID;
/*---------------------------------------------------------------------------*/
typedef int ___stream_index;
/* Nonblocking pipes */
#ifdef USE_PUMPS
/*
* A pipe is a unidirectional FIFO data structure that buffers data
* between a "writer" that writes data to the pipe and a "reader" that
* reads this data. Independently from the FIFO buffer, a pipe has a
* "reader error indicator" and a "writer error indicator". When
* created the error indicators are set to "no error" and the FIFO
* contains no data.
*
* Typically the writer writes bytes and out-of-band messages at one
* end with a "write" operation and the reader reads these bytes and
* out-of-band messages in the same order at the other end with a
* "read" operation. Out-of-band messages are used to request some
* special action from the reader and are expected to be infrequent.
* When a read operation extracts an out-of-band message from the pipe
* it reports that zero bytes can be read from the pipe and sets the
* out-of-band structure (one of the parameters of the read
* operation). The writer can set the "writer error indicator" when
* it needs to transmit an error code to the reader. After all
* previously written bytes and out-of-band messages are read by the
* reader, the next read operation will return this error code and the
* error indicator is reset to "no error". Similarly, the reader can
* set the "reader error indicator" when it needs to transmit an error
* code to the writer. The next write operation will return this
* error code and the error indicator is reset to "no error".
*
* The nonblocking pipes implemented here have read and write
* operations that don't block the calling thread. When the data
* transfer requested can't be performed immediately these operations
* will return with a special error code (EAGAIN). This allows the
* calling thread to do other things before attempting the operation
* again. We say a pipe is "ready for an operation" if calling that
* operation will not return EAGAIN (i.e. the operations will succeed
* with no error or will fail with some error different from EAGAIN).
*
* Specifically,
*
* a pipe is ready for reading when
* - the "writer error indicator" is not "no error"
* - or
* - the "reader error indicator" is "no error"
* - and
* - an out-of-band message is in the pipe
* - or at least one byte is in the FIFO buffer
*
* a pipe is ready for writing when
* - the "reader error indicator" is not "no error"
* - or
* - the "writer error indicator" is "no error"
* - and no out-of-band message is in the pipe
* - and at least one byte is free in the FIFO buffer
* - and the previous read operation did not return an error or
* an out-of-band message
* (at creation a pipe is not ready for writing and the first
* "read" operation will make the pipe ready for writing, in other
* words, after it reports an error or out-of-band message, the
* writer blocks until the reader shows some interest in more data)
*
* This table summarizes the states of a pipe (an R means ready for
* reading and a W means ready for writing and a w means ready for
* writing iff the most recent read operation did not return an
* error or out-of-band message):
*
* no writer : writer reader bytes in FIFO buffer
* error : error error? (N is size of buffer)
* +----+----+----+----+
* | w | R | R | R | no 0 bytes
* +----+----+----+----+
* | Rw | R | R | R | no > 0 bytes but < N
* +----+----+----+----+
* | R | R | R | R | no = N
* +----+----+----+----+
* | W | W | RW | RW | yes 0 bytes
* +----+----+----+----+
* | W | W | RW | RW | yes > 0 bytes but < N
* +----+----+----+----+
* | W | W | RW | RW | yes = N
* +----+----+----+----+
* :!oob:oob :!oob:oob :
*
*/
typedef struct ___nonblocking_pipe_oob_msg_struct
{
int op; /* operation */
___stream_index stream_index_param; /* parameters */
} ___nonblocking_pipe_oob_msg;
typedef struct ___nonblocking_pipe_struct
{
HANDLE mutex; /* mutex to serialize access to the pipe */
HANDLE revent; /* event, signaled iff ready for reading */
HANDLE wevent; /* event, signaled iff ready for writing */
___SCMOBJ rerr; /* the reader error indicator */
___SCMOBJ werr; /* the writer error indicator */
___BOOL oob; /* the out-of-band indicator */
___nonblocking_pipe_oob_msg oob_msg; /* out-of-band message */
DWORD rd; /* the read pointer of the circular buffer */
DWORD wr; /* the write pointer of the circular buffer */
DWORD size; /* size of the circular buffer */
___U8 *buffer; /* the circular buffer */
} ___nonblocking_pipe;
#define OOB_EOS 0
#define OOB_SEEK_TELL 1
#define OOB_SEEK_ABS 2
#define OOB_SEEK_REL 3
#define OOB_SEEK_REL_END 4
#define OOB_FORCE_OUTPUT0 5
#define OOB_FORCE_OUTPUT1 6
#define OOB_FORCE_OUTPUT2 7
#define OOB_FORCE_OUTPUT3 8
typedef struct ___device_stream_pump_struct
{
HANDLE thread;
___nonblocking_pipe pipe;
} ___device_stream_pump;
#define PIPE_BUFFER_SIZE 16384
/*
* It is important that the PUMP_PRIORITY be above that of the main
* program (which is THREAD_PRIORITY_NORMAL) so that I/O operations,
* such as flushing output buffers, will be done as soon as the pump
* reads it from the nonblocking pipe. Thus the operation will appear
* to be synchronous to the main program.
*/
#define PUMP_PRIORITY THREAD_PRIORITY_ABOVE_NORMAL
#endif
/*---------------------------------------------------------------------------*/
/* Devices. */
/* Timer device. */
typedef struct ___device_timer_struct
{
___device base;
___time expiry;
} ___device_timer;
typedef struct ___device_timer_vtbl_struct
{
___device_vtbl base;
} ___device_timer_vtbl;
extern ___SCMOBJ ___device_timer_setup
___P((___device_timer **dev,
___device_group *dgroup),
());
extern void ___device_timer_set_expiry
___P((___device_timer *dev,
___time expiry),
());
/* Byte stream device. */
typedef struct ___device_stream_struct
{
___device base;
#ifdef USE_PUMPS
___device_stream_pump *read_pump;
___device_stream_pump *write_pump;
#endif
} ___device_stream;
typedef struct ___device_stream_vtbl_struct
{
___device_vtbl base;
#define ___device_stream_select_raw_virt(self,for_writing,i,pass,state) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->select_raw_virt(self,for_writing,i,pass,state)
___SCMOBJ (*select_raw_virt)
___P((___device_stream *self,
___BOOL for_writing,
int i,
int pass,
___device_select_state *state),
());
#define ___device_stream_release_raw_virt(self) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->release_raw_virt(self)
___SCMOBJ (*release_raw_virt)
___P((___device_stream *self),
());
#define ___device_stream_force_output_raw_virt(self,level) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->force_output_raw_virt(self,level)
___SCMOBJ (*force_output_raw_virt)
___P((___device_stream *self,
int level),
());
#define ___device_stream_close_raw_virt(self,direction) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->close_raw_virt(self,direction)
___SCMOBJ (*close_raw_virt)
___P((___device_stream *self,
int direction),
());
#define ___device_stream_seek_raw_virt(self,pos,whence) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->seek_raw_virt(self,pos,whence)
___SCMOBJ (*seek_raw_virt)
___P((___device_stream *self,
___stream_index *pos,
int whence),
());
#define ___device_stream_read_raw_virt(self,buf,len,len_done) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->read_raw_virt(self,buf,len,len_done)
___SCMOBJ (*read_raw_virt)
___P((___device_stream *self,
___U8 *buf,
___stream_index len,
___stream_index *len_done),
());
#define ___device_stream_write_raw_virt(self,buf,len,len_done) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->write_raw_virt(self,buf,len,len_done)
___SCMOBJ (*write_raw_virt)
___P((___device_stream *self,
___U8 *buf,
___stream_index len,
___stream_index *len_done),
());
#define ___device_stream_width(self) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->width(self)
___SCMOBJ (*width)
___P((___device_stream *self),
());
#define ___device_stream_default_options(self) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->default_options(self)
___SCMOBJ (*default_options)
___P((___device_stream *self),
());
#define ___device_stream_options_set(self,options) \
___CAST(___device_stream_vtbl*,(self)->base.vtbl)->options_set(self,options)
___SCMOBJ (*options_set)
___P((___device_stream *self,
___SCMOBJ options),
());
} ___device_stream_vtbl;
extern ___SCMOBJ ___device_stream_select_virt
___P((___device *self,
___BOOL for_writing,
int i,
int pass,
___device_select_state *state),
());
extern ___SCMOBJ ___device_stream_release_virt
___P((___device *self),
());
extern ___SCMOBJ ___device_stream_force_output_virt
___P((___device *self,
int level),
());
extern ___SCMOBJ ___device_stream_close_virt
___P((___device *self,
int direction),
());
extern ___SCMOBJ ___device_stream_seek
___P((___device_stream *self,
___stream_index *pos,
int whence),
());
extern ___SCMOBJ ___device_stream_read
___P((___device_stream *self,
___U8 *buf,
___stream_index len,
___stream_index *len_done),
());
extern ___SCMOBJ ___device_stream_write
___P((___device_stream *self,
___U8 *buf,
___stream_index len,
___stream_index *len_done),
());
extern ___SCMOBJ ___device_stream_setup
___P((___device_stream *dev,
___device_group *dgroup,
int direction,
int pumps_on),
());
extern ___SCMOBJ ___device_select
___P((___device **devs,
int nb_read_devs,
int nb_write_devs,
___time timeout),
());
extern void ___device_select_abort
___P((___processor_state ___ps),
());
extern ___SCMOBJ ___device_force_output
___P((___device *self,
int level),
());
extern ___SCMOBJ ___device_close
___P((___device *self,
int direction),
());
extern ___SCMOBJ ___device_cleanup
___P((___device *self),
());
extern ___SCMOBJ ___device_cleanup_from_ptr
___P((void *ptr),
());
/* - - - - - - - - - - - - - - - - - - */
/* Device operations. */
extern ___SCMOBJ ___os_device_kind
___P((___SCMOBJ dev),
());
extern ___SCMOBJ ___os_device_force_output
___P((___SCMOBJ dev_condvar,
___SCMOBJ level),
());
extern ___SCMOBJ ___os_device_close
___P((___SCMOBJ dev,
___SCMOBJ direction),
());
/* - - - - - - - - - - - - - - - - - - */
/* Stream device operations. */
extern ___SCMOBJ ___os_device_stream_seek
___P((___SCMOBJ dev_condvar,
___SCMOBJ pos,
___SCMOBJ whence),
());
extern ___SCMOBJ ___os_device_stream_read
___P((___SCMOBJ dev_condvar,
___SCMOBJ buffer,
___SCMOBJ lo,
___SCMOBJ hi),
());
extern ___SCMOBJ ___os_device_stream_write
___P((___SCMOBJ dev_condvar,
___SCMOBJ buffer,
___SCMOBJ lo,
___SCMOBJ hi),
());
extern ___SCMOBJ ___os_device_stream_width
___P((___SCMOBJ dev_condvar),
());
extern ___SCMOBJ ___os_device_stream_default_options
___P((___SCMOBJ dev),
());
extern ___SCMOBJ ___os_device_stream_options_set
___P((___SCMOBJ dev,
___SCMOBJ options),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening a predefined device (stdin, stdout, stderr, console, etc). */
extern ___SCMOBJ ___os_device_stream_open_predefined
___P((___SCMOBJ index,
___SCMOBJ flags),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening a path. */
extern ___SCMOBJ ___os_device_stream_open_path
___P((___SCMOBJ path,
___SCMOBJ flags,
___SCMOBJ mode),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening a process. */
extern ___SCMOBJ ___os_device_stream_open_process
___P((___SCMOBJ path_and_args,
___SCMOBJ environment,
___SCMOBJ directory,
___SCMOBJ options),
());
extern ___SCMOBJ ___os_device_process_pid
___P((___SCMOBJ dev),
());
extern ___SCMOBJ ___os_device_process_status
___P((___SCMOBJ dev),
());
extern void ___cleanup_child_interrupt_handling ___PVOID;
/* - - - - - - - - - - - - - - - - - - */
/* Opening a TCP client. */
extern ___SCMOBJ ___os_device_tcp_client_open
___P((___SCMOBJ server_addr,
___SCMOBJ port_num,
___SCMOBJ options,
___SCMOBJ tls_context),
());
extern ___SCMOBJ ___os_device_tcp_client_socket_info
___P((___SCMOBJ dev_condvar,
___SCMOBJ peer),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening and reading a TCP server. */
extern ___SCMOBJ ___os_device_tcp_server_open
___P((___SCMOBJ server_addr,
___SCMOBJ port_num,
___SCMOBJ backlog,
___SCMOBJ options,
___SCMOBJ tls_context),
());
extern ___SCMOBJ ___os_device_tcp_server_read
___P((___SCMOBJ dev_condvar),
());
extern ___SCMOBJ ___os_device_tcp_server_socket_info
___P((___SCMOBJ dev_condvar),
());
/* - - - - - - - - - - - - - - - - - - */
/* TLS context. */
extern ___SCMOBJ ___os_make_tls_context
___P((___SCMOBJ min_tls_version,
___SCMOBJ options,
___SCMOBJ certificate_path,
___SCMOBJ private_key_path,
___SCMOBJ dh_params_path,
___SCMOBJ elliptic_curve_name,
___SCMOBJ client_ca_path),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening and reading a directory. */
extern ___SCMOBJ ___os_device_directory_open_path
___P((___SCMOBJ path,
___SCMOBJ ignore_hidden),
());
extern ___SCMOBJ ___os_device_directory_read
___P((___SCMOBJ dev_condvar),
());
/* - - - - - - - - - - - - - - - - - - */
/* Opening an event-queue. */
extern ___SCMOBJ ___os_device_event_queue_open
___P((___SCMOBJ index),
());
extern ___SCMOBJ ___os_device_event_queue_read
___P((___SCMOBJ dev_condvar),
());
/* Opening a raw device (file descriptor) */
extern ___SCMOBJ ___os_device_raw_open_from_fd
___P((___SCMOBJ fd,
___SCMOBJ flags),
());
/* - - - - - - - - - - - - - - - - - - */
/* Waiting for I/O to become possible on a set of devices. */
extern ___SCMOBJ ___os_condvar_select
___P((___SCMOBJ devices,
___SCMOBJ timeout),
());
/* - - - - - - - - - - - - - - - - - - */
/*
* Decoding and encoding of a buffer of Scheme characters to a buffer
* of bytes.
*/
extern ___SCMOBJ ___os_port_decode_chars
___P((___SCMOBJ port,
___SCMOBJ want,
___SCMOBJ eof),
());
extern ___SCMOBJ ___os_port_encode_chars
___P((___SCMOBJ port),
());
/*---------------------------------------------------------------------------*/
/* I/O module initialization/finalization. */
extern ___SCMOBJ ___setup_io_pstate
___P((___processor_state ___ps),
());
extern void ___cleanup_io_pstate
___P((___processor_state ___ps),
());
extern ___SCMOBJ ___setup_io_vmstate
___P((___virtual_machine_state ___vms),
());
extern void ___cleanup_io_vmstate
___P((___virtual_machine_state ___vms),
());
extern ___SCMOBJ ___setup_io_module ___PVOID;
extern void ___cleanup_io_module ___PVOID;
/*---------------------------------------------------------------------------*/
#endif