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     _blksize;
429         int     _old_offset;
430         ushort  _cur_column;
431         byte    _vtable_offset;
432         char[1] _shortbuf = 0;
433         void*   _lock;
434     }
435 
436     ///
437     alias _IO_FILE _iobuf;
438     ///
439     alias shared(_IO_FILE) FILE;
440 }
441 else version (CRuntime_Musl)
442 {
443     union fpos_t
444     {
445         char[16] __opaque = 0;
446         double __align;
447     }
448     struct _IO_FILE;
449 
450     ///
451     alias _IO_FILE _iobuf; // needed for phobos
452     ///
453     alias shared(_IO_FILE) FILE;
454 }
455 else version (Darwin)
456 {
457     ///
458     alias long fpos_t;
459 
460     ///
461     struct __sFILE
462     {
463         ubyte*    _p;
464         int       _r;
465         int       _w;
466         short     _flags;
467         short     _file;
468         __sbuf    _bf;
469         int       _lbfsize;
470 
471         void*     _cookie;
472         int     function(void*)                    _close;
473         int     function(void*, char*, int)        _read;
474         fpos_t  function(void*, fpos_t, int)       _seek;
475         int     function(void*, char *, int)       _write;
476 
477         __sbuf    _ub;
478         __sFILEX* _extra;
479         int       _ur;
480 
481         ubyte[3]  _ubuf;
482         ubyte[1]  _nbuf;
483 
484         __sbuf    _lb;
485 
486         int       _blksize;
487         fpos_t    _offset;
488     }
489 
490     ///
491     alias __sFILE _iobuf;
492     ///
493     alias shared(__sFILE) FILE;
494 }
495 else version (FreeBSD)
496 {
497     // Need to import wchar_ now since __mbstate_t now resides there
498     import core.stdc.wchar_ : mbstate_t;
499 
500     ///
501     alias off_t fpos_t;
502 
503     ///
504     struct __sFILE
505     {
506         ubyte*          _p;
507         int             _r;
508         int             _w;
509         short           _flags;
510         short           _file;
511         __sbuf          _bf;
512         int             _lbfsize;
513 
514         void*           _cookie;
515         int     function(void*)                 _close;
516         int     function(void*, char*, int)     _read;
517         fpos_t  function(void*, fpos_t, int)    _seek;
518         int     function(void*, in char*, int)  _write;
519 
520         __sbuf          _ub;
521         ubyte*          _up;
522         int             _ur;
523 
524         ubyte[3]        _ubuf;
525         ubyte[1]        _nbuf;
526 
527         __sbuf          _lb;
528 
529         int             _blksize;
530         fpos_t          _offset;
531 
532         pthread_mutex_t _fl_mutex;
533         pthread_t       _fl_owner;
534         int             _fl_count;
535         int             _orientation;
536         mbstate_t       _mbstate;
537     }
538 
539     ///
540     alias __sFILE _iobuf;
541     ///
542     alias shared(__sFILE) FILE;
543 }
544 else version (NetBSD)
545 {
546     ///
547     alias off_t fpos_t;
548 
549     ///
550     struct __sFILE
551     {
552         ubyte*          _p;
553         int             _r;
554         int             _w;
555         ushort           _flags;
556         short           _file;
557         __sbuf          _bf;
558         int             _lbfsize;
559 
560         void*           _cookie;
561         int     function(void*)                 _close;
562         ssize_t     function(void*, char*, size_t)     _read;
563         fpos_t  function(void*, fpos_t, int)    _seek;
564         ssize_t     function(void*, in char*, size_t)  _write;
565 
566         __sbuf          _ub;
567         ubyte*          _up;
568         int             _ur;
569 
570         ubyte[3]        _ubuf;
571         ubyte[1]        _nbuf;
572 
573         int     function(void *)    _flush;
574         /* Formerly used by fgetln/fgetwln; kept for binary compatibility */
575         char[__sbuf.sizeof - _flush.sizeof]    _lb_unused = void;
576 
577 
578         int             _blksize;
579         off_t          _offset;
580         static assert(off_t.sizeof==8);
581     }
582 
583     ///
584     alias __sFILE _iobuf;
585     ///
586     alias shared(__sFILE) FILE;
587 }
588 else version (OpenBSD)
589 {
590     ///
591     alias fpos_t = off_t;
592 
593     ///
594     struct __sFILE
595     {
596         ubyte*          _p;
597         int             _r;
598         int             _w;
599         short           _flags;
600         short           _file;
601         __sbuf          _bf;
602         int             _lbfsize;
603 
604         void*           _cookie;
605         int     function(void*)                         _close;
606         int     function(void*, scope char*, int)       _read;
607         fpos_t  function(void*, fpos_t, int)            _seek;
608         int     function(void*, scope const char*, int) _write;
609 
610         __sbuf          _ext;
611         ubyte*          _up;
612         int             _ur;
613 
614         ubyte[3]        _ubuf;
615         ubyte[1]        _nbuf;
616 
617         __sbuf          _lb;
618 
619         int             _blksize;
620         fpos_t          _offset;
621     }
622 
623     ///
624     alias shared(__sFILE) FILE;
625 }
626 else version (DragonFlyBSD)
627 {
628     alias off_t fpos_t;
629 
630     /// See /usr/include/stdio.h
631     struct __FILE_public
632     {
633         ubyte*          *_p;            /* current position in (some) buffer */
634         int             _flags;         /* flags, below; this FILE is free if 0 */
635         int             _fileno;        /* fileno, if Unix descriptor, else -1 */
636         ssize_t         _r;             /* read space left for getc() */
637         ssize_t         _w;             /* write space left for putc() */
638         ssize_t         _lbfsize;       /* 0 or -_bf._size, for inline putc */
639     }
640 
641     alias __FILE_public _iobuf;
642     alias shared(__FILE_public) FILE;
643 }
644 else version (Solaris)
645 {
646     import core.stdc.wchar_ : mbstate_t;
647 
648     ///
649     alias c_long fpos_t;
650 
651     version (D_LP64)
652     {
653         ///
654         struct _iobuf
655         {
656             char*      _ptr;   /* next character from/to here in buffer */
657             char*      _base;  /* the buffer */
658             char*      _end;   /* the end of the buffer */
659             size_t     _cnt;   /* number of available characters in buffer */
660             int        _file;  /* UNIX System file descriptor */
661             int        _flag;  /* the state of the stream */
662             ubyte[24]  _lock;  //rmutex_t   _lock; /* lock for this structure */
663             mbstate_t  _state; /* mbstate_t */
664             ubyte[32]  __fill; /* filler to bring size to 128 bytes */
665         }
666     }
667     else
668     {
669         ///
670         struct _iobuf
671         {
672             char* _ptr;
673             int _cnt;
674             char* _base;
675             char _flag = 0;
676             char _magic = 0;
677             ushort __flags; // __orientation:2
678                             // __ionolock:1
679                             // __seekable:1
680                             // __extendedfd:1
681                             // __xf_nocheck:1
682                             // __filler:10
683         }
684     }
685     ///
686     alias shared(_iobuf) FILE;
687 }
688 else version (CRuntime_Bionic)
689 {
690     import core.sys.posix.sys.types : off_t;
691     ///
692     alias off_t fpos_t;
693 
694     ///
695     struct __sFILE
696     {
697         ubyte*    _p;
698         int       _r;
699         int       _w;
700         short     _flags;
701         short     _file;
702         __sbuf    _bf;
703         int       _lbfsize;
704 
705         void*     _cookie;
706         int      function(void*)                          _close;
707         int      function(void*, scope char*, int)        _read;
708         fpos_t   function(void*, fpos_t, int)             _seek;
709         int      function(void*, scope const char*, int)  _write;
710 
711         __sbuf    _ext;
712         ubyte*    _up;
713         int       _ur;
714 
715         ubyte[3]  _ubuf;
716         ubyte[1]  _nbuf;
717 
718         __sbuf    _lb;
719 
720         int       _blksize;
721         fpos_t    _offset;
722     }
723 
724     ///
725     alias __sFILE _iobuf;
726     ///
727     alias shared(__sFILE) FILE;
728 }
729 else version (CRuntime_UClibc)
730 {
731     import core.stdc.wchar_ : mbstate_t;
732     import core.stdc.stddef : wchar_t;
733     import core.sys.posix.sys.types : ssize_t, pthread_mutex_t;
734 
735     alias long off_t;
736 
737     ///
738     struct fpos_t
739     {
740         off_t __pos;
741         mbstate_t __state;
742         int __mblen_pending;
743     }
744 
745     struct _IO_cookie_io_functions_t
746     {
747        ssize_t function(void* __cookie, char* __buf, size_t __bufsize)          read;
748        ssize_t function(void* __cookie, const char* __buf, size_t __bufsize)    write;
749        int function(void* __cookie, off_t* __pos, int __whence)                 seek;
750        int function(void* __cookie)                                             close;
751     }
752 
753     alias _IO_cookie_io_functions_t cookie_io_functions_t;
754 
755     ///
756     struct __STDIO_FILE_STRUCT
757     {
758         ushort __modeflags;
759         char[2] __ungot_width = 0;
760         int __filedes;
761         char* __bufstart;
762         char* __bufend;
763         char* __bufpos;
764         char* __bufread;
765         char* __bufgetc_u;
766         char*__bufputc_u;
767         __STDIO_FILE_STRUCT* __nextopen;
768         void *__cookie;
769         _IO_cookie_io_functions_t __gcs;
770         wchar_t[2] __ungot = 0;
771         mbstate_t __state;
772         void *__unused;
773         int __user_locking;
774         pthread_mutex_t __lock;
775     }
776 
777     ///
778     alias __STDIO_FILE_STRUCT _iobuf;
779     ///
780     alias shared(__STDIO_FILE_STRUCT) FILE;
781 }
782 else
783 {
784     static assert( false, "Unsupported platform" );
785 }
786 
787 enum
788 {
789     ///
790     _F_RDWR = 0x0003, // non-standard
791     ///
792     _F_READ = 0x0001, // non-standard
793     ///
794     _F_WRIT = 0x0002, // non-standard
795     ///
796     _F_BUF  = 0x0004, // non-standard
797     ///
798     _F_LBUF = 0x0008, // non-standard
799     ///
800     _F_ERR  = 0x0010, // non-standard
801     ///
802     _F_EOF  = 0x0020, // non-standard
803     ///
804     _F_BIN  = 0x0040, // non-standard
805     ///
806     _F_IN   = 0x0080, // non-standard
807     ///
808     _F_OUT  = 0x0100, // non-standard
809     ///
810     _F_TERM = 0x0200, // non-standard
811 }
812 
813 version (CRuntime_DigitalMars)
814 {
815     enum
816     {
817         ///
818         _IOFBF   = 0,
819         ///
820         _IOLBF   = 0x40,
821         ///
822         _IONBF   = 4,
823         ///
824         _IOREAD  = 1,     // non-standard
825         ///
826         _IOWRT   = 2,     // non-standard
827         ///
828         _IOMYBUF = 8,     // non-standard
829         ///
830         _IOEOF   = 0x10,  // non-standard
831         ///
832         _IOERR   = 0x20,  // non-standard
833         ///
834         _IOSTRG  = 0x40,  // non-standard
835         ///
836         _IORW    = 0x80,  // non-standard
837         ///
838         _IOTRAN  = 0x100, // non-standard
839         ///
840         _IOAPP   = 0x200, // non-standard
841     }
842 
843     extern shared void function() _fcloseallp;
844 
845     private extern shared FILE[_NFILE] _iob;
846 
847     ///
848     enum stdin  = &_iob[0];
849     ///
850     enum stdout = &_iob[1];
851     ///
852     enum stderr = &_iob[2];
853     ///
854     enum stdaux = &_iob[3];
855     ///
856     enum stdprn = &_iob[4];
857 }
858 else version (CRuntime_Microsoft)
859 {
860     enum
861     {
862         ///
863         _IOFBF   = 0,
864         ///
865         _IOLBF   = 0x40,
866         ///
867         _IONBF   = 4,
868         /// Removed since Visual Studio 2015.
869         _IOREAD  = 1,     // non-standard
870         /// Removed since Visual Studio 2015.
871         _IOWRT   = 2,     // non-standard
872         /// Removed since Visual Studio 2015.
873         _IOMYBUF = 8,     // non-standard
874         /// Removed since Visual Studio 2015.
875         _IOEOF   = 0x10,  // non-standard
876         /// Removed since Visual Studio 2015.
877         _IOERR   = 0x20,  // non-standard
878         /// Removed since Visual Studio 2015.
879         _IOSTRG  = 0x40,  // non-standard
880         /// Removed since Visual Studio 2015.
881         _IORW    = 0x80,  // non-standard
882         /// Removed since Visual Studio 2015.
883         _IOAPP   = 0x200, // non-standard
884         /// Removed since Visual Studio 2015.
885         _IOAPPEND = 0x200, // non-standard
886     }
887 
888     extern shared void function() _fcloseallp;
889 
890     ///
891     shared FILE* stdin;  // = &__iob_func()[0];
892     ///
893     shared FILE* stdout; // = &__iob_func()[1];
894     ///
895     shared FILE* stderr; // = &__iob_func()[2];
896 }
897 else version (CRuntime_Glibc)
898 {
899     enum
900     {
901         ///
902         _IOFBF = 0,
903         ///
904         _IOLBF = 1,
905         ///
906         _IONBF = 2,
907     }
908 
909     ///
910     extern shared FILE* stdin;
911     ///
912     extern shared FILE* stdout;
913     ///
914     extern shared FILE* stderr;
915 }
916 else version (Darwin)
917 {
918     enum
919     {
920         ///
921         _IOFBF = 0,
922         ///
923         _IOLBF = 1,
924         ///
925         _IONBF = 2,
926     }
927 
928     private extern shared FILE* __stdinp;
929     private extern shared FILE* __stdoutp;
930     private extern shared FILE* __stderrp;
931 
932     ///
933     alias __stdinp  stdin;
934     ///
935     alias __stdoutp stdout;
936     ///
937     alias __stderrp stderr;
938 }
939 else version (FreeBSD)
940 {
941     enum
942     {
943         ///
944         _IOFBF = 0,
945         ///
946         _IOLBF = 1,
947         ///
948         _IONBF = 2,
949     }
950 
951     private extern shared FILE* __stdinp;
952     private extern shared FILE* __stdoutp;
953     private extern shared FILE* __stderrp;
954 
955     ///
956     alias __stdinp  stdin;
957     ///
958     alias __stdoutp stdout;
959     ///
960     alias __stderrp stderr;
961 }
962 else version (NetBSD)
963 {
964     enum
965     {
966         ///
967         _IOFBF = 0,
968         ///
969         _IOLBF = 1,
970         ///
971         _IONBF = 2,
972     }
973 
974     private extern __gshared FILE[3] __sF;
975     @property auto __stdin()() { return &__sF[0]; }
976     @property auto __stdout()() { return &__sF[1]; }
977     @property auto __stderr()() { return &__sF[2]; }
978     ///
979     alias __stdin stdin;
980     ///
981     alias __stdout stdout;
982     ///
983     alias __stderr stderr;
984 }
985 else version (OpenBSD)
986 {
987     enum
988     {
989         ///
990         _IOFBF = 0,
991         ///
992         _IOLBF = 1,
993         ///
994         _IONBF = 2,
995     }
996 
997     private extern shared FILE[] __sF;
998 
999     ///
1000     shared stdin  = &__sF[0];
1001     ///
1002     shared stdout = &__sF[1];
1003     ///
1004     shared stderr = &__sF[2];
1005 }
1006 else version (DragonFlyBSD)
1007 {
1008     enum
1009     {
1010         _IOFBF = 0,
1011         _IOLBF = 1,
1012         _IONBF = 2,
1013     }
1014 
1015     private extern shared FILE* __stdinp;
1016     private extern shared FILE* __stdoutp;
1017     private extern shared FILE* __stderrp;
1018 
1019     alias __stdinp  stdin;
1020     alias __stdoutp stdout;
1021     alias __stderrp stderr;
1022 }
1023 else version (Solaris)
1024 {
1025     enum
1026     {
1027         ///
1028         _IOFBF = 0x00,
1029         ///
1030         _IOLBF = 0x40,
1031         ///
1032         _IONBF = 0x04,
1033         ///
1034         _IOEOF = 0x20,
1035         ///
1036         _IOERR = 0x40,
1037         ///
1038         _IOREAD = 0x01,
1039         ///
1040         _IOWRT = 0x02,
1041         ///
1042         _IORW = 0x80,
1043         ///
1044         _IOMYBUF = 0x08,
1045     }
1046 
1047     private extern shared FILE[_NFILE] __iob;
1048 
1049     ///
1050     shared stdin = &__iob[0];
1051     ///
1052     shared stdout = &__iob[1];
1053     ///
1054     shared stderr = &__iob[2];
1055 }
1056 else version (CRuntime_Bionic)
1057 {
1058     enum
1059     {
1060         ///
1061         _IOFBF = 0,
1062         ///
1063         _IOLBF = 1,
1064         ///
1065         _IONBF = 2,
1066     }
1067 
1068     private extern shared FILE[3] __sF;
1069 
1070     ///
1071     shared stdin  = &__sF[0];
1072     ///
1073     shared stdout = &__sF[1];
1074     ///
1075     shared stderr = &__sF[2];
1076 }
1077 else version (CRuntime_Musl)
1078 {
1079     // needs tail const
1080     extern shared FILE* stdin;
1081     ///
1082     extern shared FILE* stdout;
1083     ///
1084     extern shared FILE* stderr;
1085     enum
1086     {
1087         ///
1088         _IOFBF = 0,
1089         ///
1090         _IOLBF = 1,
1091         ///
1092         _IONBF = 2,
1093     }
1094 }
1095 else version (CRuntime_UClibc)
1096 {
1097     enum
1098     {
1099         ///
1100         _IOFBF = 0,
1101         ///
1102         _IOLBF = 1,
1103         ///
1104         _IONBF = 2,
1105     }
1106 
1107     ///
1108     extern shared FILE* stdin;
1109     ///
1110     extern shared FILE* stdout;
1111     ///
1112     extern shared FILE* stderr;
1113 }
1114 else
1115 {
1116     static assert( false, "Unsupported platform" );
1117 }
1118 
1119 ///
1120 int remove(scope const char* filename);
1121 ///
1122 int rename(scope const char* from, scope const char* to);
1123 
1124 ///
1125 @trusted FILE* tmpfile(); // No unsafe pointer manipulation.
1126 ///
1127 char* tmpnam(char* s);
1128 
1129 ///
1130 int   fclose(FILE* stream);
1131 
1132 // No unsafe pointer manipulation.
1133 @trusted
1134 {
1135     ///
1136     int   fflush(FILE* stream);
1137 }
1138 
1139 ///
1140 FILE* fopen(scope const char* filename, scope const char* mode);
1141 ///
1142 FILE* freopen(scope const char* filename, scope const char* mode, FILE* stream);
1143 
1144 ///
1145 void setbuf(FILE* stream, char* buf);
1146 ///
1147 int  setvbuf(FILE* stream, char* buf, int mode, size_t size);
1148 
1149 version (MinGW)
1150 {
1151     // Prefer the MinGW versions over the MSVC ones, as the latter don't handle
1152     // reals at all.
1153     ///
1154     int __mingw_fprintf(FILE* stream, scope const char* format, ...);
1155     ///
1156     alias __mingw_fprintf fprintf;
1157 
1158     ///
1159     int __mingw_fscanf(FILE* stream, scope const char* format, ...);
1160     ///
1161     alias __mingw_fscanf fscanf;
1162 
1163     ///
1164     int __mingw_sprintf(scope char* s, scope const char* format, ...);
1165     ///
1166     alias __mingw_sprintf sprintf;
1167 
1168     ///
1169     int __mingw_sscanf(scope const char* s, scope const char* format, ...);
1170     ///
1171     alias __mingw_sscanf sscanf;
1172 
1173     ///
1174     int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg);
1175     ///
1176     alias __mingw_vfprintf vfprintf;
1177 
1178     ///
1179     int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg);
1180     ///
1181     alias __mingw_vfscanf vfscanf;
1182 
1183     ///
1184     int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg);
1185     ///
1186     alias __mingw_vsprintf vsprintf;
1187 
1188     ///
1189     int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg);
1190     ///
1191     alias __mingw_vsscanf vsscanf;
1192 
1193     ///
1194     int __mingw_vprintf(scope const char* format, va_list arg);
1195     ///
1196     alias __mingw_vprintf vprintf;
1197 
1198     ///
1199     int __mingw_vscanf(scope const char* format, va_list arg);
1200     ///
1201     alias __mingw_vscanf vscanf;
1202 
1203     ///
1204     int __mingw_printf(scope const char* format, ...);
1205     ///
1206     alias __mingw_printf printf;
1207 
1208     ///
1209     int __mingw_scanf(scope const char* format, ...);
1210     ///
1211     alias __mingw_scanf scanf;
1212 }
1213 else
1214 {
1215     ///
1216     int fprintf(FILE* stream, scope const char* format, ...);
1217     ///
1218     int fscanf(FILE* stream, scope const char* format, ...);
1219     ///
1220     int sprintf(scope char* s, scope const char* format, ...);
1221     ///
1222     int sscanf(scope const char* s, scope const char* format, ...);
1223     ///
1224     int vfprintf(FILE* stream, scope const char* format, va_list arg);
1225     ///
1226     int vfscanf(FILE* stream, scope const char* format, va_list arg);
1227     ///
1228     int vsprintf(scope char* s, scope const char* format, va_list arg);
1229     ///
1230     int vsscanf(scope const char* s, scope const char* format, va_list arg);
1231     ///
1232     int vprintf(scope const char* format, va_list arg);
1233     ///
1234     int vscanf(scope const char* format, va_list arg);
1235     ///
1236     int printf(scope const char* format, ...);
1237     ///
1238     int scanf(scope const char* format, ...);
1239 }
1240 
1241 // No unsafe pointer manipulation.
1242 @trusted
1243 {
1244     ///
1245     int fgetc(FILE* stream);
1246     ///
1247     int fputc(int c, FILE* stream);
1248 }
1249 
1250 ///
1251 char* fgets(char* s, int n, FILE* stream);
1252 ///
1253 int   fputs(scope const char* s, FILE* stream);
1254 ///
1255 char* gets(char* s);
1256 ///
1257 int   puts(scope const char* s);
1258 
1259 // No unsafe pointer manipulation.
1260 extern (D) @trusted
1261 {
1262     ///
1263     int getchar()()                 { return getc(stdin);     }
1264     ///
1265     int putchar()(int c)            { return putc(c,stdout);  }
1266     ///
1267     int getc()(FILE* stream)        { return fgetc(stream);   }
1268     ///
1269     int putc()(int c, FILE* stream) { return fputc(c,stream); }
1270 }
1271 
1272 ///
1273 @trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation.
1274 
1275 ///
1276 size_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream);
1277 ///
1278 size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream);
1279 
1280 // No unsafe pointer manipulation.
1281 @trusted
1282 {
1283     ///
1284     int fgetpos(FILE* stream, scope fpos_t * pos);
1285     ///
1286     int fsetpos(FILE* stream, scope const fpos_t* pos);
1287 
1288     ///
1289     int    fseek(FILE* stream, c_long offset, int whence);
1290     ///
1291     c_long ftell(FILE* stream);
1292 }
1293 
1294 version (MinGW)
1295 {
1296   // No unsafe pointer manipulation.
1297   extern (D) @trusted
1298   {
1299     ///
1300     void rewind()(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag = stream._flag & ~_IOERR; }
1301     ///
1302     pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }
1303     ///
1304     pure int  feof()(FILE* stream)     { return stream._flag&_IOEOF; }
1305     ///
1306     pure int  ferror()(FILE* stream)   { return stream._flag&_IOERR; }
1307   }
1308   ///
1309     int   __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, ...);
1310     ///
1311     alias __mingw_snprintf _snprintf;
1312     ///
1313     alias __mingw_snprintf snprintf;
1314 
1315     ///
1316     int   __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1317     ///
1318     alias __mingw_vsnprintf _vsnprintf;
1319     ///
1320     alias __mingw_vsnprintf vsnprintf;
1321 }
1322 else version (CRuntime_DigitalMars)
1323 {
1324   // No unsafe pointer manipulation.
1325   extern (D) @trusted
1326   {
1327     ///
1328     void rewind()(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; }
1329     ///
1330     pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }
1331     ///
1332     pure int  feof()(FILE* stream)     { return stream._flag&_IOEOF; }
1333     ///
1334     pure int  ferror()(FILE* stream)   { return stream._flag&_IOERR; }
1335     ///
1336     pure int  fileno()(FILE* stream)   { return stream._file; }
1337   }
1338   ///
1339     int   _snprintf(scope char* s, size_t n, scope const char* fmt, ...);
1340     ///
1341     alias _snprintf snprintf;
1342 
1343     ///
1344     int   _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1345     ///
1346     alias _vsnprintf vsnprintf;
1347 }
1348 else version (CRuntime_Microsoft)
1349 {
1350   // No unsafe pointer manipulation.
1351   @trusted
1352   {
1353     ///
1354     void rewind(FILE* stream);
1355     ///
1356     pure void clearerr(FILE* stream);
1357     ///
1358     pure int  feof(FILE* stream);
1359     ///
1360     pure int  ferror(FILE* stream);
1361     ///
1362     pure int  fileno(FILE* stream);
1363   }
1364 
1365     ///
1366     int _snprintf(scope char* s, size_t n, scope const char* format, ...);
1367     ///
1368     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1369 
1370     ///
1371     int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1372     ///
1373     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1374 
1375     ///
1376     int _fputc_nolock(int c, FILE *fp);
1377     ///
1378     int _fgetc_nolock(FILE *fp);
1379 
1380     ///
1381     int _lock_file(FILE *fp);
1382     ///
1383     int _unlock_file(FILE *fp);
1384 
1385     ///
1386     intptr_t _get_osfhandle(int fd);
1387     ///
1388     int _open_osfhandle(intptr_t osfhandle, int flags);
1389 }
1390 else version (CRuntime_Glibc)
1391 {
1392   // No unsafe pointer manipulation.
1393   @trusted
1394   {
1395     ///
1396     void rewind(FILE* stream);
1397     ///
1398     pure void clearerr(FILE* stream);
1399     ///
1400     pure int  feof(FILE* stream);
1401     ///
1402     pure int  ferror(FILE* stream);
1403     ///
1404     int  fileno(FILE *);
1405   }
1406 
1407     ///
1408     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1409     ///
1410     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1411 }
1412 else version (Darwin)
1413 {
1414   // No unsafe pointer manipulation.
1415   @trusted
1416   {
1417     ///
1418     void rewind(FILE*);
1419     ///
1420     pure void clearerr(FILE*);
1421     ///
1422     pure int  feof(FILE*);
1423     ///
1424     pure int  ferror(FILE*);
1425     ///
1426     int  fileno(FILE*);
1427   }
1428 
1429     ///
1430     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1431     ///
1432     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1433 }
1434 else version (FreeBSD)
1435 {
1436   // No unsafe pointer manipulation.
1437   @trusted
1438   {
1439     ///
1440     void rewind(FILE*);
1441     ///
1442     pure void clearerr(FILE*);
1443     ///
1444     pure int  feof(FILE*);
1445     ///
1446     pure int  ferror(FILE*);
1447     ///
1448     int  fileno(FILE*);
1449   }
1450 
1451     ///
1452     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1453     ///
1454     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1455 }
1456 else version (NetBSD)
1457 {
1458   // No unsafe pointer manipulation.
1459   @trusted
1460   {
1461     ///
1462     void rewind(FILE*);
1463     ///
1464     pure void clearerr(FILE*);
1465     ///
1466     pure int  feof(FILE*);
1467     ///
1468     pure int  ferror(FILE*);
1469     ///
1470     int  fileno(FILE*);
1471   }
1472 
1473     ///
1474     int  snprintf(char* s, size_t n, in char* format, ...);
1475     ///
1476     int  vsnprintf(char* s, size_t n, in char* format, va_list arg);
1477 }
1478 else version (OpenBSD)
1479 {
1480     // No unsafe pointer manipulation.
1481     @trusted
1482     {
1483         ///
1484         void rewind(FILE*);
1485     }
1486     @trusted private
1487     {
1488         ///
1489         pure void clearerr(FILE*);
1490         alias __clearerr = clearerr;
1491         ///
1492         pure int  feof(FILE*);
1493         alias __feof = feof;
1494         ///
1495         pure int  ferror(FILE*);
1496         alias __ferror = ferror;
1497         ///
1498         int  fileno(FILE*);
1499         alias __fileno = fileno;
1500     }
1501 
1502     enum __SLBF = 0x0001;
1503     enum __SNBF = 0x0002;
1504     enum __SRD  = 0x0004;
1505     enum __SWR  = 0x0008;
1506     enum __SRW  = 0x0010;
1507     enum __SEOF = 0x0020;
1508     enum __SERR = 0x0040;
1509     enum __SMBF = 0x0080;
1510     enum __SAPP = 0x0100;
1511     enum __SSTR = 0x0200;
1512     enum __SOPT = 0x0400;
1513     enum __SNPT = 0x0800;
1514     enum __SOFF = 0x1000;
1515     enum __SMOD = 0x2000;
1516     enum __SALC = 0x4000;
1517     enum __SIGN = 0x8000;
1518 
1519     extern int __isthreaded;
1520 
1521     extern (D)
1522     {
1523         void __sclearerr()(FILE* p)
1524         {
1525             p._flags &= ~(__SERR|__SEOF);
1526         }
1527 
1528         int __sfeof()(FILE* p)
1529         {
1530             return (p._flags & __SEOF) != 0;
1531         }
1532 
1533         int __sferror()(FILE* p)
1534         {
1535             return (p._flags & __SERR) != 0;
1536         }
1537 
1538         int __sfileno()(FILE* p)
1539         {
1540             return p._file;
1541         }
1542 
1543         int clearerr()(FILE* file)
1544         {
1545             return !__isthreaded ? __sclearerr(file) : __clearerr(file);
1546         }
1547 
1548         int feof()(FILE* file)
1549         {
1550             return !__isthreaded ? __sfeof(file) : __feof(file);
1551         }
1552 
1553         int ferror()(FILE* file)
1554         {
1555             return !__isthreaded ? __sferror(file) : __ferror(file);
1556         }
1557 
1558         int fileno()(FILE* file)
1559         {
1560             return !__isthreaded ? __sfileno(file) : __fileno(file);
1561         }
1562     }
1563 
1564     ///
1565     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1566     ///
1567     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1568 }
1569 else version (DragonFlyBSD)
1570 {
1571   // No unsafe pointer manipulation.
1572   @trusted
1573   {
1574     void rewind(FILE*);
1575     pure void clearerr(FILE*);
1576     pure int  feof(FILE*);
1577     pure int  ferror(FILE*);
1578     int  fileno(FILE*);
1579   }
1580   enum __SLBF = 0x0001;
1581   enum __SNBF = 0x0002;
1582   enum __SRD  = 0x0004;
1583   enum __SWR  = 0x0008;
1584   enum __SRW  = 0x0010;
1585   enum __SEOF = 0x0020;
1586   enum __SERR = 0x0040;
1587   enum __SMBF = 0x0080;
1588   enum __SAPP = 0x0100;
1589   enum __SSTR = 0x0200;
1590   enum __SOPT = 0x0400;
1591   enum __SNPT = 0x0800;
1592   enum __SOFF = 0x1000;
1593   enum __SMOD = 0x2000;
1594   enum __SALC = 0x4000;
1595   enum __SIGN = 0x8000;
1596 
1597   int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1598   int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1599 }
1600 else version (Solaris)
1601 {
1602   // No unsafe pointer manipulation.
1603   @trusted
1604   {
1605     ///
1606     void rewind(FILE*);
1607     ///
1608     pure void clearerr(FILE*);
1609     ///
1610     pure int  feof(FILE*);
1611     ///
1612     pure int  ferror(FILE*);
1613     ///
1614     int  fileno(FILE*);
1615   }
1616 
1617     ///
1618     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1619     ///
1620     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1621 }
1622 else version (CRuntime_Bionic)
1623 {
1624   // No unsafe pointer manipulation.
1625   @trusted
1626   {
1627     ///
1628     void rewind(FILE*);
1629     ///
1630     pure void clearerr(FILE*);
1631     ///
1632     pure int  feof(FILE*);
1633     ///
1634     pure int  ferror(FILE*);
1635     ///
1636     int  fileno(FILE*);
1637   }
1638 
1639   ///
1640     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1641     ///
1642     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1643 }
1644 else version (CRuntime_Musl)
1645 {
1646     @trusted
1647     {
1648         ///
1649         void rewind(FILE* stream);
1650         ///
1651         pure void clearerr(FILE* stream);
1652         ///
1653         pure int  feof(FILE* stream);
1654         ///
1655         pure int  ferror(FILE* stream);
1656         ///
1657         int  fileno(FILE *);
1658     }
1659 
1660     ///
1661     int snprintf(scope char* s, size_t n, scope const char* format, ...);
1662     ///
1663     int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1664 }
1665 else version (CRuntime_UClibc)
1666 {
1667   // No unsafe pointer manipulation.
1668   @trusted
1669   {
1670     ///
1671     void rewind(FILE* stream);
1672     ///
1673     pure void clearerr(FILE* stream);
1674     ///
1675     pure int  feof(FILE* stream);
1676     ///
1677     pure int  ferror(FILE* stream);
1678     ///
1679     int  fileno(FILE *);
1680   }
1681 
1682     ///
1683     int  snprintf(scope char* s, size_t n, scope const char* format, ...);
1684     ///
1685     int  vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg);
1686 }
1687 else
1688 {
1689     static assert( false, "Unsupported platform" );
1690 }
1691 
1692 ///
1693 void perror(scope const char* s);
1694 
1695 version (CRuntime_DigitalMars)
1696 {
1697     version (none)
1698         import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore;
1699     else
1700     {
1701         // too slow to import windows
1702         private alias void* HANDLE;
1703         private void _WaitSemaphore(int iSemaphore);
1704         private void _ReleaseSemaphore(int iSemaphore);
1705     }
1706 
1707     enum
1708     {
1709         ///
1710         FHND_APPEND     = 0x04,
1711         ///
1712         FHND_DEVICE     = 0x08,
1713         ///
1714         FHND_TEXT       = 0x10,
1715         ///
1716         FHND_BYTE       = 0x20,
1717         ///
1718         FHND_WCHAR      = 0x40,
1719     }
1720 
1721     private enum _MAX_SEMAPHORES = 10 + _NFILE;
1722     private enum _semIO = 3;
1723 
1724     private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs;
1725     private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds;
1726     private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount;
1727     private extern __gshared HANDLE[_NFILE] _osfhnd;
1728     extern shared ubyte[_NFILE] __fhnd_info;
1729 
1730     // this is copied from semlock.h in DMC's runtime.
1731     private void LockSemaphore()(uint num)
1732     {
1733         asm nothrow @nogc
1734         {
1735             mov EDX, num;
1736             lock;
1737             inc _iSemLockCtrs[EDX * 2];
1738             jz lsDone;
1739             push EDX;
1740             call _WaitSemaphore;
1741             add ESP, 4;
1742         }
1743 
1744     lsDone: {}
1745     }
1746 
1747     // this is copied from semlock.h in DMC's runtime.
1748     private void UnlockSemaphore()(uint num)
1749     {
1750         asm nothrow @nogc
1751         {
1752             mov EDX, num;
1753             lock;
1754             dec _iSemLockCtrs[EDX * 2];
1755             js usDone;
1756             push EDX;
1757             call _ReleaseSemaphore;
1758             add ESP, 4;
1759         }
1760 
1761     usDone: {}
1762     }
1763 
1764     // This converts a HANDLE to a file descriptor in DMC's runtime
1765     ///
1766     int _handleToFD()(HANDLE h, int flags)
1767     {
1768         LockSemaphore(_semIO);
1769         scope(exit) UnlockSemaphore(_semIO);
1770 
1771         foreach (fd; 0 .. _NFILE)
1772         {
1773             if (!_osfhnd[fd])
1774             {
1775                 _osfhnd[fd] = h;
1776                 __fhnd_info[fd] = cast(ubyte)flags;
1777                 return fd;
1778             }
1779         }
1780 
1781         return -1;
1782     }
1783 
1784     ///
1785     HANDLE _fdToHandle()(int fd)
1786     {
1787         // no semaphore is required, once inserted, a file descriptor
1788         // doesn't change.
1789         if (fd < 0 || fd >= _NFILE)
1790             return null;
1791 
1792         return _osfhnd[fd];
1793     }
1794 
1795     enum
1796     {
1797         ///
1798         STDIN_FILENO  = 0,
1799         ///
1800         STDOUT_FILENO = 1,
1801         ///
1802         STDERR_FILENO = 2,
1803     }
1804 
1805     int open(scope const(char)* filename, int flags, ...); ///
1806     alias _open = open; ///
1807     int _wopen(scope const wchar* filename, int oflag, ...); ///
1808     int sopen(scope const char* filename, int oflag, int shflag, ...); ///
1809     alias _sopen = sopen; ///
1810     int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///
1811     int close(int fd); ///
1812     alias _close = close; ///
1813     FILE *fdopen(int fd, scope const(char)* flags); ///
1814     alias _fdopen = fdopen; ///
1815     FILE *_wfdopen(int fd, scope const(wchar)* flags); ///
1816 
1817 }
1818 else version (CRuntime_Microsoft)
1819 {
1820     int _open(scope const char* filename, int oflag, ...); ///
1821     int _wopen(scope const wchar* filename, int oflag, ...); ///
1822     int _sopen(scope const char* filename, int oflag, int shflag, ...); ///
1823     int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); ///
1824     int _close(int fd); ///
1825     FILE *_fdopen(int fd, scope const(char)* flags); ///
1826     FILE *_wfdopen(int fd, scope const(wchar)* flags); ///
1827 }
1828 
1829 version (Windows)
1830 {
1831     // file open flags
1832     enum
1833     {
1834         _O_RDONLY = 0x0000, ///
1835         O_RDONLY = _O_RDONLY, ///
1836         _O_WRONLY = 0x0001, ///
1837         O_WRONLY = _O_WRONLY, ///
1838         _O_RDWR   = 0x0002, ///
1839         O_RDWR = _O_RDWR, ///
1840         _O_APPEND = 0x0008, ///
1841         O_APPEND = _O_APPEND, ///
1842         _O_CREAT  = 0x0100, ///
1843         O_CREAT = _O_CREAT, ///
1844         _O_TRUNC  = 0x0200, ///
1845         O_TRUNC = _O_TRUNC, ///
1846         _O_EXCL   = 0x0400, ///
1847         O_EXCL = _O_EXCL, ///
1848         _O_TEXT   = 0x4000, ///
1849         O_TEXT = _O_TEXT, ///
1850         _O_BINARY = 0x8000, ///
1851         O_BINARY = _O_BINARY, ///
1852     }
1853 
1854     enum
1855     {
1856         _S_IREAD  = 0x0100, /// read permission, owner
1857         S_IREAD = _S_IREAD, /// read permission, owner
1858         _S_IWRITE = 0x0080, /// write permission, owner
1859         S_IWRITE = _S_IWRITE, /// write permission, owner
1860     }
1861 
1862     enum
1863     {
1864         _SH_DENYRW = 0x10, /// deny read/write mode
1865         SH_DENYRW = _SH_DENYRW, /// deny read/write mode
1866         _SH_DENYWR = 0x20, /// deny write mode
1867         SH_DENYWR = _SH_DENYWR, /// deny write mode
1868         _SH_DENYRD = 0x30, /// deny read mode
1869         SH_DENYRD = _SH_DENYRD, /// deny read mode
1870         _SH_DENYNO = 0x40, /// deny none mode
1871         SH_DENYNO = _SH_DENYNO, /// deny none mode
1872     }
1873 }
1874