1 /**
2 * D header file for C99 <stdio.h>
3 *
4 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdio.h.html, _stdio.h)
5 *
6 * Copyright: Copyright Sean Kelly 2005 - 2009.
7 * License: Distributed under the
8 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9 * (See accompanying file LICENSE)
10 * Authors: Sean Kelly,
11 * Alex Rønne Petersen
12 * Source: https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d
13 * Standards: ISO/IEC 9899:1999 (E)
14 */
15
16 module core.stdc.stdio;
17
18 version (OSX)
19 version = Darwin;
20 else version (iOS)
21 version = Darwin;
22 else version (TVOS)
23 version = Darwin;
24 else version (WatchOS)
25 version = Darwin;
26
27 private
28 {
29 import core.stdc.config;
30 import core.stdc.stdarg; // for va_list
31 import core.stdc.stdint : intptr_t;
32
version(FreeBSD)33 version (FreeBSD)
34 {
35 import core.sys.posix.sys.types;
36 }
version(OpenBSD)37 else version (OpenBSD)
38 {
39 import core.sys.posix.sys.types;
40 }
version(NetBSD)41 version (NetBSD)
42 {
43 import core.sys.posix.sys.types;
44 }
version(DragonFlyBSD)45 version (DragonFlyBSD)
46 {
47 import core.sys.posix.sys.types;
48 }
49 }
50
51 extern (C):
52 @system:
53 nothrow:
54 @nogc:
55
version(CRuntime_DigitalMars)56 version (CRuntime_DigitalMars)
57 {
58 enum
59 {
60 ///
61 BUFSIZ = 0x4000,
62 ///
63 EOF = -1,
64 ///
65 FOPEN_MAX = 20,
66 ///
67 FILENAME_MAX = 256, // 255 plus NULL
68 ///
69 TMP_MAX = 32767,
70 ///
71 SYS_OPEN = 20, // non-standard
72 }
73
74 ///
75 enum int _NFILE = 60; // non-standard
76 ///
77 enum string _P_tmpdir = "\\"; // non-standard
78 ///
79 enum wstring _wP_tmpdir = "\\"; // non-standard
80 ///
81 enum int L_tmpnam = _P_tmpdir.length + 12;
82 }
version(CRuntime_Microsoft)83 else version (CRuntime_Microsoft)
84 {
85 enum
86 {
87 ///
88 BUFSIZ = 512,
89 ///
90 EOF = -1,
91 ///
92 FOPEN_MAX = 20,
93 ///
94 FILENAME_MAX = 260,
95 /// Actually int.max since Visual Studio 2015.
96 TMP_MAX = 32767,
97 ///
98 _SYS_OPEN = 20, // non-standard
99 }
100
101 ///
102 enum int _NFILE = 512; // non-standard
103 /// Removed since Visual Studio 2015.
104 enum string _P_tmpdir = "\\"; // non-standard
105 /// Removed since Visual Studio 2015.
106 enum wstring _wP_tmpdir = "\\"; // non-standard
107 /// Actually 260 since Visual Studio 2015.
108 enum int L_tmpnam = _P_tmpdir.length + 12;
109 }
version(CRuntime_Glibc)110 else version (CRuntime_Glibc)
111 {
112 enum
113 {
114 ///
115 BUFSIZ = 8192,
116 ///
117 EOF = -1,
118 ///
119 FOPEN_MAX = 16,
120 ///
121 FILENAME_MAX = 4095,
122 ///
123 TMP_MAX = 238328,
124 ///
125 L_tmpnam = 20
126 }
127 }
128 else version (CRuntime_Musl)
129 {
130 enum
131 {
132 ///
133 BUFSIZ = 1024,
134 ///
135 EOF = -1,
136 ///
137 FOPEN_MAX = 1000,
138 ///
139 FILENAME_MAX = 4096,
140 ///
141 TMP_MAX = 10000,
142 ///
143 L_tmpnam = 20
144 }
145 }
146 else version (Darwin)
147 {
148 enum
149 {
150 ///
151 BUFSIZ = 1024,
152 ///
153 EOF = -1,
154 ///
155 FOPEN_MAX = 20,
156 ///
157 FILENAME_MAX = 1024,
158 ///
159 TMP_MAX = 308915776,
160 ///
161 L_tmpnam = 1024,
162 }
163
164 private
165 {
166 struct __sbuf
167 {
168 ubyte* _base;
169 int _size;
170 }
171
172 struct __sFILEX
173 {
174
175 }
176 }
177 }
178 else version (FreeBSD)
179 {
180 enum
181 {
182 ///
183 BUFSIZ = 1024,
184 ///
185 EOF = -1,
186 ///
187 FOPEN_MAX = 20,
188 ///
189 FILENAME_MAX = 1024,
190 ///
191 TMP_MAX = 308915776,
192 ///
193 L_tmpnam = 1024
194 }
195
196 struct __sbuf
197 {
198 ubyte *_base;
199 int _size;
200 }
201 }
202 else version (NetBSD)
203 {
204 enum
205 {
206 ///
207 BUFSIZ = 1024,
208 ///
209 EOF = -1,
210 ///
211 FOPEN_MAX = 20,
212 ///
213 FILENAME_MAX = 1024,
214 ///
215 TMP_MAX = 308915776,
216 ///
217 L_tmpnam = 1024
218 }
219
220 struct __sbuf
221 {
222 ubyte *_base;
223 int _size;
224 }
225 }
226 else version (OpenBSD)
227 {
228 enum
229 {
230 ///
231 BUFSIZ = 1024,
232 ///
233 EOF = -1,
234 ///
235 FOPEN_MAX = 20,
236 ///
237 FILENAME_MAX = 1024,
238 ///
239 TMP_MAX = 0x7fffffff,
240 ///
241 L_tmpnam = 1024
242 }
243
244 struct __sbuf
245 {
246 ubyte *_base;
247 int _size;
248 }
249 }
250 else version (DragonFlyBSD)
251 {
252 enum
253 {
254 BUFSIZ = 1024,
255 EOF = -1,
256 FOPEN_MAX = 20,
257 FILENAME_MAX = 1024,
258 TMP_MAX = 308915776,
259 L_tmpnam = 1024
260 }
261
262 struct __sbuf { // <sys/sbuf.h>
263 byte* s_buf; // storage buffer
264 int function(void *, const char *, int) sbuf_drain_func;
265 void* s_drain_arg; // user-supplied drain argument
266 int s_error; // current error code
267 ssize_t s_size; // size of storage buffer
268 ssize_t s_len; // current length of string
269 int s_flags; // flags
270 ssize_t s_sect_len; // current length of section
271 }
272
273 enum {
274 SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default)
275 SBUF_AUTOEXTEND = 0x00000001, // automatically extend buffer
276 SBUF_USRFLAGMSK = 0x0000ffff, // mask of flags the user may specify
277 SBUF_DYNAMIC = 0x00010000, // s_buf must be freed
278 SBUF_FINISHED = 0x00020000, // set by sbuf_finish()
279 SBUF_DYNSTRUCT = 0x00080000, // sbuf must be freed
280 SBUF_INSECTION = 0x00100000, // set by sbuf_start_section()
281 }
282 }
283 else version (Solaris)
284 {
285 enum
286 {
287 ///
288 BUFSIZ = 1024,
289 ///
290 EOF = -1,
291 ///
292 FOPEN_MAX = _NFILE,
293 ///
294 FILENAME_MAX = 1024,
295 ///
296 TMP_MAX = 17576,
297 ///
298 L_tmpnam = 25,
299 }
300
301 version (X86)
302 ///
303 enum int _NFILE = 60;
304 else
305 ///
306 enum int _NFILE = 20;
307 }
308 else version (CRuntime_Bionic)
309 {
310 enum
311 {
312 ///
313 BUFSIZ = 1024,
314 ///
315 EOF = -1,
316 ///
317 FOPEN_MAX = 20,
318 ///
319 FILENAME_MAX = 1024,
320 ///
321 TMP_MAX = 308915776,
322 ///
323 L_tmpnam = 1024
324 }
325
326 struct __sbuf
327 {
328 ubyte* _base;
329 int _size;
330 }
331 }
332 else version (CRuntime_UClibc)
333 {
334 enum
335 {
336 ///
337 BUFSIZ = 4096,
338 ///
339 EOF = -1,
340 ///
341 FOPEN_MAX = 16,
342 ///
343 FILENAME_MAX = 4095,
344 ///
345 TMP_MAX = 238328,
346 ///
347 L_tmpnam = 20
348 }
349 }
350 else
351 {
352 static assert( false, "Unsupported platform" );
353 }
354
355 enum
356 {
357 /// Offset is relative to the beginning
358 SEEK_SET,
359 /// Offset is relative to the current position
360 SEEK_CUR,
361 /// Offset is relative to the end
362 SEEK_END
363 }
364
365 version (CRuntime_DigitalMars)
366 {
367 ///
368 alias c_long fpos_t;
369
370 ///
371 struct _iobuf
372 {
373 char* _ptr;
374 int _cnt;
375 char* _base;
376 int _flag;
377 int _file;
378 int _charbuf;
379 int _bufsiz;
380 char* __tmpnum;
381 }
382
383 ///
384 alias shared(_iobuf) FILE;
385 }
386 else version (CRuntime_Microsoft)
387 {
388 ///
389 alias long fpos_t;
390
391 ///
392 struct _iobuf
393 {
394 void* undefined;
395 }
396
397 ///
398 alias shared(_iobuf) FILE;
399 }
400 else version (CRuntime_Glibc)
401 {
402 import core.stdc.wchar_ : mbstate_t;
403 ///
404 struct fpos_t
405 {
406 long __pos; // couldn't use off_t because of static if issue
407 mbstate_t __state;
408 }
409
410 ///
411 struct _IO_FILE
412 {
413 int _flags;
414 char* _read_ptr;
415 char* _read_end;
416 char* _read_base;
417 char* _write_base;
418 char* _write_ptr;
419 char* _write_end;
420 char* _buf_base;
421 char* _buf_end;
422 char* _save_base;
423 char* _backup_base;
424 char* _save_end;
425 void* _markers;
426 _IO_FILE* _chain;
427 int _fileno;
428 int _flags2;
429 ptrdiff_t _old_offset;
430 ushort _cur_column;
431 byte _vtable_offset;
432 char[1] _shortbuf = 0;
433 void* _lock;
434
435 ptrdiff_t _offset;
436
437 /*_IO_codecvt*/ void* _codecvt;
438 /*_IO_wide_data*/ void* _wide_data;
439 _IO_FILE *_freeres_list;
440 void *_freeres_buf;
441 size_t __pad5;
442 int _mode;
443
444 char[15 * int.sizeof - 4 * (void*).sizeof - size_t.sizeof] _unused2;
445 }
446
447 ///
448 alias _IO_FILE _iobuf;
449 ///
450 alias shared(_IO_FILE) FILE;
451 }
452 else version (CRuntime_Musl)
453 {
454 union fpos_t
455 {
456 char[16] __opaque = 0;
457 double __align;
458 }
459 struct _IO_FILE;
460
461 ///
462 alias _IO_FILE _iobuf; // needed for phobos
463 ///
464 alias shared(_IO_FILE) FILE;
465 }
466 else version (Darwin)
467 {
468 ///
469 alias long fpos_t;
470
471 ///
472 struct __sFILE
473 {
474 ubyte* _p;
475 int _r;
476 int _w;
477 short _flags;
478 short _file;
479 __sbuf _bf;
480 int _lbfsize;
481
482 void* _cookie;
483 int function(void*) _close;
484 int function(void*, char*, int) _read;
485 fpos_t function(void*, fpos_t, int) _seek;
486 int function(void*, char *, int) _write;
487
488 __sbuf _ub;
489 __sFILEX* _extra;
490 int _ur;
491
492 ubyte[3] _ubuf;
493 ubyte[1] _nbuf;
494
495 __sbuf _lb;
496
497 int _blksize;
498 fpos_t _offset;
499 }
500
501 ///
502 alias __sFILE _iobuf;
503 ///
504 alias shared(__sFILE) FILE;
505 }
506 else version (FreeBSD)
507 {
508 // Need to import wchar_ now since __mbstate_t now resides there
509 import core.stdc.wchar_ : mbstate_t;
510
511 ///
512 alias off_t fpos_t;
513
514 ///
515 struct __sFILE
516 {
517 ubyte* _p;
518 int _r;
519 int _w;
520 short _flags;
521 short _file;
522 __sbuf _bf;
523 int _lbfsize;
524
525 void* _cookie;
526 int function(void*) _close;
527 int function(void*, char*, int) _read;
528 fpos_t function(void*, fpos_t, int) _seek;
529 int function(void*, const scope char*, int) _write;
530
531 __sbuf _ub;
532 ubyte* _up;
533 int _ur;
534
535 ubyte[3] _ubuf;
536 ubyte[1] _nbuf;
537
538 __sbuf _lb;
539
540 int _blksize;
541 fpos_t _offset;
542
543 pthread_mutex_t _fl_mutex;
544 pthread_t _fl_owner;
545 int _fl_count;
546 int _orientation;
547 mbstate_t _mbstate;
548 }
549
550 ///
551 alias __sFILE _iobuf;
552 ///
553 alias shared(__sFILE) FILE;
554 }
555 else version (NetBSD)
556 {
557 ///
558 alias off_t fpos_t;
559
560 ///
561 struct __sFILE
562 {
563 ubyte* _p;
564 int _r;
565 int _w;
566 ushort _flags;
567 short _file;
568 __sbuf _bf;
569 int _lbfsize;
570
571 void* _cookie;
572 int function(void*) _close;
573 ssize_t function(void*, char*, size_t) _read;
574 fpos_t function(void*, fpos_t, int) _seek;
575 ssize_t function(void*, const scope char*, size_t) _write;
576
577 __sbuf _ub;
578 ubyte* _up;
579 int _ur;
580
581 ubyte[3] _ubuf;
582 ubyte[1] _nbuf;
583
584 int function(void *) _flush;
585 /* Formerly used by fgetln/fgetwln; kept for binary compatibility */
586 char[__sbuf.sizeof - _flush.sizeof] _lb_unused = void;
587
588
589 int _blksize;
590 off_t _offset;
591 static assert(off_t.sizeof==8);
592 }
593
594 ///
595 alias __sFILE _iobuf;
596 ///
597 alias shared(__sFILE) FILE;
598 }
599 else version (OpenBSD)
600 {
601 ///
602 alias fpos_t = off_t;
603
604 ///
605 struct __sFILE
606 {
607 ubyte* _p;
608 int _r;
609 int _w;
610 short _flags;
611 short _file;
612 __sbuf _bf;
613 int _lbfsize;
614
615 void* _cookie;
616 int function(void*) _close;
617 int function(void*, scope char*, int) _read;
618 fpos_t function(void*, fpos_t, int) _seek;
619 int function(void*, scope const char*, int) _write;
620
621 __sbuf _ext;
622 ubyte* _up;
623 int _ur;
624
625 ubyte[3] _ubuf;
626 ubyte[1] _nbuf;
627
628 __sbuf _lb;
629
630 int _blksize;
631 fpos_t _offset;
632 }
633
634 ///
635 alias __sFILE _iobuf;
636 ///
637 alias shared(__sFILE) FILE;
638 }
639 else version (DragonFlyBSD)
640 {
641 alias off_t fpos_t;
642
643 /// See /usr/include/stdio.h
644 struct __FILE_public
645 {
646 ubyte* *_p; /* current position in (some) buffer */
647 int _flags; /* flags, below; this FILE is free if 0 */
648 int _fileno; /* fileno, if Unix descriptor, else -1 */
649 ssize_t _r; /* read space left for getc() */
650 ssize_t _w; /* write space left for putc() */
651 ssize_t _lbfsize; /* 0 or -_bf._size, for inline putc */
652 }
653
654 alias __FILE_public _iobuf;
655 alias shared(__FILE_public) FILE;
656 }
657 else version (Solaris)
658 {
659 import core.stdc.wchar_ : mbstate_t;
660
661 ///
662 alias c_long fpos_t;
663
664 version (D_LP64)
665 {
666 ///
667 struct _iobuf
668 {
669 char* _ptr; /* next character from/to here in buffer */
670 char* _base; /* the buffer */
671 char* _end; /* the end of the buffer */
672 size_t _cnt; /* number of available characters in buffer */
673 int _file; /* UNIX System file descriptor */
674 int _flag; /* the state of the stream */
675 ubyte[24] _lock; //rmutex_t _lock; /* lock for this structure */
676 mbstate_t _state; /* mbstate_t */
677 ubyte[32] __fill; /* filler to bring size to 128 bytes */
678 }
679 }
680 else
681 {
682 ///
683 struct _iobuf
684 {
685 char* _ptr;
686 int _cnt;
687 char* _base;
688 char _flag = 0;
689 char _magic = 0;
690 ushort __flags; // __orientation:2
691 // __ionolock:1
692 // __seekable:1
693 // __extendedfd:1
694 // __xf_nocheck:1
695 // __filler:10
696 }
697 }
698 ///
699 alias shared(_iobuf) FILE;
700 }
701 else version (CRuntime_Bionic)
702 {
703 ///
704 alias c_long fpos_t; // couldn't use off_t because of static if issue
705
706 ///
707 struct __sFILE
708 {
709 ubyte* _p;
710 int _r;
711 int _w;
712 short _flags;
713 short _file;
714 __sbuf _bf;
715 int _lbfsize;
716
717 void* _cookie;
718 int function(void*) _close;
719 int function(void*, scope char*, int) _read;
720 fpos_t function(void*, fpos_t, int) _seek;
721 int function(void*, scope const char*, int) _write;
722
723 __sbuf _ext;
724 ubyte* _up;
725 int _ur;
726
727 ubyte[3] _ubuf;
728 ubyte[1] _nbuf;
729
730 __sbuf _lb;
731
732 int _blksize;
733 fpos_t _offset;
734 }
735
736 ///
737 alias __sFILE _iobuf;
738 ///
739 alias shared(__sFILE) FILE;
740 }
741 else version (CRuntime_UClibc)
742 {
743 import core.stdc.wchar_ : mbstate_t;
744 import core.stdc.stddef : wchar_t;
745 import core.sys.posix.sys.types : ssize_t, pthread_mutex_t;
746
747 ///
748 struct fpos_t
749 {
750 long __pos; // couldn't use off_t because of static if issue
751 mbstate_t __state;
752 int __mblen_pending;
753 }
754
755 struct _IO_cookie_io_functions_t
756 {
757 ssize_t function(void* __cookie, char* __buf, size_t __bufsize) read;
758 ssize_t function(void* __cookie, const char* __buf, size_t __bufsize) write;
759 int function(void* __cookie, long* __pos, int __whence) seek;
760 int function(void* __cookie) close;
761 }
762
763 alias _IO_cookie_io_functions_t cookie_io_functions_t;
764
765 ///
766 struct __STDIO_FILE_STRUCT
767 {
768 ushort __modeflags;
769 char[2] __ungot_width = 0;
770 int __filedes;
771 char* __bufstart;
772 char* __bufend;
773 char* __bufpos;
774 char* __bufread;
775 char* __bufgetc_u;
776 char*__bufputc_u;
777 __STDIO_FILE_STRUCT* __nextopen;
778 void *__cookie;
779 _IO_cookie_io_functions_t __gcs;
780 wchar_t[2] __ungot = 0;
781 mbstate_t __state;
782 void *__unused;
783 int __user_locking;
784 pthread_mutex_t __lock;
785 }
786
787 ///
788 alias __STDIO_FILE_STRUCT _iobuf;
789 ///
790 alias shared(__STDIO_FILE_STRUCT) FILE;
791 }
792 else
793 {
794 static assert( false, "Unsupported platform" );
795 }
796
797 enum
798 {
799 ///
800 _F_RDWR = 0x0003, // non-standard
801 ///
802 _F_READ = 0x0001, // non-standard
803 ///
804 _F_WRIT = 0x0002, // non-standard
805 ///
806 _F_BUF = 0x0004, // non-standard
807 ///
808 _F_LBUF = 0x0008, // non-standard
809 ///
810 _F_ERR = 0x0010, // non-standard
811 ///
812 _F_EOF = 0x0020, // non-standard
813 ///
814 _F_BIN = 0x0040, // non-standard
815 ///
816 _F_IN = 0x0080, // non-standard
817 ///
818 _F_OUT = 0x0100, // non-standard
819 ///
820 _F_TERM = 0x0200, // non-standard
821 }
822
823 version (CRuntime_DigitalMars)
824 {
825 enum
826 {
827 ///
828 _IOFBF = 0,
829 ///
830 _IOLBF = 0x40,
831 ///
832 _IONBF = 4,
833 ///
834 _IOREAD = 1, // non-standard
835 ///
836 _IOWRT = 2, // non-standard
837 ///
838 _IOMYBUF = 8, // non-standard
839 ///
840 _IOEOF = 0x10, // non-standard
841 ///
842 _IOERR = 0x20, // non-standard
843 ///
844 _IOSTRG = 0x40, // non-standard
845 ///
846 _IORW = 0x80, // non-standard
847 ///
848 _IOTRAN = 0x100, // non-standard
849 ///
850 _IOAPP = 0x200, // non-standard
851 }
852
853 extern shared void function() _fcloseallp;
854
855 private extern shared FILE[_NFILE] _iob;
856
857 ///
858 enum stdin = &_iob[0];
859 ///
860 enum stdout = &_iob[1];
861 ///
862 enum stderr = &_iob[2];
863 ///
864 enum stdaux = &_iob[3];
865 ///
866 enum stdprn = &_iob[4];
867 }
868 else version (CRuntime_Microsoft)
869 {
870 enum
871 {
872 ///
873 _IOFBF = 0,
874 ///
875 _IOLBF = 0x40,
876 ///
877 _IONBF = 4,
878 /// Removed since Visual Studio 2015.
879 _IOREAD = 1, // non-standard
880 /// Removed since Visual Studio 2015.
881 _IOWRT = 2, // non-standard
882 /// Removed since Visual Studio 2015.
883 _IOMYBUF = 8, // non-standard
884 /// Removed since Visual Studio 2015.
885 _IOEOF = 0x10, // non-standard
886 /// Removed since Visual Studio 2015.
887 _IOERR = 0x20, // non-standard
888 /// Removed since Visual Studio 2015.
889 _IOSTRG = 0x40, // non-standard
890 /// Removed since Visual Studio 2015.
891 _IORW = 0x80, // non-standard
892 /// Removed since Visual Studio 2015.
893 _IOAPP = 0x200, // non-standard
894 /// Removed since Visual Studio 2015.
895 _IOAPPEND = 0x200, // non-standard
896 }
897
898 extern shared void function() _fcloseallp;
899
900 FILE* __acrt_iob_func(int hnd); // VS2015+, reimplemented in msvc.d for VS2013-
901
902 ///
903 FILE* stdin()() { return __acrt_iob_func(0); }
904 ///
905 FILE* stdout()() { return __acrt_iob_func(1); }
906 ///
907 FILE* stderr()() { return __acrt_iob_func(2); }
908 }
909 else version (CRuntime_Glibc)
910 {
911 enum
912 {
913 ///
914 _IOFBF = 0,
915 ///
916 _IOLBF = 1,
917 ///
918 _IONBF = 2,
919 }
920
921 ///
922 extern shared FILE* stdin;
923 ///
924 extern shared FILE* stdout;
925 ///
926 extern shared FILE* stderr;
927 }
928 else version (Darwin)
929 {
930 enum
931 {
932 ///
933 _IOFBF = 0,
934 ///
935 _IOLBF = 1,
936 ///
937 _IONBF = 2,
938 }
939
940 private extern shared FILE* __stdinp;
941 private extern shared FILE* __stdoutp;
942 private extern shared FILE* __stderrp;
943
944 ///
945 alias __stdinp stdin;
946 ///
947 alias __stdoutp stdout;
948 ///
949 alias __stderrp stderr;
950 }
951 else version (FreeBSD)
952 {
953 enum
954 {
955 ///
956 _IOFBF = 0,
957 ///
958 _IOLBF = 1,
959 ///
960 _IONBF = 2,
961 }
962
963 private extern shared FILE* __stdinp;
964 private extern shared FILE* __stdoutp;
965 private extern shared FILE* __stderrp;
966
967 ///
968 alias __stdinp stdin;
969 ///
970 alias __stdoutp stdout;
971 ///
972 alias __stderrp stderr;
973 }
974 else version (NetBSD)
975 {
976 enum
977 {
978 ///
979 _IOFBF = 0,
980 ///
981 _IOLBF = 1,
982 ///
983 _IONBF = 2,
984 }
985
986 private extern shared FILE[3] __sF;
987 @property auto __stdin()() { return &__sF[0]; }
988 @property auto __stdout()() { return &__sF[1]; }
989 @property auto __stderr()() { return &__sF[2]; }
990 ///
991 alias __stdin stdin;
992 ///
993 alias __stdout stdout;
994 ///
995 alias __stderr stderr;
996 }
997 else version (OpenBSD)
998 {
999 enum
1000 {
1001 ///
1002 _IOFBF = 0,
1003 ///
1004 _IOLBF = 1,
1005 ///
1006 _IONBF = 2,
1007 }
1008
1009 private extern shared FILE[3] __sF;
1010 @property auto __stdin()() { return &__sF[0]; }
1011 @property auto __stdout()() { return &__sF[1]; }
1012 @property auto __stderr()() { return &__sF[2]; }
1013 ///
1014 alias __stdin stdin;
1015 ///
1016 alias __stdout stdout;
1017 ///
1018 alias __stderr stderr;
1019 }
1020 else version (DragonFlyBSD)
1021 {
1022 enum
1023 {
1024 _IOFBF = 0,
1025 _IOLBF = 1,
1026 _IONBF = 2,
1027 }
1028
1029 private extern shared FILE* __stdinp;
1030 private extern shared FILE* __stdoutp;
1031 private extern shared FILE* __stderrp;
1032
1033 alias __stdinp stdin;
1034 alias __stdoutp stdout;
1035 alias __stderrp stderr;
1036 }
1037 else version (Solaris)
1038 {
1039 enum
1040 {
1041 ///
1042 _IOFBF = 0x00,
1043 ///
1044 _IOLBF = 0x40,
1045 ///
1046 _IONBF = 0x04,
1047 ///
1048 _IOEOF = 0x20,
1049 ///
1050 _IOERR = 0x40,
1051 ///
1052 _IOREAD = 0x01,
1053 ///
1054 _IOWRT = 0x02,
1055 ///
1056 _IORW = 0x80,
1057 ///
1058 _IOMYBUF = 0x08,
1059 }
1060
1061 private extern shared FILE[_NFILE] __iob;
1062
1063 ///
1064 @property auto stdin()() { return &__iob[0]; }
1065 ///
1066 @property auto stdout()() { return &__iob[1]; }
1067 ///
1068 @property auto stderr()() { return &__iob[2]; }
1069 }
1070 else version (CRuntime_Bionic)
1071 {
1072 enum
1073 {
1074 ///
1075 _IOFBF = 0,
1076 ///
1077 _IOLBF = 1,
1078 ///
1079 _IONBF = 2,
1080 }
1081
1082 private extern shared FILE[3] __sF;
1083
1084 ///
1085 @property auto stdin()() { return &__sF[0]; }
1086 ///
1087 @property auto stdout()() { return &__sF[1]; }
1088 ///
1089 @property auto stderr()() { return &__sF[2]; }
1090 }
1091 else version (CRuntime_Musl)
1092 {
1093 // needs tail const
1094 extern shared FILE* stdin;
1095 ///
1096 extern shared FILE* stdout;
1097 ///
1098 extern shared FILE* stderr;
1099 enum
1100 {
1101 ///
1102 _IOFBF = 0,
1103 ///
1104 _IOLBF = 1,
1105 ///
1106 _IONBF = 2,
1107 }
1108 }
1109 else version (CRuntime_UClibc)
1110 {
1111 enum
1112 {
1113 ///
1114 _IOFBF = 0,
1115 ///
1116 _IOLBF = 1,
1117 ///
1118 _IONBF = 2,
1119 }
1120
1121 ///
1122 extern shared FILE* stdin;
1123 ///
1124 extern shared FILE* stdout;
1125 ///
1126 extern shared FILE* stderr;
1127 }
1128 else
1129 {
1130 static assert( false, "Unsupported platform" );
1131 }
1132
1133 ///
1134 int remove(scope const char* filename);
1135 ///
1136 int rename(scope const char* from, scope const char* to);
1137
1138 ///
1139 @trusted FILE* tmpfile(); // No unsafe pointer manipulation.
1140 ///
1141 char* tmpnam(char* s);
1142
1143 ///
1144 int fclose(FILE* stream);
1145
1146 // No unsafe pointer manipulation.
1147 @trusted
1148 {
1149 ///
1150 int fflush(FILE* stream);
1151 }
1152
1153 ///
1154 FILE* fopen(scope const char* filename, scope const char* mode);
1155 ///
1156 FILE* freopen(scope const char* filename, scope const char* mode, FILE* stream);
1157
1158 ///
1159 void setbuf(FILE* stream, char* buf);
1160 ///
1161 int setvbuf(FILE* stream, char* buf, int mode, size_t size);
1162
1163 version (MinGW)
1164 {
1165 // Prefer the MinGW versions over the MSVC ones, as the latter don't handle
1166 // reals at all.
1167 ///
1168 pragma(printf)
1169 int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...);
1170 ///
1171 alias __mingw_fprintf fprintf;
1172
1173 ///
1174 pragma(scanf)
1175 int __mingw_fscanf(FILE* stream, scope const char* format, scope ...);
1176 ///
1177 alias __mingw_fscanf fscanf;
1178
1179 ///
1180 pragma(printf)
1181 int __mingw_sprintf(scope char* s, scope const char* format, scope const ...);
1182 ///
1183 alias __mingw_sprintf sprintf;
1184
1185 ///
1186 pragma(scanf)
1187 int __mingw_sscanf(scope const char* s, scope const char* format, scope ...);
1188 ///
1189 alias __mingw_sscanf sscanf;
1190
1191 ///
1192 pragma(printf)
1193 int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg);
1194 ///
1195 alias __mingw_vfprintf vfprintf;
1196
1197 ///
1198 pragma(scanf)
1199 int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg);
1200 ///
1201 alias __mingw_vfscanf vfscanf;
1202
1203 ///
1204 pragma(printf)
1205 int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg);
1206 ///
1207 alias __mingw_vsprintf vsprintf;
1208
1209 ///
1210 pragma(scanf)
1211 int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg);
1212 ///
1213 alias __mingw_vsscanf vsscanf;
1214
1215 ///
1216 pragma(printf)
1217 int __mingw_vprintf(scope const char* format, va_list arg);
1218 ///
1219 alias __mingw_vprintf vprintf;
1220
1221 ///
1222 pragma(scanf)
1223 int __mingw_vscanf(scope const char* format, va_list arg);
1224 ///
1225 alias __mingw_vscanf vscanf;
1226
1227 ///
1228 pragma(printf)
1229 int __mingw_printf(scope const char* format, scope const ...);
1230 ///
1231 alias __mingw_printf printf;
1232
1233 ///
1234 pragma(scanf)
1235 int __mingw_scanf(scope const char* format, scope ...);
1236 ///
1237 alias __mingw_scanf scanf;
1238 }
1239 else
1240 {
1241 ///
1242 pragma(printf)
1243 int fprintf(FILE* stream, scope const char* format, scope const ...);
1244 ///
1245 pragma(scanf)
1246 int fscanf(FILE* stream, scope const char* format, scope ...);
1247 ///
1248 pragma(printf)
1249 int sprintf(scope char* s, scope const char* format, scope const ...);
1250 ///
1251 pragma(scanf)
1252 int sscanf(scope const char* s, scope const char* format, scope ...);
1253 ///
1254 pragma(printf)
1255 int vfprintf(FILE* stream, scope const char* format, va_list arg);
1256 ///
1257 pragma(scanf)
1258 int vfscanf(FILE* stream, scope const char* format, va_list arg);
1259 ///
1260 pragma(printf)
1261 int vsprintf(scope char* s, scope const char* format, va_list arg);
1262 ///
1263 pragma(scanf)
1264 int vsscanf(scope const char* s, scope const char* format, va_list arg);
1265 ///
1266 pragma(printf)
1267 int vprintf(scope const char* format, va_list arg);
1268 ///
1269 pragma(scanf)
1270 int vscanf(scope const char* format, va_list arg);
1271 ///
1272 pragma(printf)
1273 int printf(scope const char* format, scope const ...);
1274 ///
1275 pragma(scanf)
1276 int scanf(scope const char* format, scope ...);
1277 }
1278
1279 // No unsafe pointer manipulation.
1280 @trusted
1281 {
1282 ///
1283 int fgetc(FILE* stream);
1284 ///
1285 int fputc(int c, FILE* stream);
1286 }
1287
1288 ///
1289 char* fgets(char* s, int n, FILE* stream);
1290 ///
1291 int fputs(scope const char* s, FILE* stream);
1292 ///
1293 char* gets(char* s);
1294 ///
1295 int puts(scope const char* s);
1296
1297 // No unsafe pointer manipulation.
1298 extern (D) @trusted
1299 {
1300 ///
1301 int getchar()() { return getc(stdin); }
1302 ///
1303 int putchar()(int c) { return putc(c,stdout); }
1304 }
1305
1306 ///
1307 alias getc = fgetc;
1308 ///
1309 alias putc = fputc;
1310
1311 ///
1312 @trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation.
1313
1314 ///
1315 size_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream);
1316 ///
1317 size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream);
1318
1319 // No unsafe pointer manipulation.
1320 @trusted
1321 {
1322 ///
1323 int fgetpos(FILE* stream, scope fpos_t * pos);
1324 ///
1325 int fsetpos(FILE* stream, scope const fpos_t* pos);
1326
1327 ///
1328 int fseek(FILE* stream, c_long offset, int whence);
1329 ///
1330 c_long ftell(FILE* stream);
1331 }
1332
1333 version (CRuntime_DigitalMars)
1334 {
1335 // No unsafe pointer manipulation.
1336 extern (D) @trusted
1337 {
1338 ///
1339 void rewind()(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; }
1340 ///
1341 pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }
1342 ///
1343 pure int feof()(FILE* stream) { return stream._flag&_IOEOF; }
1344 ///
1345 pure int ferror()(FILE* stream) { return stream._flag&_IOERR; }
1346 ///
1347 pure int fileno()(FILE* stream) { return stream._file; }
1348 }
1349 ///
1350 pragma(printf)
1351 int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
1352 ///
1353 alias _snprintf snprintf;
1354
1355 ///
1356 pragma(printf)
1357 int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1358 ///
1359 alias _vsnprintf vsnprintf;
1360
1361 //
1362 // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the
1363 // unshared version of FILE*, usable when the FILE is locked.
1364 //
1365
1366 ///
1367 int _fputc_nlock(int c, _iobuf* fp);
1368 ///
1369 int _fputwc_nlock(int c, _iobuf* fp);
1370 ///
1371 int _fgetc_nlock(_iobuf* fp);
1372 ///
1373 int _fgetwc_nlock(_iobuf* fp);
1374 ///
1375 int __fp_lock(FILE* fp);
1376 ///
1377 void __fp_unlock(FILE* fp);
1378 ///
1379 int setmode(int fd, int mode);
1380 }
1381 else version (CRuntime_Microsoft)
1382 {
1383 // No unsafe pointer manipulation.
1384 @trusted
1385 {
1386 ///
1387 void rewind(FILE* stream);
1388 ///
1389 pure void clearerr(FILE* stream);
1390 ///
1391 pure int feof(FILE* stream);
1392 ///
1393 pure int ferror(FILE* stream);
1394 ///
1395 pure int fileno(FILE* stream);
1396 }
1397
1398 version (MinGW)
1399 {
1400 pragma(printf)
1401 int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...);
1402 ///
1403 alias __mingw_snprintf _snprintf;
1404 ///
1405 alias __mingw_snprintf snprintf;
1406
1407 ///
1408 pragma(printf)
1409 int __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1410 ///
1411 alias __mingw_vsnprintf _vsnprintf;
1412 ///
1413 alias __mingw_vsnprintf vsnprintf;
1414 }
1415 else
1416 {
1417 ///
1418 pragma(printf)
1419 int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1420 ///
1421 pragma(printf)
1422 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1423
1424 ///
1425 pragma(printf)
1426 int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1427 ///
1428 pragma(printf)
1429 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1430 }
1431
1432 //
1433 // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared
1434 // version of FILE*, usable when the FILE is locked.
1435 //
1436 import core.stdc.stddef : wchar_t;
1437 import core.stdc.wchar_ : wint_t;
1438
1439 ///
1440 int _fputc_nolock(int c, _iobuf* fp);
1441 ///
1442 int _fgetc_nolock(_iobuf* fp);
1443 ///
1444 wint_t _fputwc_nolock(wchar_t c, _iobuf* fp);
1445 ///
1446 wint_t _fgetwc_nolock(_iobuf* fp);
1447 ///
1448 void _lock_file(FILE* fp);
1449 ///
1450 void _unlock_file(FILE* fp);
1451 ///
1452 int _setmode(int fd, int mode);
1453 ///
1454 int _fseeki64(FILE* stream, long offset, int origin);
1455 ///
1456 long _ftelli64(FILE* stream);
1457 ///
1458 intptr_t _get_osfhandle(int fd);
1459 ///
1460 int _open_osfhandle(intptr_t osfhandle, int flags);
1461 }
1462 else version (CRuntime_Glibc)
1463 {
1464 // No unsafe pointer manipulation.
1465 @trusted
1466 {
1467 ///
1468 void rewind(FILE* stream);
1469 ///
1470 pure void clearerr(FILE* stream);
1471 ///
1472 pure int feof(FILE* stream);
1473 ///
1474 pure int ferror(FILE* stream);
1475 ///
1476 int fileno(FILE *);
1477 }
1478
1479 ///
1480 pragma(printf)
1481 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1482 ///
1483 pragma(printf)
1484 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1485
1486 //
1487 // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared
1488 // version of FILE*, usable when the FILE is locked.
1489 // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html
1490 //
1491 import core.stdc.wchar_ : wint_t;
1492 import core.stdc.stddef : wchar_t;
1493
1494 ///
1495 int fputc_unlocked(int c, _iobuf* stream);
1496 ///
1497 int fgetc_unlocked(_iobuf* stream);
1498 ///
1499 wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream);
1500 ///
1501 wint_t fgetwc_unlocked(_iobuf* stream);
1502 }
1503 else version (Darwin)
1504 {
1505 // No unsafe pointer manipulation.
1506 @trusted
1507 {
1508 ///
1509 void rewind(FILE*);
1510 ///
1511 pure void clearerr(FILE*);
1512 ///
1513 pure int feof(FILE*);
1514 ///
1515 pure int ferror(FILE*);
1516 ///
1517 int fileno(FILE*);
1518 }
1519
1520 ///
1521 pragma(printf)
1522 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1523 ///
1524 pragma(printf)
1525 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1526 }
1527 else version (FreeBSD)
1528 {
1529 // No unsafe pointer manipulation.
1530 @trusted
1531 {
1532 ///
1533 void rewind(FILE*);
1534 ///
1535 pure void clearerr(FILE*);
1536 ///
1537 pure int feof(FILE*);
1538 ///
1539 pure int ferror(FILE*);
1540 ///
1541 int fileno(FILE*);
1542 }
1543
1544 ///
1545 pragma(printf)
1546 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1547 ///
1548 pragma(printf)
1549 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1550 }
1551 else version (NetBSD)
1552 {
1553 // No unsafe pointer manipulation.
1554 @trusted
1555 {
1556 ///
1557 void rewind(FILE*);
1558 ///
1559 pure void clearerr(FILE*);
1560 ///
1561 pure int feof(FILE*);
1562 ///
1563 pure int ferror(FILE*);
1564 ///
1565 int fileno(FILE*);
1566 }
1567
1568 ///
1569 pragma(printf)
1570 int snprintf(char* s, size_t n, const scope char* format, scope const ...);
1571 ///
1572 pragma(printf)
1573 int vsnprintf(char* s, size_t n, const scope char* format, va_list arg);
1574 }
1575 else version (OpenBSD)
1576 {
1577 // No unsafe pointer manipulation.
1578 @trusted
1579 {
1580 ///
1581 void rewind(FILE*);
1582 }
1583 @trusted private
1584 {
1585 ///
1586 pragma(mangle, "clearerr")
1587 pure void __clearerr(FILE*);
1588 ///
1589 pragma(mangle, "feof")
1590 pure int __feof(FILE*);
1591 ///
1592 pragma(mangle, "ferror")
1593 pure int __ferror(FILE*);
1594 ///
1595 pragma(mangle, "fileno")
1596 int __fileno(FILE*);
1597 }
1598
1599 enum __SLBF = 0x0001;
1600 enum __SNBF = 0x0002;
1601 enum __SRD = 0x0004;
1602 enum __SWR = 0x0008;
1603 enum __SRW = 0x0010;
1604 enum __SEOF = 0x0020;
1605 enum __SERR = 0x0040;
1606 enum __SMBF = 0x0080;
1607 enum __SAPP = 0x0100;
1608 enum __SSTR = 0x0200;
1609 enum __SOPT = 0x0400;
1610 enum __SNPT = 0x0800;
1611 enum __SOFF = 0x1000;
1612 enum __SMOD = 0x2000;
1613 enum __SALC = 0x4000;
1614 enum __SIGN = 0x8000;
1615
1616 extern immutable __gshared int __isthreaded;
1617
1618 extern (D) @trusted
1619 {
1620 void __sclearerr()(FILE* p)
1621 {
1622 p._flags = p._flags & ~(__SERR|__SEOF);
1623 }
1624
1625 int __sfeof()(FILE* p)
1626 {
1627 return (p._flags & __SEOF) != 0;
1628 }
1629
1630 int __sferror()(FILE* p)
1631 {
1632 return (p._flags & __SERR) != 0;
1633 }
1634
1635 int __sfileno()(FILE* p)
1636 {
1637 return p._file;
1638 }
1639
1640 pure void clearerr()(FILE* file)
1641 {
1642 !__isthreaded ? __sclearerr(file) : __clearerr(file);
1643 }
1644
1645 pure int feof()(FILE* file)
1646 {
1647 return !__isthreaded ? __sfeof(file) : __feof(file);
1648 }
1649
1650 pure int ferror()(FILE* file)
1651 {
1652 return !__isthreaded ? __sferror(file) : __ferror(file);
1653 }
1654
1655 int fileno()(FILE* file)
1656 {
1657 return !__isthreaded ? __sfileno(file) : __fileno(file);
1658 }
1659 }
1660
1661 ///
1662 pragma(printf)
1663 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1664 ///
1665 pragma(printf)
1666 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1667 }
1668 else version (DragonFlyBSD)
1669 {
1670 // No unsafe pointer manipulation.
1671 @trusted
1672 {
1673 void rewind(FILE*);
1674 pure void clearerr(FILE*);
1675 pure int feof(FILE*);
1676 pure int ferror(FILE*);
1677 int fileno(FILE*);
1678 }
1679 enum __SLBF = 0x0001;
1680 enum __SNBF = 0x0002;
1681 enum __SRD = 0x0004;
1682 enum __SWR = 0x0008;
1683 enum __SRW = 0x0010;
1684 enum __SEOF = 0x0020;
1685 enum __SERR = 0x0040;
1686 enum __SMBF = 0x0080;
1687 enum __SAPP = 0x0100;
1688 enum __SSTR = 0x0200;
1689 enum __SOPT = 0x0400;
1690 enum __SNPT = 0x0800;
1691 enum __SOFF = 0x1000;
1692 enum __SMOD = 0x2000;
1693 enum __SALC = 0x4000;
1694 enum __SIGN = 0x8000;
1695
1696 pragma(printf)
1697 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1698 pragma(printf)
1699 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1700 }
1701 else version (Solaris)
1702 {
1703 // No unsafe pointer manipulation.
1704 @trusted
1705 {
1706 ///
1707 void rewind(FILE*);
1708 ///
1709 pure void clearerr(FILE*);
1710 ///
1711 pure int feof(FILE*);
1712 ///
1713 pure int ferror(FILE*);
1714 ///
1715 int fileno(FILE*);
1716 }
1717
1718 ///
1719 pragma(printf)
1720 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1721 ///
1722 pragma(printf)
1723 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1724 }
1725 else version (CRuntime_Bionic)
1726 {
1727 // No unsafe pointer manipulation.
1728 @trusted
1729 {
1730 ///
1731 void rewind(FILE*);
1732 ///
1733 pure void clearerr(FILE*);
1734 ///
1735 pure int feof(FILE*);
1736 ///
1737 pure int ferror(FILE*);
1738 ///
1739 int fileno(FILE*);
1740 }
1741
1742 ///
1743 pragma(printf)
1744 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1745 ///
1746 pragma(printf)
1747 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1748 }
1749 else version (CRuntime_Musl)
1750 {
1751 @trusted
1752 {
1753 ///
1754 void rewind(FILE* stream);
1755 ///
1756 pure void clearerr(FILE* stream);
1757 ///
1758 pure int feof(FILE* stream);
1759 ///
1760 pure int ferror(FILE* stream);
1761 ///
1762 int fileno(FILE *);
1763 }
1764
1765 ///
1766 pragma(printf)
1767 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1768 ///
1769 pragma(printf)
1770 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1771 }
1772 else version (CRuntime_UClibc)
1773 {
1774 // No unsafe pointer manipulation.
1775 @trusted
1776 {
1777 ///
1778 void rewind(FILE* stream);
1779 ///
1780 pure void clearerr(FILE* stream);
1781 ///
1782 pure int feof(FILE* stream);
1783 ///
1784 pure int ferror(FILE* stream);
1785 ///
1786 int fileno(FILE *);
1787 }
1788
1789 ///
1790 pragma(printf)
1791 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...);
1792 ///
1793 pragma(printf)
1794 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1795 }
1796 else
1797 {
1798 static assert( false, "Unsupported platform" );
1799 }
1800
1801 ///
1802 void perror(scope const char* s);
1803
1804 version (CRuntime_DigitalMars)
1805 {
1806 version (none)
1807 import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore;
1808 else
1809 {
1810 // too slow to import windows
1811 private alias void* HANDLE;
1812 private void _WaitSemaphore(int iSemaphore);
1813 private void _ReleaseSemaphore(int iSemaphore);
1814 }
1815
1816 enum
1817 {
1818 ///
1819 FHND_APPEND = 0x04,
1820 ///
1821 FHND_DEVICE = 0x08,
1822 ///
1823 FHND_TEXT = 0x10,
1824 ///
1825 FHND_BYTE = 0x20,
1826 ///
1827 FHND_WCHAR = 0x40,
1828 }
1829
1830 private enum _MAX_SEMAPHORES = 10 + _NFILE;
1831 private enum _semIO = 3;
1832
1833 private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs;
1834 private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds;
1835 private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount;
1836 private extern __gshared HANDLE[_NFILE] _osfhnd;
1837 extern shared ubyte[_NFILE] __fhnd_info;
1838
1839 // this is copied from semlock.h in DMC's runtime.
1840 private void LockSemaphore()(uint num)
1841 {
1842 asm nothrow @nogc
1843 {
1844 mov EDX, num;
1845 lock;
1846 inc _iSemLockCtrs[EDX * 2];
1847 jz lsDone;
1848 push EDX;
1849 call _WaitSemaphore;
1850 add ESP, 4;
1851 }
1852
1853 lsDone: {}
1854 }
1855
1856 // this is copied from semlock.h in DMC's runtime.
1857 private void UnlockSemaphore()(uint num)
1858 {
1859 asm nothrow @nogc
1860 {
1861 mov EDX, num;
1862 lock;
1863 dec _iSemLockCtrs[EDX * 2];
1864 js usDone;
1865 push EDX;
1866 call _ReleaseSemaphore;
1867 add ESP, 4;
1868 }
1869
1870 usDone: {}
1871 }
1872
1873 // This converts a HANDLE to a file descriptor in DMC's runtime
1874 ///
1875 int _handleToFD()(HANDLE h, int flags)
1876 {
1877 LockSemaphore(_semIO);
1878 scope(exit) UnlockSemaphore(_semIO);
1879
1880 foreach (fd; 0 .. _NFILE)
1881 {
1882 if (!_osfhnd[fd])
1883 {
1884 _osfhnd[fd] = h;
1885 __fhnd_info[fd] = cast(ubyte)flags;
1886 return fd;
1887 }
1888 }
1889
1890 return -1;
1891 }
1892
1893 ///
1894 HANDLE _fdToHandle()(int fd)
1895 {
1896 // no semaphore is required, once inserted, a file descriptor
1897 // doesn't change.
1898 if (fd < 0 || fd >= _NFILE)
1899 return null;
1900
1901 return _osfhnd[fd];
1902 }
1903
1904 enum
1905 {
1906 ///
1907 STDIN_FILENO = 0,
1908 ///
1909 STDOUT_FILENO = 1,
1910 ///
1911 STDERR_FILENO = 2,
1912 }
1913
1914 int open(scope const(char)* filename, int flags, ...); ///
1915 alias _open = open; ///
1916 int _wopen(scope const wchar* filename, int oflag, ...); ///
1917 int sopen(scope const char* filename, int oflag, int shflag, ...); ///
1918 alias _sopen = sopen; ///
1919 int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///
1920 int close(int fd); ///
1921 alias _close = close; ///
1922 FILE *fdopen(int fd, scope const(char)* flags); ///
1923 alias _fdopen = fdopen; ///
1924 FILE *_wfdopen(int fd, scope const(wchar)* flags); ///
1925
1926 }
1927 else version (CRuntime_Microsoft)
1928 {
1929 int _open(scope const char* filename, int oflag, ...); ///
1930 int _wopen(scope const wchar* filename, int oflag, ...); ///
1931 int _sopen(scope const char* filename, int oflag, int shflag, ...); ///
1932 int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///
1933 int _close(int fd); ///
1934 FILE *_fdopen(int fd, scope const(char)* flags); ///
1935 FILE *_wfdopen(int fd, scope const(wchar)* flags); ///
1936 }
1937
1938 version (Windows)
1939 {
1940 // file open flags
1941 enum
1942 {
1943 _O_RDONLY = 0x0000, ///
1944 O_RDONLY = _O_RDONLY, ///
1945 _O_WRONLY = 0x0001, ///
1946 O_WRONLY = _O_WRONLY, ///
1947 _O_RDWR = 0x0002, ///
1948 O_RDWR = _O_RDWR, ///
1949 _O_APPEND = 0x0008, ///
1950 O_APPEND = _O_APPEND, ///
1951 _O_CREAT = 0x0100, ///
1952 O_CREAT = _O_CREAT, ///
1953 _O_TRUNC = 0x0200, ///
1954 O_TRUNC = _O_TRUNC, ///
1955 _O_EXCL = 0x0400, ///
1956 O_EXCL = _O_EXCL, ///
1957 _O_TEXT = 0x4000, ///
1958 O_TEXT = _O_TEXT, ///
1959 _O_BINARY = 0x8000, ///
1960 O_BINARY = _O_BINARY, ///
1961 _O_WTEXT = 0x10000, ///
1962 _O_U16TEXT = 0x20000, ///
1963 _O_U8TEXT = 0x40000, ///
1964 _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), ///
1965 O_ACCMODE = _O_ACCMODE, ///
1966 _O_RAW = _O_BINARY, ///
1967 O_RAW = _O_BINARY, ///
1968 _O_NOINHERIT = 0x0080, ///
1969 O_NOINHERIT = _O_NOINHERIT, ///
1970 _O_TEMPORARY = 0x0040, ///
1971 O_TEMPORARY = _O_TEMPORARY, ///
1972 _O_SHORT_LIVED = 0x1000, ///
1973 _O_SEQUENTIAL = 0x0020, ///
1974 O_SEQUENTIAL = _O_SEQUENTIAL, ///
1975 _O_RANDOM = 0x0010, ///
1976 O_RANDOM = _O_RANDOM, ///
1977 }
1978
1979 enum
1980 {
1981 _S_IREAD = 0x0100, /// read permission, owner
1982 S_IREAD = _S_IREAD, /// read permission, owner
1983 _S_IWRITE = 0x0080, /// write permission, owner
1984 S_IWRITE = _S_IWRITE, /// write permission, owner
1985 }
1986
1987 enum
1988 {
1989 _SH_DENYRW = 0x10, /// deny read/write mode
1990 SH_DENYRW = _SH_DENYRW, /// deny read/write mode
1991 _SH_DENYWR = 0x20, /// deny write mode
1992 SH_DENYWR = _SH_DENYWR, /// deny write mode
1993 _SH_DENYRD = 0x30, /// deny read mode
1994 SH_DENYRD = _SH_DENYRD, /// deny read mode
1995 _SH_DENYNO = 0x40, /// deny none mode
1996 SH_DENYNO = _SH_DENYNO, /// deny none mode
1997 }
1998 }
1999