/** * D header file for C99 * * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdio.h.html, _stdio.h) * * Copyright: Copyright Sean Kelly 2005 - 2009. * License: Distributed under the * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). * (See accompanying file LICENSE) * Authors: Sean Kelly, * Alex Rønne Petersen * Source: https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d * Standards: ISO/IEC 9899:1999 (E) */ module core.stdc.stdio; version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; private { import core.stdc.config; import core.stdc.stdarg; // for va_list import core.stdc.stdint : intptr_t; version (FreeBSD) { import core.sys.posix.sys.types; } else version (OpenBSD) { import core.sys.posix.sys.types; } version (NetBSD) { import core.sys.posix.sys.types; } version (DragonFlyBSD) { import core.sys.posix.sys.types; } } extern (C): @system: nothrow: @nogc: version (CRuntime_DigitalMars) { enum { /// BUFSIZ = 0x4000, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 256, // 255 plus NULL /// TMP_MAX = 32767, /// SYS_OPEN = 20, // non-standard } /// enum int _NFILE = 60; // non-standard /// enum string _P_tmpdir = "\\"; // non-standard /// enum wstring _wP_tmpdir = "\\"; // non-standard /// enum int L_tmpnam = _P_tmpdir.length + 12; } else version (CRuntime_Microsoft) { enum { /// BUFSIZ = 512, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 260, /// Actually int.max since Visual Studio 2015. TMP_MAX = 32767, /// _SYS_OPEN = 20, // non-standard } /// enum int _NFILE = 512; // non-standard /// Removed since Visual Studio 2015. enum string _P_tmpdir = "\\"; // non-standard /// Removed since Visual Studio 2015. enum wstring _wP_tmpdir = "\\"; // non-standard /// Actually 260 since Visual Studio 2015. enum int L_tmpnam = _P_tmpdir.length + 12; } else version (CRuntime_Glibc) { enum { /// BUFSIZ = 8192, /// EOF = -1, /// FOPEN_MAX = 16, /// FILENAME_MAX = 4095, /// TMP_MAX = 238328, /// L_tmpnam = 20 } } else version (CRuntime_Musl) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 1000, /// FILENAME_MAX = 4096, /// TMP_MAX = 10000, /// L_tmpnam = 20 } } else version (Darwin) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 1024, /// TMP_MAX = 308915776, /// L_tmpnam = 1024, } private { struct __sbuf { ubyte* _base; int _size; } struct __sFILEX { } } } else version (FreeBSD) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 1024, /// TMP_MAX = 308915776, /// L_tmpnam = 1024 } struct __sbuf { ubyte *_base; int _size; } } else version (NetBSD) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 1024, /// TMP_MAX = 308915776, /// L_tmpnam = 1024 } struct __sbuf { ubyte *_base; int _size; } } else version (OpenBSD) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 1024, /// TMP_MAX = 0x7fffffff, /// L_tmpnam = 1024 } struct __sbuf { ubyte *_base; int _size; } } else version (DragonFlyBSD) { enum { BUFSIZ = 1024, EOF = -1, FOPEN_MAX = 20, FILENAME_MAX = 1024, TMP_MAX = 308915776, L_tmpnam = 1024 } struct __sbuf { // byte* s_buf; // storage buffer int function(void *, const char *, int) sbuf_drain_func; void* s_drain_arg; // user-supplied drain argument int s_error; // current error code ssize_t s_size; // size of storage buffer ssize_t s_len; // current length of string int s_flags; // flags ssize_t s_sect_len; // current length of section } enum { SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default) SBUF_AUTOEXTEND = 0x00000001, // automatically extend buffer SBUF_USRFLAGMSK = 0x0000ffff, // mask of flags the user may specify SBUF_DYNAMIC = 0x00010000, // s_buf must be freed SBUF_FINISHED = 0x00020000, // set by sbuf_finish() SBUF_DYNSTRUCT = 0x00080000, // sbuf must be freed SBUF_INSECTION = 0x00100000, // set by sbuf_start_section() } } else version (Solaris) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = _NFILE, /// FILENAME_MAX = 1024, /// TMP_MAX = 17576, /// L_tmpnam = 25, } version (X86) /// enum int _NFILE = 60; else /// enum int _NFILE = 20; } else version (CRuntime_Bionic) { enum { /// BUFSIZ = 1024, /// EOF = -1, /// FOPEN_MAX = 20, /// FILENAME_MAX = 1024, /// TMP_MAX = 308915776, /// L_tmpnam = 1024 } struct __sbuf { ubyte* _base; int _size; } } else version (CRuntime_UClibc) { enum { /// BUFSIZ = 4096, /// EOF = -1, /// FOPEN_MAX = 16, /// FILENAME_MAX = 4095, /// TMP_MAX = 238328, /// L_tmpnam = 20 } } else { static assert( false, "Unsupported platform" ); } enum { /// Offset is relative to the beginning SEEK_SET, /// Offset is relative to the current position SEEK_CUR, /// Offset is relative to the end SEEK_END } version (CRuntime_DigitalMars) { /// alias c_long fpos_t; /// struct _iobuf { char* _ptr; int _cnt; char* _base; int _flag; int _file; int _charbuf; int _bufsiz; char* __tmpnum; } /// alias shared(_iobuf) FILE; } else version (CRuntime_Microsoft) { /// alias long fpos_t; /// struct _iobuf { void* undefined; } /// alias shared(_iobuf) FILE; } else version (CRuntime_Glibc) { import core.stdc.wchar_ : mbstate_t; /// struct fpos_t { long __pos; // couldn't use off_t because of static if issue mbstate_t __state; } /// struct _IO_FILE { int _flags; char* _read_ptr; char* _read_end; char* _read_base; char* _write_base; char* _write_ptr; char* _write_end; char* _buf_base; char* _buf_end; char* _save_base; char* _backup_base; char* _save_end; void* _markers; _IO_FILE* _chain; int _fileno; int _flags2; ptrdiff_t _old_offset; ushort _cur_column; byte _vtable_offset; char[1] _shortbuf = 0; void* _lock; ptrdiff_t _offset; /*_IO_codecvt*/ void* _codecvt; /*_IO_wide_data*/ void* _wide_data; _IO_FILE *_freeres_list; void *_freeres_buf; size_t __pad5; int _mode; char[15 * int.sizeof - 4 * (void*).sizeof - size_t.sizeof] _unused2; } /// alias _IO_FILE _iobuf; /// alias shared(_IO_FILE) FILE; } else version (CRuntime_Musl) { union fpos_t { char[16] __opaque = 0; double __align; } struct _IO_FILE; /// alias _IO_FILE _iobuf; // needed for phobos /// alias shared(_IO_FILE) FILE; } else version (Darwin) { /// alias long fpos_t; /// struct __sFILE { ubyte* _p; int _r; int _w; short _flags; short _file; __sbuf _bf; int _lbfsize; void* _cookie; int function(void*) _close; int function(void*, char*, int) _read; fpos_t function(void*, fpos_t, int) _seek; int function(void*, char *, int) _write; __sbuf _ub; __sFILEX* _extra; int _ur; ubyte[3] _ubuf; ubyte[1] _nbuf; __sbuf _lb; int _blksize; fpos_t _offset; } /// alias __sFILE _iobuf; /// alias shared(__sFILE) FILE; } else version (FreeBSD) { // Need to import wchar_ now since __mbstate_t now resides there import core.stdc.wchar_ : mbstate_t; /// alias off_t fpos_t; /// struct __sFILE { ubyte* _p; int _r; int _w; short _flags; short _file; __sbuf _bf; int _lbfsize; void* _cookie; int function(void*) _close; int function(void*, char*, int) _read; fpos_t function(void*, fpos_t, int) _seek; int function(void*, const scope char*, int) _write; __sbuf _ub; ubyte* _up; int _ur; ubyte[3] _ubuf; ubyte[1] _nbuf; __sbuf _lb; int _blksize; fpos_t _offset; pthread_mutex_t _fl_mutex; pthread_t _fl_owner; int _fl_count; int _orientation; mbstate_t _mbstate; } /// alias __sFILE _iobuf; /// alias shared(__sFILE) FILE; } else version (NetBSD) { /// alias off_t fpos_t; /// struct __sFILE { ubyte* _p; int _r; int _w; ushort _flags; short _file; __sbuf _bf; int _lbfsize; void* _cookie; int function(void*) _close; ssize_t function(void*, char*, size_t) _read; fpos_t function(void*, fpos_t, int) _seek; ssize_t function(void*, const scope char*, size_t) _write; __sbuf _ub; ubyte* _up; int _ur; ubyte[3] _ubuf; ubyte[1] _nbuf; int function(void *) _flush; /* Formerly used by fgetln/fgetwln; kept for binary compatibility */ char[__sbuf.sizeof - _flush.sizeof] _lb_unused = void; int _blksize; off_t _offset; static assert(off_t.sizeof==8); } /// alias __sFILE _iobuf; /// alias shared(__sFILE) FILE; } else version (OpenBSD) { /// alias fpos_t = off_t; /// struct __sFILE { ubyte* _p; int _r; int _w; short _flags; short _file; __sbuf _bf; int _lbfsize; void* _cookie; int function(void*) _close; int function(void*, scope char*, int) _read; fpos_t function(void*, fpos_t, int) _seek; int function(void*, scope const char*, int) _write; __sbuf _ext; ubyte* _up; int _ur; ubyte[3] _ubuf; ubyte[1] _nbuf; __sbuf _lb; int _blksize; fpos_t _offset; } /// alias __sFILE _iobuf; /// alias shared(__sFILE) FILE; } else version (DragonFlyBSD) { alias off_t fpos_t; /// See /usr/include/stdio.h struct __FILE_public { ubyte* *_p; /* current position in (some) buffer */ int _flags; /* flags, below; this FILE is free if 0 */ int _fileno; /* fileno, if Unix descriptor, else -1 */ ssize_t _r; /* read space left for getc() */ ssize_t _w; /* write space left for putc() */ ssize_t _lbfsize; /* 0 or -_bf._size, for inline putc */ } alias __FILE_public _iobuf; alias shared(__FILE_public) FILE; } else version (Solaris) { import core.stdc.wchar_ : mbstate_t; /// alias c_long fpos_t; version (D_LP64) { /// struct _iobuf { char* _ptr; /* next character from/to here in buffer */ char* _base; /* the buffer */ char* _end; /* the end of the buffer */ size_t _cnt; /* number of available characters in buffer */ int _file; /* UNIX System file descriptor */ int _flag; /* the state of the stream */ ubyte[24] _lock; //rmutex_t _lock; /* lock for this structure */ mbstate_t _state; /* mbstate_t */ ubyte[32] __fill; /* filler to bring size to 128 bytes */ } } else { /// struct _iobuf { char* _ptr; int _cnt; char* _base; char _flag = 0; char _magic = 0; ushort __flags; // __orientation:2 // __ionolock:1 // __seekable:1 // __extendedfd:1 // __xf_nocheck:1 // __filler:10 } } /// alias shared(_iobuf) FILE; } else version (CRuntime_Bionic) { /// alias c_long fpos_t; // couldn't use off_t because of static if issue /// struct __sFILE { ubyte* _p; int _r; int _w; short _flags; short _file; __sbuf _bf; int _lbfsize; void* _cookie; int function(void*) _close; int function(void*, scope char*, int) _read; fpos_t function(void*, fpos_t, int) _seek; int function(void*, scope const char*, int) _write; __sbuf _ext; ubyte* _up; int _ur; ubyte[3] _ubuf; ubyte[1] _nbuf; __sbuf _lb; int _blksize; fpos_t _offset; } /// alias __sFILE _iobuf; /// alias shared(__sFILE) FILE; } else version (CRuntime_UClibc) { import core.stdc.wchar_ : mbstate_t; import core.stdc.stddef : wchar_t; import core.sys.posix.sys.types : ssize_t, pthread_mutex_t; /// struct fpos_t { long __pos; // couldn't use off_t because of static if issue mbstate_t __state; int __mblen_pending; } struct _IO_cookie_io_functions_t { ssize_t function(void* __cookie, char* __buf, size_t __bufsize) read; ssize_t function(void* __cookie, const char* __buf, size_t __bufsize) write; int function(void* __cookie, long* __pos, int __whence) seek; int function(void* __cookie) close; } alias _IO_cookie_io_functions_t cookie_io_functions_t; /// struct __STDIO_FILE_STRUCT { ushort __modeflags; char[2] __ungot_width = 0; int __filedes; char* __bufstart; char* __bufend; char* __bufpos; char* __bufread; char* __bufgetc_u; char*__bufputc_u; __STDIO_FILE_STRUCT* __nextopen; void *__cookie; _IO_cookie_io_functions_t __gcs; wchar_t[2] __ungot = 0; mbstate_t __state; void *__unused; int __user_locking; pthread_mutex_t __lock; } /// alias __STDIO_FILE_STRUCT _iobuf; /// alias shared(__STDIO_FILE_STRUCT) FILE; } else { static assert( false, "Unsupported platform" ); } enum { /// _F_RDWR = 0x0003, // non-standard /// _F_READ = 0x0001, // non-standard /// _F_WRIT = 0x0002, // non-standard /// _F_BUF = 0x0004, // non-standard /// _F_LBUF = 0x0008, // non-standard /// _F_ERR = 0x0010, // non-standard /// _F_EOF = 0x0020, // non-standard /// _F_BIN = 0x0040, // non-standard /// _F_IN = 0x0080, // non-standard /// _F_OUT = 0x0100, // non-standard /// _F_TERM = 0x0200, // non-standard } version (CRuntime_DigitalMars) { enum { /// _IOFBF = 0, /// _IOLBF = 0x40, /// _IONBF = 4, /// _IOREAD = 1, // non-standard /// _IOWRT = 2, // non-standard /// _IOMYBUF = 8, // non-standard /// _IOEOF = 0x10, // non-standard /// _IOERR = 0x20, // non-standard /// _IOSTRG = 0x40, // non-standard /// _IORW = 0x80, // non-standard /// _IOTRAN = 0x100, // non-standard /// _IOAPP = 0x200, // non-standard } extern shared void function() _fcloseallp; private extern shared FILE[_NFILE] _iob; /// enum stdin = &_iob[0]; /// enum stdout = &_iob[1]; /// enum stderr = &_iob[2]; /// enum stdaux = &_iob[3]; /// enum stdprn = &_iob[4]; } else version (CRuntime_Microsoft) { enum { /// _IOFBF = 0, /// _IOLBF = 0x40, /// _IONBF = 4, /// Removed since Visual Studio 2015. _IOREAD = 1, // non-standard /// Removed since Visual Studio 2015. _IOWRT = 2, // non-standard /// Removed since Visual Studio 2015. _IOMYBUF = 8, // non-standard /// Removed since Visual Studio 2015. _IOEOF = 0x10, // non-standard /// Removed since Visual Studio 2015. _IOERR = 0x20, // non-standard /// Removed since Visual Studio 2015. _IOSTRG = 0x40, // non-standard /// Removed since Visual Studio 2015. _IORW = 0x80, // non-standard /// Removed since Visual Studio 2015. _IOAPP = 0x200, // non-standard /// Removed since Visual Studio 2015. _IOAPPEND = 0x200, // non-standard } extern shared void function() _fcloseallp; FILE* __acrt_iob_func(int hnd); // VS2015+, reimplemented in msvc.d for VS2013- /// FILE* stdin()() { return __acrt_iob_func(0); } /// FILE* stdout()() { return __acrt_iob_func(1); } /// FILE* stderr()() { return __acrt_iob_func(2); } } else version (CRuntime_Glibc) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } /// extern shared FILE* stdin; /// extern shared FILE* stdout; /// extern shared FILE* stderr; } else version (Darwin) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } private extern shared FILE* __stdinp; private extern shared FILE* __stdoutp; private extern shared FILE* __stderrp; /// alias __stdinp stdin; /// alias __stdoutp stdout; /// alias __stderrp stderr; } else version (FreeBSD) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } private extern shared FILE* __stdinp; private extern shared FILE* __stdoutp; private extern shared FILE* __stderrp; /// alias __stdinp stdin; /// alias __stdoutp stdout; /// alias __stderrp stderr; } else version (NetBSD) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } private extern shared FILE[3] __sF; @property auto __stdin()() { return &__sF[0]; } @property auto __stdout()() { return &__sF[1]; } @property auto __stderr()() { return &__sF[2]; } /// alias __stdin stdin; /// alias __stdout stdout; /// alias __stderr stderr; } else version (OpenBSD) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } private extern shared FILE[3] __sF; @property auto __stdin()() { return &__sF[0]; } @property auto __stdout()() { return &__sF[1]; } @property auto __stderr()() { return &__sF[2]; } /// alias __stdin stdin; /// alias __stdout stdout; /// alias __stderr stderr; } else version (DragonFlyBSD) { enum { _IOFBF = 0, _IOLBF = 1, _IONBF = 2, } private extern shared FILE* __stdinp; private extern shared FILE* __stdoutp; private extern shared FILE* __stderrp; alias __stdinp stdin; alias __stdoutp stdout; alias __stderrp stderr; } else version (Solaris) { enum { /// _IOFBF = 0x00, /// _IOLBF = 0x40, /// _IONBF = 0x04, /// _IOEOF = 0x20, /// _IOERR = 0x40, /// _IOREAD = 0x01, /// _IOWRT = 0x02, /// _IORW = 0x80, /// _IOMYBUF = 0x08, } private extern shared FILE[_NFILE] __iob; /// @property auto stdin()() { return &__iob[0]; } /// @property auto stdout()() { return &__iob[1]; } /// @property auto stderr()() { return &__iob[2]; } } else version (CRuntime_Bionic) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } private extern shared FILE[3] __sF; /// @property auto stdin()() { return &__sF[0]; } /// @property auto stdout()() { return &__sF[1]; } /// @property auto stderr()() { return &__sF[2]; } } else version (CRuntime_Musl) { // needs tail const extern shared FILE* stdin; /// extern shared FILE* stdout; /// extern shared FILE* stderr; enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } } else version (CRuntime_UClibc) { enum { /// _IOFBF = 0, /// _IOLBF = 1, /// _IONBF = 2, } /// extern shared FILE* stdin; /// extern shared FILE* stdout; /// extern shared FILE* stderr; } else { static assert( false, "Unsupported platform" ); } /// int remove(scope const char* filename); /// int rename(scope const char* from, scope const char* to); /// @trusted FILE* tmpfile(); // No unsafe pointer manipulation. /// char* tmpnam(char* s); /// int fclose(FILE* stream); // No unsafe pointer manipulation. @trusted { /// int fflush(FILE* stream); } /// FILE* fopen(scope const char* filename, scope const char* mode); /// FILE* freopen(scope const char* filename, scope const char* mode, FILE* stream); /// void setbuf(FILE* stream, char* buf); /// int setvbuf(FILE* stream, char* buf, int mode, size_t size); version (MinGW) { // Prefer the MinGW versions over the MSVC ones, as the latter don't handle // reals at all. /// pragma(printf) int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...); /// alias __mingw_fprintf fprintf; /// pragma(scanf) int __mingw_fscanf(FILE* stream, scope const char* format, scope ...); /// alias __mingw_fscanf fscanf; /// pragma(printf) int __mingw_sprintf(scope char* s, scope const char* format, scope const ...); /// alias __mingw_sprintf sprintf; /// pragma(scanf) int __mingw_sscanf(scope const char* s, scope const char* format, scope ...); /// alias __mingw_sscanf sscanf; /// pragma(printf) int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg); /// alias __mingw_vfprintf vfprintf; /// pragma(scanf) int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg); /// alias __mingw_vfscanf vfscanf; /// pragma(printf) int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg); /// alias __mingw_vsprintf vsprintf; /// pragma(scanf) int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg); /// alias __mingw_vsscanf vsscanf; /// pragma(printf) int __mingw_vprintf(scope const char* format, va_list arg); /// alias __mingw_vprintf vprintf; /// pragma(scanf) int __mingw_vscanf(scope const char* format, va_list arg); /// alias __mingw_vscanf vscanf; /// pragma(printf) int __mingw_printf(scope const char* format, scope const ...); /// alias __mingw_printf printf; /// pragma(scanf) int __mingw_scanf(scope const char* format, scope ...); /// alias __mingw_scanf scanf; } else { /// pragma(printf) int fprintf(FILE* stream, scope const char* format, scope const ...); /// pragma(scanf) int fscanf(FILE* stream, scope const char* format, scope ...); /// pragma(printf) int sprintf(scope char* s, scope const char* format, scope const ...); /// pragma(scanf) int sscanf(scope const char* s, scope const char* format, scope ...); /// pragma(printf) int vfprintf(FILE* stream, scope const char* format, va_list arg); /// pragma(scanf) int vfscanf(FILE* stream, scope const char* format, va_list arg); /// pragma(printf) int vsprintf(scope char* s, scope const char* format, va_list arg); /// pragma(scanf) int vsscanf(scope const char* s, scope const char* format, va_list arg); /// pragma(printf) int vprintf(scope const char* format, va_list arg); /// pragma(scanf) int vscanf(scope const char* format, va_list arg); /// pragma(printf) int printf(scope const char* format, scope const ...); /// pragma(scanf) int scanf(scope const char* format, scope ...); } // No unsafe pointer manipulation. @trusted { /// int fgetc(FILE* stream); /// int fputc(int c, FILE* stream); } /// char* fgets(char* s, int n, FILE* stream); /// int fputs(scope const char* s, FILE* stream); /// char* gets(char* s); /// int puts(scope const char* s); // No unsafe pointer manipulation. extern (D) @trusted { /// int getchar()() { return getc(stdin); } /// int putchar()(int c) { return putc(c,stdout); } } /// alias getc = fgetc; /// alias putc = fputc; /// @trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation. /// size_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream); /// size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream); // No unsafe pointer manipulation. @trusted { /// int fgetpos(FILE* stream, scope fpos_t * pos); /// int fsetpos(FILE* stream, scope const fpos_t* pos); /// int fseek(FILE* stream, c_long offset, int whence); /// c_long ftell(FILE* stream); } version (CRuntime_DigitalMars) { // No unsafe pointer manipulation. extern (D) @trusted { /// void rewind()(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; } /// pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); } /// pure int feof()(FILE* stream) { return stream._flag&_IOEOF; } /// pure int ferror()(FILE* stream) { return stream._flag&_IOERR; } /// pure int fileno()(FILE* stream) { return stream._file; } } /// pragma(printf) int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias _snprintf snprintf; /// pragma(printf) int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// alias _vsnprintf vsnprintf; // // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the // unshared version of FILE*, usable when the FILE is locked. // /// int _fputc_nlock(int c, _iobuf* fp); /// int _fputwc_nlock(int c, _iobuf* fp); /// int _fgetc_nlock(_iobuf* fp); /// int _fgetwc_nlock(_iobuf* fp); /// int __fp_lock(FILE* fp); /// void __fp_unlock(FILE* fp); /// int setmode(int fd, int mode); } else version (CRuntime_Microsoft) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE* stream); /// pure void clearerr(FILE* stream); /// pure int feof(FILE* stream); /// pure int ferror(FILE* stream); /// pure int fileno(FILE* stream); } version (MinGW) { pragma(printf) int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); /// alias __mingw_snprintf _snprintf; /// alias __mingw_snprintf snprintf; /// pragma(printf) int __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// alias __mingw_vsnprintf _vsnprintf; /// alias __mingw_vsnprintf vsnprintf; } else { /// pragma(printf) int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } // // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared // version of FILE*, usable when the FILE is locked. // import core.stdc.stddef : wchar_t; import core.stdc.wchar_ : wint_t; /// int _fputc_nolock(int c, _iobuf* fp); /// int _fgetc_nolock(_iobuf* fp); /// wint_t _fputwc_nolock(wchar_t c, _iobuf* fp); /// wint_t _fgetwc_nolock(_iobuf* fp); /// void _lock_file(FILE* fp); /// void _unlock_file(FILE* fp); /// int _setmode(int fd, int mode); /// int _fseeki64(FILE* stream, long offset, int origin); /// long _ftelli64(FILE* stream); /// intptr_t _get_osfhandle(int fd); /// int _open_osfhandle(intptr_t osfhandle, int flags); } else version (CRuntime_Glibc) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE* stream); /// pure void clearerr(FILE* stream); /// pure int feof(FILE* stream); /// pure int ferror(FILE* stream); /// int fileno(FILE *); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); // // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared // version of FILE*, usable when the FILE is locked. // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html // import core.stdc.wchar_ : wint_t; import core.stdc.stddef : wchar_t; /// int fputc_unlocked(int c, _iobuf* stream); /// int fgetc_unlocked(_iobuf* stream); /// wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream); /// wint_t fgetwc_unlocked(_iobuf* stream); } else version (Darwin) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); /// pure void clearerr(FILE*); /// pure int feof(FILE*); /// pure int ferror(FILE*); /// int fileno(FILE*); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (FreeBSD) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); /// pure void clearerr(FILE*); /// pure int feof(FILE*); /// pure int ferror(FILE*); /// int fileno(FILE*); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (NetBSD) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); /// pure void clearerr(FILE*); /// pure int feof(FILE*); /// pure int ferror(FILE*); /// int fileno(FILE*); } /// pragma(printf) int snprintf(char* s, size_t n, const scope char* format, scope const ...); /// pragma(printf) int vsnprintf(char* s, size_t n, const scope char* format, va_list arg); } else version (OpenBSD) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); } @trusted private { /// pragma(mangle, "clearerr") pure void __clearerr(FILE*); /// pragma(mangle, "feof") pure int __feof(FILE*); /// pragma(mangle, "ferror") pure int __ferror(FILE*); /// pragma(mangle, "fileno") int __fileno(FILE*); } enum __SLBF = 0x0001; enum __SNBF = 0x0002; enum __SRD = 0x0004; enum __SWR = 0x0008; enum __SRW = 0x0010; enum __SEOF = 0x0020; enum __SERR = 0x0040; enum __SMBF = 0x0080; enum __SAPP = 0x0100; enum __SSTR = 0x0200; enum __SOPT = 0x0400; enum __SNPT = 0x0800; enum __SOFF = 0x1000; enum __SMOD = 0x2000; enum __SALC = 0x4000; enum __SIGN = 0x8000; extern immutable __gshared int __isthreaded; extern (D) @trusted { void __sclearerr()(FILE* p) { p._flags = p._flags & ~(__SERR|__SEOF); } int __sfeof()(FILE* p) { return (p._flags & __SEOF) != 0; } int __sferror()(FILE* p) { return (p._flags & __SERR) != 0; } int __sfileno()(FILE* p) { return p._file; } pure void clearerr()(FILE* file) { !__isthreaded ? __sclearerr(file) : __clearerr(file); } pure int feof()(FILE* file) { return !__isthreaded ? __sfeof(file) : __feof(file); } pure int ferror()(FILE* file) { return !__isthreaded ? __sferror(file) : __ferror(file); } int fileno()(FILE* file) { return !__isthreaded ? __sfileno(file) : __fileno(file); } } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (DragonFlyBSD) { // No unsafe pointer manipulation. @trusted { void rewind(FILE*); pure void clearerr(FILE*); pure int feof(FILE*); pure int ferror(FILE*); int fileno(FILE*); } enum __SLBF = 0x0001; enum __SNBF = 0x0002; enum __SRD = 0x0004; enum __SWR = 0x0008; enum __SRW = 0x0010; enum __SEOF = 0x0020; enum __SERR = 0x0040; enum __SMBF = 0x0080; enum __SAPP = 0x0100; enum __SSTR = 0x0200; enum __SOPT = 0x0400; enum __SNPT = 0x0800; enum __SOFF = 0x1000; enum __SMOD = 0x2000; enum __SALC = 0x4000; enum __SIGN = 0x8000; pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (Solaris) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); /// pure void clearerr(FILE*); /// pure int feof(FILE*); /// pure int ferror(FILE*); /// int fileno(FILE*); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_Bionic) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE*); /// pure void clearerr(FILE*); /// pure int feof(FILE*); /// pure int ferror(FILE*); /// int fileno(FILE*); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_Musl) { @trusted { /// void rewind(FILE* stream); /// pure void clearerr(FILE* stream); /// pure int feof(FILE* stream); /// pure int ferror(FILE* stream); /// int fileno(FILE *); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else version (CRuntime_UClibc) { // No unsafe pointer manipulation. @trusted { /// void rewind(FILE* stream); /// pure void clearerr(FILE* stream); /// pure int feof(FILE* stream); /// pure int ferror(FILE* stream); /// int fileno(FILE *); } /// pragma(printf) int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); /// pragma(printf) int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); } else { static assert( false, "Unsupported platform" ); } /// void perror(scope const char* s); version (CRuntime_DigitalMars) { version (none) import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore; else { // too slow to import windows private alias void* HANDLE; private void _WaitSemaphore(int iSemaphore); private void _ReleaseSemaphore(int iSemaphore); } enum { /// FHND_APPEND = 0x04, /// FHND_DEVICE = 0x08, /// FHND_TEXT = 0x10, /// FHND_BYTE = 0x20, /// FHND_WCHAR = 0x40, } private enum _MAX_SEMAPHORES = 10 + _NFILE; private enum _semIO = 3; private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs; private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds; private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount; private extern __gshared HANDLE[_NFILE] _osfhnd; extern shared ubyte[_NFILE] __fhnd_info; // this is copied from semlock.h in DMC's runtime. private void LockSemaphore()(uint num) { asm nothrow @nogc { mov EDX, num; lock; inc _iSemLockCtrs[EDX * 2]; jz lsDone; push EDX; call _WaitSemaphore; add ESP, 4; } lsDone: {} } // this is copied from semlock.h in DMC's runtime. private void UnlockSemaphore()(uint num) { asm nothrow @nogc { mov EDX, num; lock; dec _iSemLockCtrs[EDX * 2]; js usDone; push EDX; call _ReleaseSemaphore; add ESP, 4; } usDone: {} } // This converts a HANDLE to a file descriptor in DMC's runtime /// int _handleToFD()(HANDLE h, int flags) { LockSemaphore(_semIO); scope(exit) UnlockSemaphore(_semIO); foreach (fd; 0 .. _NFILE) { if (!_osfhnd[fd]) { _osfhnd[fd] = h; __fhnd_info[fd] = cast(ubyte)flags; return fd; } } return -1; } /// HANDLE _fdToHandle()(int fd) { // no semaphore is required, once inserted, a file descriptor // doesn't change. if (fd < 0 || fd >= _NFILE) return null; return _osfhnd[fd]; } enum { /// STDIN_FILENO = 0, /// STDOUT_FILENO = 1, /// STDERR_FILENO = 2, } int open(scope const(char)* filename, int flags, ...); /// alias _open = open; /// int _wopen(scope const wchar* filename, int oflag, ...); /// int sopen(scope const char* filename, int oflag, int shflag, ...); /// alias _sopen = sopen; /// int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); /// int close(int fd); /// alias _close = close; /// FILE *fdopen(int fd, scope const(char)* flags); /// alias _fdopen = fdopen; /// FILE *_wfdopen(int fd, scope const(wchar)* flags); /// } else version (CRuntime_Microsoft) { int _open(scope const char* filename, int oflag, ...); /// int _wopen(scope const wchar* filename, int oflag, ...); /// int _sopen(scope const char* filename, int oflag, int shflag, ...); /// int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); /// int _close(int fd); /// FILE *_fdopen(int fd, scope const(char)* flags); /// FILE *_wfdopen(int fd, scope const(wchar)* flags); /// } version (Windows) { // file open flags enum { _O_RDONLY = 0x0000, /// O_RDONLY = _O_RDONLY, /// _O_WRONLY = 0x0001, /// O_WRONLY = _O_WRONLY, /// _O_RDWR = 0x0002, /// O_RDWR = _O_RDWR, /// _O_APPEND = 0x0008, /// O_APPEND = _O_APPEND, /// _O_CREAT = 0x0100, /// O_CREAT = _O_CREAT, /// _O_TRUNC = 0x0200, /// O_TRUNC = _O_TRUNC, /// _O_EXCL = 0x0400, /// O_EXCL = _O_EXCL, /// _O_TEXT = 0x4000, /// O_TEXT = _O_TEXT, /// _O_BINARY = 0x8000, /// O_BINARY = _O_BINARY, /// _O_WTEXT = 0x10000, /// _O_U16TEXT = 0x20000, /// _O_U8TEXT = 0x40000, /// _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), /// O_ACCMODE = _O_ACCMODE, /// _O_RAW = _O_BINARY, /// O_RAW = _O_BINARY, /// _O_NOINHERIT = 0x0080, /// O_NOINHERIT = _O_NOINHERIT, /// _O_TEMPORARY = 0x0040, /// O_TEMPORARY = _O_TEMPORARY, /// _O_SHORT_LIVED = 0x1000, /// _O_SEQUENTIAL = 0x0020, /// O_SEQUENTIAL = _O_SEQUENTIAL, /// _O_RANDOM = 0x0010, /// O_RANDOM = _O_RANDOM, /// } enum { _S_IREAD = 0x0100, /// read permission, owner S_IREAD = _S_IREAD, /// read permission, owner _S_IWRITE = 0x0080, /// write permission, owner S_IWRITE = _S_IWRITE, /// write permission, owner } enum { _SH_DENYRW = 0x10, /// deny read/write mode SH_DENYRW = _SH_DENYRW, /// deny read/write mode _SH_DENYWR = 0x20, /// deny write mode SH_DENYWR = _SH_DENYWR, /// deny write mode _SH_DENYRD = 0x30, /// deny read mode SH_DENYRD = _SH_DENYRD, /// deny read mode _SH_DENYNO = 0x40, /// deny none mode SH_DENYNO = _SH_DENYNO, /// deny none mode } }