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