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