// Written in the D programming language.

/**
$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Symbols))
$(TR $(TD File handles) $(TD
    $(MYREF __popen)
    $(MYREF File)
    $(MYREF isFileHandle)
    $(MYREF openNetwork)
    $(MYREF stderr)
    $(MYREF stdin)
    $(MYREF stdout)
))
$(TR $(TD Reading) $(TD
    $(MYREF chunks)
    $(MYREF lines)
    $(MYREF readf)
    $(MYREF readfln)
    $(MYREF readln)
))
$(TR $(TD Writing) $(TD
    $(MYREF toFile)
    $(MYREF write)
    $(MYREF writef)
    $(MYREF writefln)
    $(MYREF writeln)
))
$(TR $(TD Misc) $(TD
    $(MYREF KeepTerminator)
    $(MYREF LockType)
    $(MYREF StdioException)
))
))

Standard I/O functions that extend $(LINK2 https://dlang.org/phobos/core_stdc_stdio.html, core.stdc.stdio).  $(B core.stdc.stdio)
is $(D_PARAM public)ally imported when importing $(B std.stdio).

There are three layers of I/O:
$(OL
$(LI The lowest layer is the operating system layer. The two main schemes are Windows and Posix.)
$(LI C's $(TT stdio.h) which unifies the two operating system schemes.)
$(LI $(TT std.stdio), this module, unifies the various $(TT stdio.h) implementations into
a high level package for D programs.)
)

Source: $(PHOBOSSRC std/stdio.d)
Copyright: Copyright The D Language Foundation 2007-.
License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors:   $(HTTP digitalmars.com, Walter Bright),
           $(HTTP erdani.org, Andrei Alexandrescu),
           Alex Rønne Petersen
Macros:
CSTDIO=$(HTTP cplusplus.com/reference/cstdio/$1/, $1)
 */
module std.stdio;

/*
# Glossary

The three layers have many terms for their data structures and types.
Here we try to bring some sanity to them for the intrepid code spelunker.

## Windows

Handle

        A Windows handle is an opaque object of type HANDLE.
        The `HANDLE` for standard devices can be retrieved with
        Windows `GetStdHandle()`.

## Posix

file descriptor, aka fileno, aka fildes

        An int from 0..`FOPEN_MAX`, which is an index into some internal data
        structure.
        0 is for `stdin`, 1 for `stdout`, 2 for `stderr`.
        Negative values usually indicate an error.

## stdio.h

`FILE`

        A struct that encapsulates the C library's view of the operating system
        files. A `FILE` should only be referred to via a pointer.

`fileno`

        A field of `FILE` which is the Posix file descriptor for Posix systems, and
        and an index into an array of file `HANDLE`s for Windows.
        This array is how Posix behavior is emulated on Windows.
        For Digital Mars C, that array is `__osfhnd[]`, and is initialized
        at program start by the C runtime library.
        In this module, they are typed as `fileno_t`.

`stdin`, `stdout`, `stderr`

        Global pointers to `FILE` representing standard input, output, and error streams.
        Being global means there are synchronization issues when multiple threads
        are doing I/O on the same streams.

## std.stdio

*/

import core.stdc.stddef : wchar_t;
public import core.stdc.stdio;
import std.algorithm.mutation : copy;
import std.meta : allSatisfy;
import std.range : ElementEncodingType, empty, front, isBidirectionalRange,
    isInputRange, isSomeFiniteCharInputRange, put;
import std.traits : isSomeChar, isSomeString, Unqual;
import std.typecons : Flag, No, Yes;

/++
If flag `KeepTerminator` is set to `KeepTerminator.yes`, then the delimiter
is included in the strings returned.
+/
alias KeepTerminator = Flag!"keepTerminator";

version (CRuntime_Microsoft)
{
}
else version (CRuntime_Glibc)
{
}
else version (CRuntime_Bionic)
{
    version = GENERIC_IO;
}
else version (CRuntime_Musl)
{
    version = GENERIC_IO;
}
else version (CRuntime_UClibc)
{
    version = GENERIC_IO;
}
else version (OSX)
{
    version = GENERIC_IO;
    version = Darwin;
}
else version (iOS)
{
    version = GENERIC_IO;
    version = Darwin;
}
else version (TVOS)
{
    version = GENERIC_IO;
    version = Darwin;
}
else version (WatchOS)
{
    version = GENERIC_IO;
    version = Darwin;
}
else version (FreeBSD)
{
    version = GENERIC_IO;
}
else version (NetBSD)
{
    version = GENERIC_IO;
}
else version (OpenBSD)
{
    version = GENERIC_IO;
}
else version (DragonFlyBSD)
{
    version = GENERIC_IO;
}
else version (Solaris)
{
    version = GENERIC_IO;
}
else
{
    static assert(0, "unsupported operating system");
}

// Character type used for operating system filesystem APIs
version (Windows)
{
    private alias FSChar = wchar;
}
else
{
    private alias FSChar = char;
}

private alias fileno_t = int;   // file descriptor, fildes, fileno

version (Windows)
{
    // core.stdc.stdio.fopen expects file names to be
    // encoded in CP_ACP on Windows instead of UTF-8.
    /+ Waiting for druntime pull 299
    +/
    extern (C) nothrow @nogc FILE* _wfopen(scope const wchar* filename, scope const wchar* mode);
    extern (C) nothrow @nogc FILE* _wfreopen(scope const wchar* filename, scope const wchar* mode, FILE* fp);

    import core.sys.windows.basetsd : HANDLE;
}

version (Posix)
{
    static import core.sys.posix.stdio; // getdelim, flockfile
}

version (CRuntime_Microsoft)
{
    private alias _FPUTC = _fputc_nolock;
    private alias _FPUTWC = _fputwc_nolock;
    private alias _FGETC = _fgetc_nolock;
    private alias _FGETWC = _fgetwc_nolock;
    private alias _FLOCK = _lock_file;
    private alias _FUNLOCK = _unlock_file;
}
else version (CRuntime_Glibc)
{
    private alias _FPUTC = fputc_unlocked;
    private alias _FPUTWC = fputwc_unlocked;
    private alias _FGETC = fgetc_unlocked;
    private alias _FGETWC = fgetwc_unlocked;
    private alias _FLOCK = core.sys.posix.stdio.flockfile;
    private alias _FUNLOCK = core.sys.posix.stdio.funlockfile;
}
else version (GENERIC_IO)
{
    nothrow:
    @nogc:

    extern (C) private
    {
        static import core.stdc.wchar_;

        pragma(mangle, fputc.mangleof) int _FPUTC(int c, _iobuf* fp);
        pragma(mangle, core.stdc.wchar_.fputwc.mangleof) int _FPUTWC(wchar_t c, _iobuf* fp);
        pragma(mangle, fgetc.mangleof) int _FGETC(_iobuf* fp);
        pragma(mangle, core.stdc.wchar_.fgetwc.mangleof) int _FGETWC(_iobuf* fp);
    }

    version (Posix)
    {
        private alias _FLOCK = core.sys.posix.stdio.flockfile;
        private alias _FUNLOCK = core.sys.posix.stdio.funlockfile;
    }
    else
    {
        static assert(0, "don't know how to lock files on GENERIC_IO");
    }
}
else
{
    static assert(0, "unsupported C I/O system");
}

private extern (C) @nogc nothrow
{
    pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted;
    pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted;
}

//------------------------------------------------------------------------------
private struct ByRecordImpl(Fields...)
{
private:
    import std.typecons : Tuple;

    File file;
    char[] line;
    Tuple!(Fields) current;
    string format;

public:
    this(File f, string format)
    {
        assert(f.isOpen);
        file = f;
        this.format = format;
        popFront(); // prime the range
    }

    /// Range primitive implementations.
    @property bool empty()
    {
        return !file.isOpen;
    }

    /// Ditto
    @property ref Tuple!(Fields) front()
    {
        return current;
    }

    /// Ditto
    void popFront()
    {
        import std.conv : text;
        import std.exception : enforce;
        import std.format.read : formattedRead;
        import std.string : chomp;

        enforce(file.isOpen, "ByRecord: File must be open");
        file.readln(line);
        if (!line.length)
        {
            file.detach();
        }
        else
        {
            line = chomp(line);
            formattedRead(line, format, &current);
            enforce(line.empty, text("Leftover characters in record: `",
                            line, "'"));
        }
    }
}

template byRecord(Fields...)
{
    auto byRecord(File f, string format)
    {
        return typeof(return)(f, format);
    }
}

/**
Encapsulates a `FILE*`. Generally D does not attempt to provide
thin wrappers over equivalent functions in the C standard library, but
manipulating `FILE*` values directly is unsafe and error-prone in
many ways. The `File` type ensures safe manipulation, automatic
file closing, and a lot of convenience.

The underlying `FILE*` handle is maintained in a reference-counted
manner, such that as soon as the last `File` variable bound to a
given `FILE*` goes out of scope, the underlying `FILE*` is
automatically closed.

Example:
----
// test.d
import std.stdio;

void main(string[] args)
{
    auto f = File("test.txt", "w"); // open for writing
    f.write("Hello");
    if (args.length > 1)
    {
        auto g = f; // now g and f write to the same file
                    // internal reference count is 2
        g.write(", ", args[1]);
        // g exits scope, reference count decreases to 1
    }
    f.writeln("!");
    // f exits scope, reference count falls to zero,
    // underlying `FILE*` is closed.
}
----
$(CONSOLE
% rdmd test.d Jimmy
% cat test.txt
Hello, Jimmy!
% __
)
 */
struct File
{
    import core.atomic : atomicOp, atomicStore, atomicLoad;
    import std.range.primitives : ElementEncodingType;
    import std.traits : isScalarType, isArray;
    enum Orientation { unknown, narrow, wide }

    private struct Impl
    {
        FILE * handle = null; // Is null iff this Impl is closed by another File
        shared uint refs = uint.max / 2;
        bool isPopened; // true iff the stream has been created by popen()
        Orientation orientation;
    }
    private Impl* _p;
    private string _name;

    package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted @nogc nothrow
    {
        import core.stdc.stdlib : malloc;

        assert(!_p);
        _p = cast(Impl*) malloc(Impl.sizeof);
        if (!_p)
        {
            import core.exception : onOutOfMemoryError;
            onOutOfMemoryError();
        }
        initImpl(handle, name, refs, isPopened);
    }

    private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false) @nogc nothrow pure @safe
    {
        assert(_p);
        _p.handle = handle;
        atomicStore(_p.refs, refs);
        _p.isPopened = isPopened;
        _p.orientation = Orientation.unknown;
        _name = name;
    }

/**
Constructor taking the name of the file to open and the open mode.

Copying one `File` object to another results in the two `File`
objects referring to the same underlying file.

The destructor automatically closes the file as soon as no `File`
object refers to it anymore.

Params:
    name = range or string representing the file _name
    stdioOpenmode = range or string represting the open mode
        (with the same semantics as in the C standard library
        $(CSTDIO fopen) function)

Throws: `ErrnoException` if the file could not be opened.
 */
    this(string name, scope const(char)[] stdioOpenmode = "rb") @safe
    {
        import std.conv : text;
        import std.exception : errnoEnforce;

        this(errnoEnforce(_fopen(name, stdioOpenmode),
                        text("Cannot open file `", name, "' in mode `",
                                stdioOpenmode, "'")),
                name);

        // MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422)
        version (CRuntime_Microsoft)
        {
            setAppendWin(stdioOpenmode);
        }
    }

    /// ditto
    this(R1, R2)(R1 name)
    if (isSomeFiniteCharInputRange!R1)
    {
        import std.conv : to;
        this(name.to!string, "rb");
    }

    /// ditto
    this(R1, R2)(R1 name, R2 mode)
    if (isSomeFiniteCharInputRange!R1 &&
        isSomeFiniteCharInputRange!R2)
    {
        import std.conv : to;
        this(name.to!string, mode.to!string);
    }

    @safe unittest
    {
        static import std.file;
        import std.utf : byChar;
        auto deleteme = testFilename();
        auto f = File(deleteme.byChar, "w".byChar);
        f.close();
        std.file.remove(deleteme);
    }

    ~this() @safe
    {
        detach();
    }

    this(this) @safe pure nothrow @nogc
    {
        if (!_p) return;
        assert(atomicLoad(_p.refs));
        atomicOp!"+="(_p.refs, 1);
    }

/**
Assigns a file to another. The target of the assignment gets detached
from whatever file it was attached to, and attaches itself to the new
file.
 */
    ref File opAssign(File rhs) @safe return
    {
        import std.algorithm.mutation : swap;

        swap(this, rhs);
        return this;
    }

     // https://issues.dlang.org/show_bug.cgi?id=20129
    @safe unittest
    {
        File[int] aa;
        aa.require(0, File.init);
    }

/**
Detaches from the current file (throwing on failure), and then attempts to
_open file `name` with mode `stdioOpenmode`. The mode has the
same semantics as in the C standard library $(CSTDIO fopen) function.

Throws: `ErrnoException` in case of error.
 */
    void open(string name, scope const(char)[] stdioOpenmode = "rb") @trusted
    {
        resetFile(name, stdioOpenmode, false);
    }

    // https://issues.dlang.org/show_bug.cgi?id=20585
    @system unittest
    {
        File f;
        try
            f.open("doesn't exist");
        catch (Exception _e)
        {
        }

        assert(!f.isOpen);

        f.close();  // to check not crash here
    }

    private void resetFile(string name, scope const(char)[] stdioOpenmode, bool isPopened) @trusted
    {
        import core.stdc.stdlib : malloc;
        import std.exception : enforce;
        import std.conv : text;
        import std.exception : errnoEnforce;

        if (_p !is null)
        {
            detach();
        }

        FILE* handle;
        version (Posix)
        {
            if (isPopened)
            {
                errnoEnforce(handle = _popen(name, stdioOpenmode),
                             "Cannot run command `"~name~"'");
            }
            else
            {
                errnoEnforce(handle = _fopen(name, stdioOpenmode),
                             text("Cannot open file `", name, "' in mode `",
                                  stdioOpenmode, "'"));
            }
        }
        else
        {
            assert(isPopened == false);
            errnoEnforce(handle = _fopen(name, stdioOpenmode),
                         text("Cannot open file `", name, "' in mode `",
                              stdioOpenmode, "'"));
        }
        _p = cast(Impl*) enforce(malloc(Impl.sizeof), "Out of memory");
        initImpl(handle, name, 1, isPopened);
        version (CRuntime_Microsoft)
        {
            setAppendWin(stdioOpenmode);
        }
    }

    private void closeHandles() @trusted
    {
        assert(_p);
        import std.exception : errnoEnforce;

        version (Posix)
        {
            import core.sys.posix.stdio : pclose;
            import std.format : format;

            if (_p.isPopened)
            {
                auto res = pclose(_p.handle);
                errnoEnforce(res != -1,
                        "Could not close pipe `"~_name~"'");
                _p.handle = null;
                return;
            }
        }
        if (_p.handle)
        {
            auto handle = _p.handle;
            _p.handle = null;
            // fclose disassociates the FILE* even in case of error (https://issues.dlang.org/show_bug.cgi?id=19751)
            errnoEnforce(.fclose(handle) == 0,
                    "Could not close file `"~_name~"'");
        }
    }

    version (CRuntime_Microsoft)
    {
        private void setAppendWin(scope const(char)[] stdioOpenmode) @safe
        {
            bool append, update;
            foreach (c; stdioOpenmode)
                if (c == 'a')
                    append = true;
                else
                if (c == '+')
                    update = true;
            if (append && !update)
                seek(size);
        }
    }

/**
Reuses the `File` object to either open a different file, or change
the file mode. If `name` is `null`, the mode of the currently open
file is changed; otherwise, a new file is opened, reusing the C
`FILE*`. The function has the same semantics as in the C standard
library $(CSTDIO freopen) function.

Note: Calling `reopen` with a `null` `name` is not implemented
in all C runtimes.

Throws: `ErrnoException` in case of error.
 */
    void reopen(string name, scope const(char)[] stdioOpenmode = "rb") @trusted
    {
        import std.conv : text;
        import std.exception : enforce, errnoEnforce;
        import std.internal.cstring : tempCString;

        enforce(isOpen, "Attempting to reopen() an unopened file");

        auto namez = (name == null ? _name : name).tempCString!FSChar();
        auto modez = stdioOpenmode.tempCString!FSChar();

        FILE* fd = _p.handle;
        version (Windows)
            fd =  _wfreopen(namez, modez, fd);
        else
            fd = freopen(namez, modez, fd);

        errnoEnforce(fd, name
            ? text("Cannot reopen file `", name, "' in mode `", stdioOpenmode, "'")
            : text("Cannot reopen file in mode `", stdioOpenmode, "'"));

        if (name !is null)
            _name = name;
    }

    @safe unittest // Test changing filename
    {
        import std.exception : assertThrown, assertNotThrown;
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "foo");
        scope(exit) std.file.remove(deleteme);
        auto f = File(deleteme);
        assert(f.readln() == "foo");

        auto deleteme2 = testFilename();
        std.file.write(deleteme2, "bar");
        scope(exit) std.file.remove(deleteme2);
        f.reopen(deleteme2);
        assert(f.name == deleteme2);
        assert(f.readln() == "bar");
        f.close();
    }

    version (CRuntime_Microsoft) {} else // Not implemented
    @safe unittest // Test changing mode
    {
        import std.exception : assertThrown, assertNotThrown;
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "foo");
        scope(exit) std.file.remove(deleteme);
        auto f = File(deleteme, "r+");
        assert(f.readln() == "foo");
        f.reopen(null, "w");
        f.write("bar");
        f.seek(0);
        f.reopen(null, "a");
        f.write("baz");
        assert(f.name == deleteme);
        f.close();
        assert(std.file.readText(deleteme) == "barbaz");
    }

/**
Detaches from the current file (throwing on failure), and then runs a command
by calling the C standard library function $(HTTP
pubs.opengroup.org/onlinepubs/7908799/xsh/popen.html, popen).

Throws: `ErrnoException` in case of error.
 */
    version (Posix) void popen(string command, scope const(char)[] stdioOpenmode = "r") @safe
    {
        resetFile(command, stdioOpenmode ,true);
    }

/**
First calls `detach` (throwing on failure), then attempts to
associate the given file descriptor with the `File`, and sets the file's name to `null`.

The mode must be compatible with the mode of the file descriptor.

Throws: `ErrnoException` in case of error.
Params:
    fd = File descriptor to associate with this `File`.
    stdioOpenmode = Mode to associate with this File. The mode has the same
        semantics as in the POSIX library function $(HTTP
        pubs.opengroup.org/onlinepubs/7908799/xsh/fdopen.html, fdopen)
        and must be compatible with `fd`.
 */
    void fdopen(int fd, scope const(char)[] stdioOpenmode = "rb") @safe
    {
        fdopen(fd, stdioOpenmode, null);
    }

    package void fdopen(int fd, scope const(char)[] stdioOpenmode, string name) @trusted
    {
        import std.exception : errnoEnforce;
        import std.internal.cstring : tempCString;

        auto modez = stdioOpenmode.tempCString();
        detach();

        version (CRuntime_Microsoft)
        {
            auto fp = _fdopen(fd, modez);
            errnoEnforce(fp);
        }
        else version (Posix)
        {
            import core.sys.posix.stdio : fdopen;
            auto fp = fdopen(fd, modez);
            errnoEnforce(fp);
        }
        else
            static assert(0, "no fdopen() available");

        this = File(fp, name);
    }

    // Declare a dummy HANDLE to allow generating documentation
    // for Windows-only methods.
    version (StdDdoc) { version (Windows) {} else alias HANDLE = int; }

/**
First calls `detach` (throwing on failure), and then attempts to
associate the given Windows `HANDLE` with the `File`. The mode must
be compatible with the access attributes of the handle. Windows only.

Throws: `ErrnoException` in case of error.
*/
    version (StdDdoc)
    void windowsHandleOpen(HANDLE handle, scope const(char)[] stdioOpenmode);

    version (Windows)
    void windowsHandleOpen(HANDLE handle, scope const(char)[] stdioOpenmode)
    {
        import core.stdc.stdint : intptr_t;
        import std.exception : errnoEnforce;
        import std.format : format;

        // Create file descriptors from the handles
        int mode;
        modeLoop:
        foreach (c; stdioOpenmode)
            switch (c)
            {
                case 'r': mode |= _O_RDONLY; break;
                case '+': mode &=~_O_RDONLY; break;
                case 'a': mode |= _O_APPEND; break;
                case 'b': mode |= _O_BINARY; break;
                case 't': mode |= _O_TEXT;   break;
                case ',': break modeLoop;
                default: break;
            }

        auto fd = _open_osfhandle(cast(intptr_t) handle, mode);

        errnoEnforce(fd >= 0, "Cannot open Windows HANDLE");
        fdopen(fd, stdioOpenmode, "HANDLE(%s)".format(handle));
    }


/** Returns `true` if the file is opened. */
    @property bool isOpen() const @safe pure nothrow
    {
        return _p !is null && _p.handle;
    }

/**
Returns `true` if the file is at end (see $(CSTDIO feof)).

Throws: `Exception` if the file is not opened.
 */
    @property bool eof() const @trusted pure
    {
        import std.exception : enforce;

        enforce(_p && _p.handle, "Calling eof() against an unopened file.");
        return .feof(cast(FILE*) _p.handle) != 0;
    }

/**
 Returns the name last used to initialize this `File`, if any.

 Some functions that create or initialize the `File` set the name field to `null`.
 Examples include $(LREF tmpfile), $(LREF wrapFile), and $(LREF fdopen). See the
 documentation of those functions for details.

 Returns: The name last used to initialize this this file, or `null` otherwise.
 */
    @property string name() const @safe pure nothrow return
    {
        return _name;
    }

/**
If the file is closed or not yet opened, returns `true`. Otherwise, returns
$(CSTDIO ferror) for the file handle.
 */
    @property bool error() const @trusted pure nothrow
    {
        return !isOpen || .ferror(cast(FILE*) _p.handle);
    }

    @safe unittest
    {
        // https://issues.dlang.org/show_bug.cgi?id=12349
        static import std.file;
        auto deleteme = testFilename();
        auto f = File(deleteme, "w");
        scope(exit) std.file.remove(deleteme);

        f.close();
        assert(f.error);
    }

/**
Detaches from the underlying file. If the sole owner, calls `close`.

Throws: `ErrnoException` on failure if closing the file.
  */
    void detach() @trusted
    {
        import core.stdc.stdlib : free;

        if (!_p) return;
        scope(exit) _p = null;

        if (atomicOp!"-="(_p.refs, 1) == 0)
        {
            scope(exit) free(_p);
            closeHandles();
        }
    }

    @safe unittest
    {
        static import std.file;

        auto deleteme = testFilename();
        scope(exit) std.file.remove(deleteme);
        auto f = File(deleteme, "w");
        {
            auto f2 = f;
            f2.detach();
        }
        assert(f._p.refs == 1);
        f.close();
    }

/**
If the file was closed or not yet opened, succeeds vacuously. Otherwise
closes the file (by calling $(CSTDIO fclose)),
throwing on error. Even if an exception is thrown, afterwards the $(D
File) object is empty. This is different from `detach` in that it
always closes the file; consequently, all other `File` objects
referring to the same handle will see a closed file henceforth.

Throws: `ErrnoException` on error.
 */
    void close() @trusted
    {
        import core.stdc.stdlib : free;
        import std.exception : errnoEnforce;

        if (!_p) return; // succeed vacuously
        scope(exit)
        {
            if (atomicOp!"-="(_p.refs, 1) == 0)
                free(_p);
            _p = null; // start a new life
        }
        if (!_p.handle) return; // Impl is closed by another File

        scope(exit) _p.handle = null; // nullify the handle anyway
        closeHandles();
    }

/**
If the file is closed or not yet opened, succeeds vacuously. Otherwise, returns
$(CSTDIO clearerr) for the file handle.
 */
    void clearerr() @safe pure nothrow
    {
        _p is null || _p.handle is null ||
        .clearerr(_p.handle);
    }

/**
Flushes the C `FILE` buffers.

Calls $(CSTDIO fflush) for the file handle.

Throws: `Exception` if the file is not opened or if the call to `fflush` fails.
 */
    void flush() @trusted
    {
        import std.exception : enforce, errnoEnforce;

        enforce(isOpen, "Attempting to flush() in an unopened file");
        errnoEnforce(.fflush(_p.handle) == 0);
    }

    @safe unittest
    {
        // https://issues.dlang.org/show_bug.cgi?id=12349
        import std.exception : assertThrown;
        static import std.file;

        auto deleteme = testFilename();
        auto f = File(deleteme, "w");
        scope(exit) std.file.remove(deleteme);

        f.close();
        assertThrown(f.flush());
    }

/**
Forces any data buffered by the OS to be written to disk.
Call $(LREF flush) before calling this function to flush the C `FILE` buffers first.

This function calls
$(HTTP msdn.microsoft.com/en-us/library/windows/desktop/aa364439%28v=vs.85%29.aspx,
`FlushFileBuffers`) on Windows,
$(HTTP developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html,
`F_FULLFSYNC fcntl`) on Darwin and
$(HTTP pubs.opengroup.org/onlinepubs/7908799/xsh/fsync.html,
`fsync`) on POSIX for the file handle.

Throws: `Exception` if the file is not opened or if the OS call fails.
 */
    void sync() @trusted
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to sync() an unopened file");

        version (Windows)
        {
            import core.sys.windows.winbase : FlushFileBuffers;
            wenforce(FlushFileBuffers(windowsHandle), "FlushFileBuffers failed");
        }
        else version (Darwin)
        {
            import core.sys.darwin.fcntl : fcntl, F_FULLFSYNC;
            import std.exception : errnoEnforce;
            errnoEnforce(fcntl(fileno, F_FULLFSYNC, 0) != -1, "fcntl failed");
        }
        else
        {
            import core.sys.posix.unistd : fsync;
            import std.exception : errnoEnforce;
            errnoEnforce(fsync(fileno) == 0, "fsync failed");
        }
    }

/**
Calls $(CSTDIO fread) for the
file handle. The number of items to read and the size of
each item is inferred from the size and type of the input array, respectively.

Returns: The slice of `buffer` containing the data that was actually read.
This will be shorter than `buffer` if EOF was reached before the buffer
could be filled. If the buffer is empty, it will be returned.

Throws: `ErrnoException` if the file is not opened or the call to `fread` fails.

`rawRead` always reads in binary mode on Windows.
 */
    T[] rawRead(T)(T[] buffer)
    {
        import std.exception : enforce, errnoEnforce;

        if (!buffer.length)
            return buffer;
        enforce(isOpen, "Attempting to read from an unopened file");
        version (Windows)
        {
            immutable fileno_t fd = .fileno(_p.handle);
            immutable mode = ._setmode(fd, _O_BINARY);
            scope(exit) ._setmode(fd, mode);
        }
        immutable freadResult = trustedFread(_p.handle, buffer);
        assert(freadResult <= buffer.length); // fread return guarantee
        if (freadResult != buffer.length) // error or eof
        {
            errnoEnforce(!error);
            return buffer[0 .. freadResult];
        }
        return buffer;
    }

    ///
    @system unittest
    {
        static import std.file;

        auto testFile = std.file.deleteme();
        std.file.write(testFile, "\r\n\n\r\n");
        scope(exit) std.file.remove(testFile);

        auto f = File(testFile, "r");
        auto buf = f.rawRead(new char[5]);
        f.close();
        assert(buf == "\r\n\n\r\n");
    }

    // https://issues.dlang.org/show_bug.cgi?id=24685
    static assert(!__traits(compiles, (File f) @safe { int*[1] bar; f.rawRead(bar[]); }));

    // https://issues.dlang.org/show_bug.cgi?id=21729
    @system unittest
    {
        import std.exception : assertThrown;

        File f;
        ubyte[1] u;
        assertThrown(f.rawRead(u));
    }

    // https://issues.dlang.org/show_bug.cgi?id=21728
    @system unittest
    {
        static if (__traits(compiles, { import std.process : pipe; })) // not available for iOS
        {
            import std.process : pipe;
            import std.exception : assertThrown;

            auto p = pipe();
            p.readEnd.close;
            ubyte[1] u;
            assertThrown(p.readEnd.rawRead(u));
        }
    }

    // https://issues.dlang.org/show_bug.cgi?id=13893
    @system unittest
    {
        import std.exception : assertNotThrown;

        File f;
        ubyte[0] u;
        assertNotThrown(f.rawRead(u));
    }

/**
Calls $(CSTDIO fwrite) for the file
handle. The number of items to write and the size of each
item is inferred from the size and type of the input array, respectively. An
error is thrown if the buffer could not be written in its entirety.

`rawWrite` always writes in binary mode on Windows.

Throws: `ErrnoException` if the file is not opened or if the call to `fwrite` fails.
 */
    void rawWrite(T)(in T[] buffer)
    {
        import std.conv : text;
        import std.exception : errnoEnforce;

        version (Windows)
        {
            immutable fileno_t fd = .fileno(_p.handle);
            immutable oldMode = ._setmode(fd, _O_BINARY);

            if (oldMode != _O_BINARY)
            {
                // need to flush the data that was written with the original mode
                ._setmode(fd, oldMode);
                flush(); // before changing translation mode ._setmode(fd, _O_BINARY);
                ._setmode(fd, _O_BINARY);
            }

            scope (exit)
            {
                if (oldMode != _O_BINARY)
                {
                    flush();
                    ._setmode(fd, oldMode);
                }
            }
        }

        auto result = trustedFwrite(_p.handle, buffer);
        if (result == result.max) result = 0;
        errnoEnforce(result == buffer.length,
                text("Wrote ", result, " instead of ", buffer.length,
                        " objects of type ", T.stringof, " to file `",
                        _name, "'"));
    }

    ///
    @system unittest
    {
        static import std.file;

        auto testFile = std.file.deleteme();
        auto f = File(testFile, "w");
        scope(exit) std.file.remove(testFile);

        f.rawWrite("\r\n\n\r\n");
        f.close();
        assert(std.file.read(testFile) == "\r\n\n\r\n");
    }

/**
Calls $(CSTDIO fseek)
for the file handle to move its position indicator.

Params:
    offset = Binary files: Number of bytes to offset from origin.$(BR)
             Text files: Either zero, or a value returned by $(LREF tell).
    origin = Binary files: Position used as reference for the offset, must be
             one of $(REF_ALTTEXT SEEK_SET, SEEK_SET, core,stdc,stdio),
             $(REF_ALTTEXT SEEK_CUR, SEEK_CUR, core,stdc,stdio) or
             $(REF_ALTTEXT SEEK_END, SEEK_END, core,stdc,stdio).$(BR)
             Text files: Shall necessarily be
             $(REF_ALTTEXT SEEK_SET, SEEK_SET, core,stdc,stdio).

Throws: `Exception` if the file is not opened.
        `ErrnoException` if the call to `fseek` fails.
 */
    void seek(long offset, int origin = SEEK_SET) @trusted
    {
        import std.conv : to, text;
        import std.exception : enforce, errnoEnforce;

        // Some libc sanitize the whence input (e.g. glibc), but some don't,
        // e.g. Microsoft runtime crashes on an invalid origin,
        // and Musl additionally accept SEEK_DATA & SEEK_HOLE (Linux extension).
        // To provide a consistent behavior cross platform, we use the glibc check
        // See also https://issues.dlang.org/show_bug.cgi?id=19797
        enforce(origin == SEEK_SET || origin == SEEK_CUR ||  origin == SEEK_END,
                "Invalid `origin` argument passed to `seek`, must be one of: SEEK_SET, SEEK_CUR, SEEK_END");

        enforce(isOpen, "Attempting to seek() in an unopened file");
        version (Windows)
        {
            version (CRuntime_Microsoft)
            {
                alias fseekFun = _fseeki64;
                alias off_t = long;
            }
            else
            {
                alias fseekFun = fseek;
                alias off_t = int;
            }
        }
        else version (Posix)
        {
            import core.sys.posix.stdio : fseeko, off_t;
            alias fseekFun = fseeko;
        }
        errnoEnforce(fseekFun(_p.handle, to!off_t(offset), origin) == 0,
                "Could not seek in file `"~_name~"'");
    }

    @system unittest
    {
        import std.conv : text;
        static import std.file;
        import std.exception;

        auto deleteme = testFilename();
        auto f = File(deleteme, "w+");
        scope(exit) { f.close(); std.file.remove(deleteme); }
        f.rawWrite("abcdefghijklmnopqrstuvwxyz");
        f.seek(7);
        assert(f.readln() == "hijklmnopqrstuvwxyz");

        version (CRuntime_Bionic)
            auto bigOffset = int.max - 100;
        else
            auto bigOffset = cast(ulong) int.max + 100;
        f.seek(bigOffset);
        assert(f.tell == bigOffset, text(f.tell));
        // Uncomment the tests below only if you want to wait for
        // a long time
        // f.rawWrite("abcdefghijklmnopqrstuvwxyz");
        // f.seek(-3, SEEK_END);
        // assert(f.readln() == "xyz");

        assertThrown(f.seek(0, ushort.max));
    }

/**
Calls $(CSTDIO ftell)
for the managed file handle, which returns the current value of
the position indicator of the file handle.

Throws: `Exception` if the file is not opened.
        `ErrnoException` if the call to `ftell` fails.
 */
    @property ulong tell() const @trusted
    {
        import std.exception : enforce, errnoEnforce;

        enforce(isOpen, "Attempting to tell() in an unopened file");
        version (Windows)
        {
            version (CRuntime_Microsoft)
                immutable result = _ftelli64(cast(FILE*) _p.handle);
            else
                immutable result = ftell(cast(FILE*) _p.handle);
        }
        else version (Posix)
        {
            import core.sys.posix.stdio : ftello;
            immutable result = ftello(cast(FILE*) _p.handle);
        }
        errnoEnforce(result != -1,
                "Query ftell() failed for file `"~_name~"'");
        return result;
    }

    ///
    @system unittest
    {
        import std.conv : text;
        static import std.file;

        auto testFile = std.file.deleteme();
        std.file.write(testFile, "abcdefghijklmnopqrstuvwqxyz");
        scope(exit) { std.file.remove(testFile); }

        auto f = File(testFile);
        auto a = new ubyte[4];
        f.rawRead(a);
        assert(f.tell == 4, text(f.tell));
    }

/**
Calls $(CSTDIO rewind) for the file handle.

Throws: `Exception` if the file is not opened.
 */
    void rewind() @safe
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to rewind() an unopened file");
        .rewind(_p.handle);
    }

/**
Calls $(CSTDIO setvbuf) for the file handle.

Throws: `Exception` if the file is not opened.
        `ErrnoException` if the call to `setvbuf` fails.
 */
    void setvbuf(size_t size, int mode = _IOFBF) @trusted
    {
        import std.exception : enforce, errnoEnforce;

        enforce(isOpen, "Attempting to call setvbuf() on an unopened file");
        errnoEnforce(.setvbuf(_p.handle, null, mode, size) == 0,
                "Could not set buffering for file `"~_name~"'");
    }

/**
Calls $(CSTDIO setvbuf) for the file handle.

Throws: `Exception` if the file is not opened.
        `ErrnoException` if the call to `setvbuf` fails.
*/
    void setvbuf(void[] buf, int mode = _IOFBF) @trusted
    {
        import std.exception : enforce, errnoEnforce;

        enforce(isOpen, "Attempting to call setvbuf() on an unopened file");
        errnoEnforce(.setvbuf(_p.handle,
                        cast(char*) buf.ptr, mode, buf.length) == 0,
                "Could not set buffering for file `"~_name~"'");
    }


    version (Windows)
    {
        import core.sys.windows.winbase : OVERLAPPED;
        import core.sys.windows.winnt : BOOL, ULARGE_INTEGER;
        import std.windows.syserror : wenforce;

        private BOOL lockImpl(alias F, Flags...)(ulong start, ulong length,
            Flags flags)
        {
            if (!start && !length)
                length = ulong.max;
            ULARGE_INTEGER liStart = void, liLength = void;
            liStart.QuadPart = start;
            liLength.QuadPart = length;
            OVERLAPPED overlapped;
            overlapped.Offset = liStart.LowPart;
            overlapped.OffsetHigh = liStart.HighPart;
            overlapped.hEvent = null;
            return F(windowsHandle, flags, 0, liLength.LowPart,
                liLength.HighPart, &overlapped);
        }
    }
    version (Posix)
    {
        private int lockImpl(int operation, short l_type,
            ulong start, ulong length)
        {
            import core.sys.posix.fcntl : fcntl, flock, off_t;
            import core.sys.posix.unistd : getpid;
            import std.conv : to;

            flock fl = void;
            fl.l_type   = l_type;
            fl.l_whence = SEEK_SET;
            fl.l_start  = to!off_t(start);
            fl.l_len    = to!off_t(length);
            fl.l_pid    = getpid();
            return fcntl(fileno, operation, &fl);
        }
    }

/**
Locks the specified file segment. If the file segment is already locked
by another process, waits until the existing lock is released.
If both `start` and `length` are zero, the entire file is locked.

Locks created using `lock` and `tryLock` have the following properties:
$(UL
 $(LI All locks are automatically released when the process terminates.)
 $(LI Locks are not inherited by child processes.)
 $(LI Closing a file will release all locks associated with the file. On POSIX,
      even locks acquired via a different `File` will be released as well.)
 $(LI Not all NFS implementations correctly implement file locking.)
)
 */
    void lock(LockType lockType = LockType.readWrite,
        ulong start = 0, ulong length = 0)
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to call lock() on an unopened file");
        version (Posix)
        {
            import core.sys.posix.fcntl : F_RDLCK, F_SETLKW, F_WRLCK;
            import std.exception : errnoEnforce;
            immutable short type = lockType == LockType.readWrite
                ? F_WRLCK : F_RDLCK;
            errnoEnforce(lockImpl(F_SETLKW, type, start, length) != -1,
                    "Could not set lock for file `"~_name~"'");
        }
        else
        version (Windows)
        {
            import core.sys.windows.winbase : LockFileEx, LOCKFILE_EXCLUSIVE_LOCK;
            immutable type = lockType == LockType.readWrite ?
                LOCKFILE_EXCLUSIVE_LOCK : 0;
            wenforce(lockImpl!LockFileEx(start, length, type),
                    "Could not set lock for file `"~_name~"'");
        }
        else
            static assert(false);
    }

/**
Attempts to lock the specified file segment.
If both `start` and `length` are zero, the entire file is locked.
Returns: `true` if the lock was successful, and `false` if the
specified file segment was already locked.
 */
    bool tryLock(LockType lockType = LockType.readWrite,
        ulong start = 0, ulong length = 0)
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to call tryLock() on an unopened file");
        version (Posix)
        {
            import core.stdc.errno : EACCES, EAGAIN, errno;
            import core.sys.posix.fcntl : F_RDLCK, F_SETLK, F_WRLCK;
            import std.exception : errnoEnforce;
            immutable short type = lockType == LockType.readWrite
                ? F_WRLCK : F_RDLCK;
            immutable res = lockImpl(F_SETLK, type, start, length);
            if (res == -1 && (errno == EACCES || errno == EAGAIN))
                return false;
            errnoEnforce(res != -1, "Could not set lock for file `"~_name~"'");
            return true;
        }
        else
        version (Windows)
        {
            import core.sys.windows.winbase : GetLastError, LockFileEx, LOCKFILE_EXCLUSIVE_LOCK,
                LOCKFILE_FAIL_IMMEDIATELY;
            import core.sys.windows.winerror : ERROR_IO_PENDING, ERROR_LOCK_VIOLATION;
            immutable type = lockType == LockType.readWrite
                ? LOCKFILE_EXCLUSIVE_LOCK : 0;
            immutable res = lockImpl!LockFileEx(start, length,
                type | LOCKFILE_FAIL_IMMEDIATELY);
            if (!res && (GetLastError() == ERROR_IO_PENDING
                || GetLastError() == ERROR_LOCK_VIOLATION))
                return false;
            wenforce(res, "Could not set lock for file `"~_name~"'");
            return true;
        }
        else
            static assert(false);
    }

/**
Removes the lock over the specified file segment.
 */
    void unlock(ulong start = 0, ulong length = 0)
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to call unlock() on an unopened file");
        version (Posix)
        {
            import core.sys.posix.fcntl : F_SETLK, F_UNLCK;
            import std.exception : errnoEnforce;
            errnoEnforce(lockImpl(F_SETLK, F_UNLCK, start, length) != -1,
                    "Could not remove lock for file `"~_name~"'");
        }
        else
        version (Windows)
        {
            import core.sys.windows.winbase : UnlockFileEx;
            wenforce(lockImpl!UnlockFileEx(start, length),
                "Could not remove lock for file `"~_name~"'");
        }
        else
            static assert(false);
    }

    version (Windows)
    @system unittest
    {
        static import std.file;
        auto deleteme = testFilename();
        scope(exit) std.file.remove(deleteme);
        auto f = File(deleteme, "wb");
        assert(f.tryLock());
        auto g = File(deleteme, "wb");
        assert(!g.tryLock());
        assert(!g.tryLock(LockType.read));
        f.unlock();
        f.lock(LockType.read);
        assert(!g.tryLock());
        assert(g.tryLock(LockType.read));
        f.unlock();
        g.unlock();
    }

    version (Posix)
    @system unittest
    {
    static if (__traits(compiles, { import std.process : spawnProcess; }))
    {
        static import std.file;
        auto deleteme = testFilename();
        scope(exit) std.file.remove(deleteme);

        // Since locks are per-process, we cannot test lock failures within
        // the same process. fork() is used to create a second process.
        static void runForked(void delegate() code)
        {
            import core.sys.posix.sys.wait : waitpid;
            import core.sys.posix.unistd : fork, _exit;
            int child, status;
            if ((child = fork()) == 0)
            {
                code();
                _exit(0);
            }
            else
            {
                assert(waitpid(child, &status, 0) != -1);
                assert(status == 0, "Fork crashed");
            }
        }

        auto f = File(deleteme, "w+b");

        runForked
        ({
            auto g = File(deleteme, "a+b");
            assert(g.tryLock());
            g.unlock();
            assert(g.tryLock(LockType.read));
        });

        assert(f.tryLock());
        runForked
        ({
            auto g = File(deleteme, "a+b");
            assert(!g.tryLock());
            assert(!g.tryLock(LockType.read));
        });
        f.unlock();

        f.lock(LockType.read);
        runForked
        ({
            auto g = File(deleteme, "a+b");
            assert(!g.tryLock());
            assert(g.tryLock(LockType.read));
            g.unlock();
        });
        f.unlock();
    } // static if
    } // unittest


/**
Writes its arguments in text format to the file.

Throws: `Exception` if the file is not opened.
        `ErrnoException` on an error writing to the file.
*/
    void write(S...)(S args)
    {
        import std.traits : isBoolean, isIntegral, isAggregateType;
        import std.utf : UTFException;
        auto w = lockingTextWriter();
        foreach (arg; args)
        {
            try
            {
                alias A = typeof(arg);
                static if (isAggregateType!A || is(A == enum))
                {
                    import std.format.write : formattedWrite;

                    formattedWrite(w, "%s", arg);
                }
                else static if (isSomeString!A)
                {
                    put(w, arg);
                }
                else static if (isIntegral!A)
                {
                    import std.conv : toTextRange;

                    toTextRange(arg, w);
                }
                else static if (isBoolean!A)
                {
                    put(w, arg ? "true" : "false");
                }
                else static if (isSomeChar!A)
                {
                    put(w, arg);
                }
                else
                {
                    import std.format.write : formattedWrite;

                    // Most general case
                    formattedWrite(w, "%s", arg);
                }
            }
            catch (UTFException e)
            {
                /* Reset the writer so that it doesn't throw another
                UTFException on destruction. */
                w.highSurrogate = '\0';
                throw e;
            }
        }
    }

/**
Writes its arguments in text format to the file, followed by a newline.

Throws: `Exception` if the file is not opened.
        `ErrnoException` on an error writing to the file.
*/
    void writeln(S...)(S args)
    {
        write(args, '\n');
    }

/**
Writes its arguments in text format to the file, according to the
format string fmt.

Params:
fmt = The $(REF_ALTTEXT format string, formattedWrite, std, _format).
When passed as a compile-time argument, the string will be statically checked
against the argument types passed.
args = Items to write.

Throws: `Exception` if the file is not opened.
        `ErrnoException` on an error writing to the file.
*/
    void writef(alias fmt, A...)(A args)
    if (isSomeString!(typeof(fmt)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(fmt, A);
        static assert(!e, e);
        return this.writef(fmt, args);
    }

    /// ditto
    void writef(Char, A...)(in Char[] fmt, A args)
    {
        import std.format.write : formattedWrite;

        formattedWrite(lockingTextWriter(), fmt, args);
    }

    /// Equivalent to `file.writef(fmt, args, '\n')`.
    void writefln(alias fmt, A...)(A args)
    if (isSomeString!(typeof(fmt)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(fmt, A);
        static assert(!e, e);
        return this.writefln(fmt, args);
    }

    /// ditto
    void writefln(Char, A...)(in Char[] fmt, A args)
    {
        import std.format.write : formattedWrite;

        auto w = lockingTextWriter();
        formattedWrite(w, fmt, args);
        w.put('\n');
    }

/**
Read line from the file handle and return it as a specified type.

This version manages its own read buffer, which means one memory allocation per call. If you are not
retaining a reference to the read data, consider the `File.readln(buf)` version, which may offer
better performance as it can reuse its read buffer.

Params:
    S = Template parameter; the type of the allocated buffer, and the type returned. Defaults to `string`.
    terminator = Line terminator (by default, `'\n'`).

Note:
    String terminators are not supported due to ambiguity with readln(buf) below.

Returns:
    The line that was read, including the line terminator character.

Throws:
    `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.

Example:
---
// Reads `stdin` and writes it to `stdout`.
import std.stdio;

void main()
{
    string line;
    while ((line = stdin.readln()) !is null)
        write(line);
}
---
*/
    S readln(S = string)(dchar terminator = '\n') @safe
    if (isSomeString!S)
    {
        Unqual!(ElementEncodingType!S)[] buf;
        readln(buf, terminator);
        return (() @trusted => cast(S) buf)();
    }

    @safe unittest
    {
        import std.algorithm.comparison : equal;
        static import std.file;
        import std.meta : AliasSeq;

        auto deleteme = testFilename();
        std.file.write(deleteme, "hello\nworld\n");
        scope(exit) std.file.remove(deleteme);
        static foreach (String; AliasSeq!(string, char[], wstring, wchar[], dstring, dchar[]))
        {{
            auto witness = [ "hello\n", "world\n" ];
            auto f = File(deleteme);
            uint i = 0;
            String buf;
            while ((buf = f.readln!String()).length)
            {
                assert(i < witness.length);
                assert(equal(buf, witness[i++]));
            }
            assert(i == witness.length);
        }}
    }

    @safe unittest
    {
        static import std.file;
        import std.typecons : Tuple;

        auto deleteme = testFilename();
        std.file.write(deleteme, "cześć \U0002000D");
        scope(exit) std.file.remove(deleteme);
        uint[] lengths = [12,8,7];
        static foreach (uint i, C; Tuple!(char, wchar, dchar).Types)
        {{
            immutable(C)[] witness = "cześć \U0002000D";
            auto buf = File(deleteme).readln!(immutable(C)[])();
            assert(buf.length == lengths[i]);
            assert(buf == witness);
        }}
    }

/**
Read line from the file handle and write it to `buf[]`, including
terminating character.

This can be faster than $(D line = File.readln()) because you can reuse
the buffer for each call. Note that reusing the buffer means that you
must copy the previous contents if you wish to retain them.

Params:
buf = Buffer used to store the resulting line data. buf is
enlarged if necessary, then set to the slice exactly containing the line.
terminator = Line terminator (by default, `'\n'`). Use
$(REF newline, std,ascii) for portability (unless the file was opened in
text mode).

Returns:
0 for end of file, otherwise number of characters read.
The return value will always be equal to `buf.length`.

Throws: `StdioException` on I/O error, or `UnicodeException` on Unicode
conversion error.

Example:
---
// Read lines from `stdin` into a string
// Ignore lines starting with '#'
// Write the string to `stdout`
import std.stdio;

void main()
{
    string output;
    char[] buf;

    while (stdin.readln(buf))
    {
        if (buf[0] == '#')
            continue;

        output ~= buf;
    }

    write(output);
}
---

This method can be more efficient than the one in the previous example
because `stdin.readln(buf)` reuses (if possible) memory allocated
for `buf`, whereas $(D line = stdin.readln()) makes a new memory allocation
for every line.

For even better performance you can help `readln` by passing in a
large buffer to avoid memory reallocations. This can be done by reusing the
largest buffer returned by `readln`:

Example:
---
// Read lines from `stdin` and count words
import std.array, std.stdio;

void main()
{
    char[] buf;
    size_t words = 0;

    while (!stdin.eof)
    {
        char[] line = buf;
        stdin.readln(line);
        if (line.length > buf.length)
            buf = line;

        words += line.split.length;
    }

    writeln(words);
}
---
This is actually what $(LREF byLine) does internally, so its usage
is recommended if you want to process a complete file.
*/
    size_t readln(C)(ref C[] buf, dchar terminator = '\n') @safe
    if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
    {
        import std.exception : enforce;

        static if (is(C == char))
        {
            enforce(_p && _p.handle, "Attempt to read from an unopened file.");
            if (_p.orientation == Orientation.unknown)
            {
                import core.stdc.wchar_ : fwide;
                auto w = fwide(_p.handle, 0);
                if (w < 0) _p.orientation = Orientation.narrow;
                else if (w > 0) _p.orientation = Orientation.wide;
            }
            return readlnImpl(_p.handle, buf, terminator, _p.orientation);
        }
        else
        {
            string s = readln(terminator);
            if (!s.length)
            {
                buf = buf[0 .. 0];
                return 0;
            }

            import std.utf : codeLength;
            buf.length = codeLength!C(s);
            size_t idx;
            foreach (C c; s)
                buf[idx++] = c;

            return buf.length;
        }
    }

    @safe unittest
    {
        static import std.file;
        auto deleteme = testFilename();
        std.file.write(deleteme, "123\n456789");
        scope(exit) std.file.remove(deleteme);

        auto file = File(deleteme);
        char[] buffer = new char[10];
        char[] line = buffer;
        file.readln(line);
        auto beyond = line.length;
        buffer[beyond] = 'a';
        file.readln(line); // should not write buffer beyond line
        assert(buffer[beyond] == 'a');
    }

    // https://issues.dlang.org/show_bug.cgi?id=15293
    @safe unittest
    {
        // @system due to readln
        static import std.file;
        auto deleteme = testFilename();
        std.file.write(deleteme, "a\n\naa");
        scope(exit) std.file.remove(deleteme);

        auto file = File(deleteme);
        char[] buffer;
        char[] line;

        file.readln(buffer, '\n');

        line = buffer;
        file.readln(line, '\n');

        line = buffer;
        file.readln(line, '\n');

        assert(line[0 .. 1].capacity == 0);
    }

/** ditto */
    size_t readln(C, R)(ref C[] buf, R terminator) @safe
    if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
        isBidirectionalRange!R && is(typeof(terminator.front == dchar.init)))
    {
        import std.algorithm.mutation : swap;
        import std.algorithm.searching : endsWith;
        import std.range.primitives : back;

        auto last = terminator.back;
        C[] buf2;
        swap(buf, buf2);
        for (;;)
        {
            if (!readln(buf2, last) || endsWith(buf2, terminator))
            {
                if (buf.empty)
                {
                    buf = buf2;
                }
                else
                {
                    buf ~= buf2;
                }
                break;
            }
            buf ~= buf2;
        }
        return buf.length;
    }

    @safe unittest
    {
        static import std.file;
        import std.typecons : Tuple;

        auto deleteme = testFilename();
        std.file.write(deleteme, "hello\n\rworld\nhow\n\rare ya");
        scope(exit) std.file.remove(deleteme);
        foreach (C; Tuple!(char, wchar, dchar).Types)
        {
            immutable(C)[][] witness = [ "hello\n\r", "world\nhow\n\r", "are ya" ];
            auto f = File(deleteme);
            uint i = 0;
            C[] buf;
            while (f.readln(buf, "\n\r"))
            {
                assert(i < witness.length);
                assert(buf == witness[i++]);
            }
            assert(buf.length == 0);
        }
    }

    /**
     * Reads formatted _data from the file using $(REF formattedRead, std,_format).
     * Params:
     * format = The $(REF_ALTTEXT format string, formattedWrite, std, _format).
     * When passed as a compile-time argument, the string will be statically checked
     * against the argument types passed.
     * data = Items to be read.
     * Returns:
     *      Same as `formattedRead`: The number of variables filled. If the input range `r` ends early,
     *      this number will be less than the number of variables provided.
     * Example:
----
// test.d
void main()
{
    import std.stdio;
    auto f = File("input");
    foreach (_; 0 .. 3)
    {
        int a;
        f.readf!" %d"(a);
        writeln(++a);
    }
}
----
$(CONSOLE
% echo "1 2 3" > input
% rdmd test.d
2
3
4
)
     */
    uint readf(alias format, Data...)(auto ref Data data)
    if (isSomeString!(typeof(format)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(format, Data);
        static assert(!e, e);
        return this.readf(format, data);
    }

    /// ditto
    uint readf(Data...)(scope const(char)[] format, auto ref Data data)
    {
        import std.format.read : formattedRead;

        assert(isOpen);
        auto input = LockingTextReader(this);
        return formattedRead(input, format, data);
    }

    ///
    @system unittest
    {
        static import std.file;

        auto deleteme = std.file.deleteme();
        std.file.write(deleteme, "hello\nworld\ntrue\nfalse\n");
        scope(exit) std.file.remove(deleteme);
        string s;
        auto f = File(deleteme);
        f.readf!"%s\n"(s);
        assert(s == "hello", "["~s~"]");
        f.readf("%s\n", s);
        assert(s == "world", "["~s~"]");

        bool b1, b2;
        f.readf("%s\n%s\n", b1, b2);
        assert(b1 == true && b2 == false);
    }

    // backwards compatibility with pointers
    @system unittest
    {
        // @system due to readf
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "hello\nworld\ntrue\nfalse\n");
        scope(exit) std.file.remove(deleteme);
        string s;
        auto f = File(deleteme);
        f.readf("%s\n", &s);
        assert(s == "hello", "["~s~"]");
        f.readf("%s\n", &s);
        assert(s == "world", "["~s~"]");

        // https://issues.dlang.org/show_bug.cgi?id=11698
        bool b1, b2;
        f.readf("%s\n%s\n", &b1, &b2);
        assert(b1 == true && b2 == false);
    }

    // backwards compatibility (mixed)
    @system unittest
    {
        // @system due to readf
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "hello\nworld\ntrue\nfalse\n");
        scope(exit) std.file.remove(deleteme);
        string s1, s2;
        auto f = File(deleteme);
        f.readf("%s\n%s\n", s1, &s2);
        assert(s1 == "hello");
        assert(s2 == "world");

        // https://issues.dlang.org/show_bug.cgi?id=11698
        bool b1, b2;
        f.readf("%s\n%s\n", &b1, b2);
        assert(b1 == true && b2 == false);
    }

    // Nice error of std.stdio.readf with newlines
    // https://issues.dlang.org/show_bug.cgi?id=12260
    @system unittest
    {
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "1\n2");
        scope(exit) std.file.remove(deleteme);
        int input;
        auto f = File(deleteme);
        f.readf("%s", &input);

        import std.conv : ConvException;
        import std.exception : collectException;
        assert(collectException!ConvException(f.readf("%s", &input)).msg ==
            "Unexpected '\\n' when converting from type LockingTextReader to type int");
    }

    /**
    Reads a line from the file and parses it using $(REF formattedRead, std,format,read).

    Params:
      format = The $(MREF_ALTTEXT format string, std,format). When passed as a
      compile-time argument, the string will be statically checked against the
      argument types passed.
      data = Items to be read.

    Returns: Same as `formattedRead`: the number of variables filled. If the
    input ends early, this number will be less that the number of variables
    provided.

    Example:
    ---
    // sum_rows.d
    void main()
    {
        import std.stdio;
        auto f = File("input");
        int a, b, c;
        while (f.readfln("%d %d %d", a, b, c) == 3)
        {
            writeln(a + b + c);
        }
    }
    ---
    $(CONSOLE
% cat << EOF > input
1 2 3
4 5 6
7 8 9
EOF
% rdmd sum_rows.d
6
15
24
    )
    */
    uint readfln(alias format, Data...)(auto ref Data data)
    if (isSomeString!(typeof(format)))
    {
        import std.format : checkFormatException;

        alias e = checkFormatException!(format, Data);
        static assert(!e, e);
        return this.readfln(format, data);
    }

    /// ditto
    uint readfln(Data...)(scope const(char)[] format, auto ref Data data)
    {
        import std.format.read : formattedRead;
        import std.string : stripRight;

        string line = this.readln.stripRight("\r\n");
        return formattedRead(line, format, data);
    }

    @system unittest
    {
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "hello\nworld\ntrue\nfalse\n");
        scope(exit) std.file.remove(deleteme);
        string s;
        auto f = File(deleteme);
        f.readfln!"%s"(s);
        assert(s == "hello", "["~s~"]");
        f.readfln("%s", s);
        assert(s == "world", "["~s~"]");

        bool b1, b2;
        f.readfln("%s", b1);
        f.readfln("%s", b2);
        assert(b1 == true && b2 == false);
    }

/**
 Returns a temporary file by calling $(CSTDIO tmpfile).
 Note that the created file has no $(LREF name).*/
    static File tmpfile() @safe
    {
        import std.exception : errnoEnforce;

        return File(errnoEnforce(.tmpfile(),
                "Could not create temporary file with tmpfile()"),
            null);
    }

/**
Unsafe function that wraps an existing `FILE*`. The resulting $(D
File) never takes the initiative in closing the file.
Note that the created file has no $(LREF name)*/
    /*private*/ static File wrapFile(FILE* f) @safe
    {
        import std.exception : enforce;

        return File(enforce(f, "Could not wrap null FILE*"),
            null, /*uint.max / 2*/ 9999);
    }

/**
Returns the `FILE*` corresponding to this object.
 */
    FILE* getFP() @safe pure
    {
        import std.exception : enforce;

        enforce(_p && _p.handle,
                "Attempting to call getFP() on an unopened file");
        return _p.handle;
    }

    @system unittest
    {
        static import core.stdc.stdio;
        assert(stdout.getFP() == core.stdc.stdio.stdout);
    }

/**
Returns the file number corresponding to this object.
 */
    @property fileno_t fileno() const @trusted
    {
        import std.exception : enforce;

        enforce(isOpen, "Attempting to call fileno() on an unopened file");
        return .fileno(cast(FILE*) _p.handle);
    }

/**
Returns the underlying operating system `HANDLE` (Windows only).
*/
    version (StdDdoc)
    @property HANDLE windowsHandle();

    version (Windows)
    @property HANDLE windowsHandle()
    {
        return cast(HANDLE)_get_osfhandle(fileno);
    }


// Note: This was documented until 2013/08
/*
Range that reads one line at a time.  Returned by $(LREF byLine).

Allows to directly use range operations on lines of a file.
*/
    private struct ByLineImpl(Char, Terminator)
    {
    private:
        import std.typecons : borrow, RefCountedAutoInitialize, SafeRefCounted;

        /* Ref-counting stops the source range's Impl
         * from getting out of sync after the range is copied, e.g.
         * when accessing range.front, then using std.range.take,
         * then accessing range.front again. */
        alias PImpl = SafeRefCounted!(Impl, RefCountedAutoInitialize.no);
        PImpl impl;

        static if (isScalarType!Terminator)
            enum defTerm = '\n';
        else
            enum defTerm = cast(Terminator)"\n";

    public:
        this(File f, KeepTerminator kt = No.keepTerminator,
                Terminator terminator = defTerm)
        {
            impl = PImpl(f, kt, terminator);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        @property bool empty() @trusted
        {
            // Using `ref` is actually necessary here.
            return impl.borrow!((ref i) => i.empty);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        @property Char[] front() @trusted
        {
            // Using `ref` is likely optional here.
            return impl.borrow!((ref i) => i.front);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        void popFront() @trusted
        {
            return impl.borrow!((ref i) => i.popFront());
        }

    private:
        struct Impl
        {
        private:
            File file;
            Char[] line;
            Char[] buffer;
            Terminator terminator;
            KeepTerminator keepTerminator;
            bool haveLine;

        @safe:
        public:
            this(File f, KeepTerminator kt, Terminator terminator)
            {
                file = f;
                this.terminator = terminator;
                keepTerminator = kt;
            }

            // Range primitive implementations.
            @property bool empty()
            {
                needLine();
                return line is null;
            }

            @property Char[] front()
            {
                needLine();
                return line;
            }

            void popFront()
            {
                needLine();
                haveLine = false;
            }

        private:
            void needLine()
            {
                if (haveLine)
                    return;
                import std.algorithm.searching : endsWith;
                assert(file.isOpen);
                line = buffer;
                file.readln(line, terminator);
                if (line.length > buffer.length)
                {
                    buffer = line;
                }
                if (line.empty)
                {
                    file.detach();
                    line = null;
                }
                else if (keepTerminator == No.keepTerminator
                        && endsWith(line, terminator))
                {
                    static if (isScalarType!Terminator)
                        enum tlen = 1;
                    else static if (isArray!Terminator)
                    {
                        static assert(
                            is(immutable ElementEncodingType!Terminator == immutable Char));
                        const tlen = terminator.length;
                    }
                    else
                        static assert(false);
                    line = line[0 .. line.length - tlen];
                }
                haveLine = true;
            }
        }
    }

/**
Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
set up to read from the file handle one line at a time.

The element type for the range will be `Char[]`. Range primitives
may throw `StdioException` on I/O error.

Note:
Each `front` will not persist after $(D
popFront) is called, so the caller must copy its contents (e.g. by
calling `to!string`) when retention is needed. If the caller needs
to retain a copy of every line, use the $(LREF byLineCopy) function
instead.

Params:
Char = Character type for each line, defaulting to `char`.
keepTerminator = Use `Yes.keepTerminator` to include the
terminator at the end of each line.
terminator = Line separator (`'\n'` by default). Use
$(REF newline, std,ascii) for portability (unless the file was opened in
text mode).

Example:
----
import std.algorithm, std.stdio, std.string;
// Count words in a file using ranges.
void main()
{
    auto file = File("file.txt"); // Open for reading
    const wordCount = file.byLine()            // Read lines
                          .map!split           // Split into words
                          .map!(a => a.length) // Count words per line
                          .sum();              // Total word count
    writeln(wordCount);
}
----

Example:
----
import std.range, std.stdio;
// Read lines using foreach.
void main()
{
    auto file = File("file.txt"); // Open for reading
    auto range = file.byLine();
    // Print first three lines
    foreach (line; range.take(3))
        writeln(line);
    // Print remaining lines beginning with '#'
    foreach (line; range)
    {
        if (!line.empty && line[0] == '#')
            writeln(line);
    }
}
----
Notice that neither example accesses the line data returned by
`front` after the corresponding `popFront` call is made (because
the contents may well have changed).
----

Windows specific Example:
----
import std.stdio;

version (Windows)
void main()
{

	foreach (line; File("file.txt").byLine(No.keepTerminator, "\r\n"))
	{
		writeln("|"~line~"|");
		if (line == "HelloWorld")
		    writeln("^This Line is here.");
	}

}
*/
    auto byLine(Terminator = char, Char = char)
            (KeepTerminator keepTerminator = No.keepTerminator,
            Terminator terminator = '\n')
    if (isScalarType!Terminator)
    {
        return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);
    }

/// ditto
    auto byLine(Terminator, Char = char)
            (KeepTerminator keepTerminator, Terminator terminator)
    if (is(immutable ElementEncodingType!Terminator == immutable Char))
    {
        return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);
    }

    @safe unittest
    {
        static import std.file;
        auto deleteme = testFilename();
        std.file.write(deleteme, "hi");
        scope(success) std.file.remove(deleteme);

        import std.meta : AliasSeq;
        static foreach (T; AliasSeq!(char, wchar, dchar))
        {{
            auto blc = File(deleteme).byLine!(T, T);
            assert(blc.front == "hi");
            // check front is cached
            assert(blc.front is blc.front);
        }}
    }

    // https://issues.dlang.org/show_bug.cgi?id=19980
    @safe unittest
    {
        static import std.file;
        auto deleteme = testFilename();
        std.file.write(deleteme, "Line 1\nLine 2\nLine 3\n");
        scope(success) std.file.remove(deleteme);

        auto f = File(deleteme);
        f.byLine();
        f.byLine();
        assert(f.byLine().front == "Line 1");
    }

    private struct ByLineCopy(Char, Terminator)
    {
    private:
        import std.typecons : borrow, RefCountedAutoInitialize, SafeRefCounted;

        /* Ref-counting stops the source range's ByLineCopyImpl
         * from getting out of sync after the range is copied, e.g.
         * when accessing range.front, then using std.range.take,
         * then accessing range.front again. */
        alias Impl = SafeRefCounted!(ByLineCopyImpl!(Char, Terminator),
            RefCountedAutoInitialize.no);
        Impl impl;

    public:
        this(File f, KeepTerminator kt, Terminator terminator)
        {
            impl = Impl(f, kt, terminator);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        @property bool empty() @trusted
        {
            // Using `ref` is actually necessary here.
            return impl.borrow!((ref i) => i.empty);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        @property Char[] front() @trusted
        {
            // Using `ref` is likely optional here.
            return impl.borrow!((ref i) => i.front);
        }

        /* Verifiably `@safe` when built with -preview=DIP1000. */
        void popFront() @trusted
        {
            impl.borrow!((ref i) => i.popFront());
        }
    }

    private struct ByLineCopyImpl(Char, Terminator)
    {
        ByLineImpl!(Unqual!Char, Terminator).Impl impl;
        bool gotFront;
        Char[] line;

    public:
        this(File f, KeepTerminator kt, Terminator terminator)
        {
            impl = ByLineImpl!(Unqual!Char, Terminator).Impl(f, kt, terminator);
        }

        @property bool empty()
        {
            return impl.empty;
        }

        @property front()
        {
            if (!gotFront)
            {
                line = impl.front.dup;
                gotFront = true;
            }
            return line;
        }

        void popFront()
        {
            impl.popFront();
            gotFront = false;
        }
    }

/**
Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
set up to read from the file handle one line
at a time. Each line will be newly allocated. `front` will cache
its value to allow repeated calls without unnecessary allocations.

Note: Due to caching byLineCopy can be more memory-efficient than
`File.byLine.map!idup`.

The element type for the range will be `Char[]`. Range
primitives may throw `StdioException` on I/O error.

Params:
Char = Character type for each line, defaulting to $(D immutable char).
keepTerminator = Use `Yes.keepTerminator` to include the
terminator at the end of each line.
terminator = Line separator (`'\n'` by default). Use
$(REF newline, std,ascii) for portability (unless the file was opened in
text mode).

Example:
----
import std.algorithm, std.array, std.stdio;
// Print sorted lines of a file.
void main()
{
    auto sortedLines = File("file.txt")   // Open for reading
                       .byLineCopy()      // Read persistent lines
                       .array()           // into an array
                       .sort();           // then sort them
    foreach (line; sortedLines)
        writeln(line);
}
----
See_Also:
$(REF readText, std,file)
*/
    auto byLineCopy(Terminator = char, Char = immutable char)
            (KeepTerminator keepTerminator = No.keepTerminator,
            Terminator terminator = '\n')
    if (isScalarType!Terminator)
    {
        return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator);
    }

/// ditto
    auto byLineCopy(Terminator, Char = immutable char)
            (KeepTerminator keepTerminator, Terminator terminator)
    if (is(immutable ElementEncodingType!Terminator == immutable Char))
    {
        return ByLineCopy!(Char, Terminator)(this, keepTerminator, terminator);
    }

    @safe unittest
    {
        static assert(is(typeof(File("").byLine.front) == char[]));
        static assert(is(typeof(File("").byLineCopy.front) == string));
        static assert(
            is(typeof(File("").byLineCopy!(char, char).front) == char[]));
    }

    @safe unittest
    {
        import std.algorithm.comparison : equal;
        static import std.file;

        auto deleteme = testFilename();
        std.file.write(deleteme, "");
        scope(success) std.file.remove(deleteme);

        // Test empty file
        auto f = File(deleteme);
        foreach (line; f.byLine())
        {
            assert(false);
        }
        f.detach();
        assert(!f.isOpen);

        void test(Terminator)(string txt, in string[] witness,
                KeepTerminator kt, Terminator term, bool popFirstLine = false)
        {
            import std.algorithm.sorting : sort;
            import std.array : array;
            import std.conv : text;
            import std.range.primitives : walkLength;

            uint i;
            std.file.write(deleteme, txt);
            auto f = File(deleteme);
            scope(exit)
            {
                f.close();
                assert(!f.isOpen);
            }
            auto lines = f.byLine(kt, term);
            if (popFirstLine)
            {
                lines.popFront();
                i = 1;
            }
            assert(lines.empty || lines.front is lines.front);
            foreach (line; lines)
            {
                assert(line == witness[i++]);
            }
            assert(i == witness.length, text(i, " != ", witness.length));

            // https://issues.dlang.org/show_bug.cgi?id=11830
            auto walkedLength = File(deleteme).byLine(kt, term).walkLength;
            assert(walkedLength == witness.length, text(walkedLength, " != ", witness.length));

            // test persistent lines
            assert(File(deleteme).byLineCopy(kt, term).array.sort() == witness.dup.sort());
        }

        KeepTerminator kt = No.keepTerminator;
        test("", null, kt, '\n');
        test("\n", [ "" ], kt, '\n');
        test("asd\ndef\nasdf", [ "asd", "def", "asdf" ], kt, '\n');
        test("asd\ndef\nasdf", [ "asd", "def", "asdf" ], kt, '\n', true);
        test("asd\ndef\nasdf\n", [ "asd", "def", "asdf" ], kt, '\n');
        test("foo", [ "foo" ], kt, '\n', true);
        test("bob\r\nmarge\r\nsteve\r\n", ["bob", "marge", "steve"],
            kt, "\r\n");
        test("sue\r", ["sue"], kt, '\r');

        kt = Yes.keepTerminator;
        test("", null, kt, '\n');
        test("\n", [ "\n" ], kt, '\n');
        test("asd\ndef\nasdf", [ "asd\n", "def\n", "asdf" ], kt, '\n');
        test("asd\ndef\nasdf\n", [ "asd\n", "def\n", "asdf\n" ], kt, '\n');
        test("asd\ndef\nasdf\n", [ "asd\n", "def\n", "asdf\n" ], kt, '\n', true);
        test("foo", [ "foo" ], kt, '\n');
        test("bob\r\nmarge\r\nsteve\r\n", ["bob\r\n", "marge\r\n", "steve\r\n"],
            kt, "\r\n");
        test("sue\r", ["sue\r"], kt, '\r');
    }

    @safe unittest
    {
        import std.algorithm.comparison : equal;
        import std.range : drop, take;

        version (Win64)
        {
            static import std.file;

            /* the C function tmpfile doesn't seem to work, even when called from C */
            auto deleteme = testFilename();
            auto file = File(deleteme, "w+");
            scope(success) std.file.remove(deleteme);
        }
        else version (CRuntime_Bionic)
        {
            static import std.file;

            /* the C function tmpfile doesn't work when called from a shared
               library apk:
               https://code.google.com/p/android/issues/detail?id=66815 */
            auto deleteme = testFilename();
            auto file = File(deleteme, "w+");
            scope(success) std.file.remove(deleteme);
        }
        else
            auto file = File.tmpfile();
        file.write("1\n2\n3\n");

        // https://issues.dlang.org/show_bug.cgi?id=9599
        file.rewind();
        File.ByLineImpl!(char, char) fbl = file.byLine();
        auto fbl2 = fbl;
        assert(fbl.front == "1");
        assert(fbl.front is fbl2.front);
        assert(fbl.take(1).equal(["1"]));
        assert(fbl.equal(["2", "3"]));
        assert(fbl.empty);
        assert(file.isOpen); // we still have a valid reference

        file.rewind();
        fbl = file.byLine();
        assert(!fbl.drop(2).empty);
        assert(fbl.equal(["3"]));
        assert(fbl.empty);
        assert(file.isOpen);

        file.detach();
        assert(!file.isOpen);
    }

    @safe unittest
    {
        static import std.file;
        auto deleteme = testFilename();
        std.file.write(deleteme, "hi");
        scope(success) std.file.remove(deleteme);

        auto blc = File(deleteme).byLineCopy;
        assert(!blc.empty);
        // check front is cached
        assert(blc.front is blc.front);
    }

    /**
    Creates an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    set up to parse one line at a time from the file into a tuple.

    Range primitives may throw `StdioException` on I/O error.

    Params:
        format = tuple record $(REF_ALTTEXT _format, formattedRead, std, _format)

    Returns:
        The input range set up to parse one line at a time into a record tuple.

    See_Also:

        It is similar to $(LREF byLine) and uses
        $(REF_ALTTEXT _format, formattedRead, std, _format) under the hood.
    */
    template byRecord(Fields...)
    {
        auto byRecord(string format)
        {
            return ByRecordImpl!(Fields)(this, format);
        }
    }

    ///
    @system unittest
    {
         static import std.file;
         import std.typecons : tuple;

         // prepare test file
         auto testFile = std.file.deleteme();
         scope(failure) printf("Failed test at line %d\n", __LINE__);
         std.file.write(testFile, "1 2\n4 1\n5 100");
         scope(exit) std.file.remove(testFile);

         File f = File(testFile);
         scope(exit) f.close();

         auto expected = [tuple(1, 2), tuple(4, 1), tuple(5, 100)];
         uint i;
         foreach (e; f.byRecord!(int, int)("%s %s"))
         {
             assert(e == expected[i++]);
         }
    }

    // Note: This was documented until 2013/08
    /*
     * Range that reads a chunk at a time.
     */
    private struct ByChunkImpl
    {
    private:
        File    file_;
        ubyte[] chunk_;

        void prime()
        {
            chunk_ = file_.rawRead(chunk_);
            if (chunk_.length == 0)
                file_.detach();
        }

    public:
        this(File file, size_t size)
        {
            this(file, new ubyte[](size));
        }

        this(File file, ubyte[] buffer)
        {
            import std.exception : enforce;
            enforce(buffer.length, "size must be larger than 0");
            file_ = file;
            chunk_ = buffer;
            prime();
        }

        // `ByChunk`'s input range primitive operations.
        @property nothrow
        bool empty() const
        {
            return !file_.isOpen;
        }

        /// Ditto
        @property nothrow
        ubyte[] front()
        {
            version (assert)
            {
                import core.exception : RangeError;
                if (empty)
                    throw new RangeError();
            }
            return chunk_;
        }

        /// Ditto
        void popFront()
        {
            version (assert)
            {
                import core.exception : RangeError;
                if (empty)
                    throw new RangeError();
            }
            prime();
        }
    }

/**
Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
set up to read from the file handle a chunk at a time.

The element type for the range will be `ubyte[]`. Range primitives
may throw `StdioException` on I/O error.

Example:
---------
void main()
{
    // Read standard input 4KB at a time
    foreach (ubyte[] buffer; stdin.byChunk(4096))
    {
        ... use buffer ...
    }
}
---------

The parameter may be a number (as shown in the example above) dictating the
size of each chunk. Alternatively, `byChunk` accepts a
user-provided buffer that it uses directly.

Example:
---------
void main()
{
    // Read standard input 4KB at a time
    foreach (ubyte[] buffer; stdin.byChunk(new ubyte[4096]))
    {
        ... use buffer ...
    }
}
---------

In either case, the content of the buffer is reused across calls. That means
`front` will not persist after `popFront` is called, so if retention is
needed, the caller must copy its contents (e.g. by calling `buffer.dup`).

In the  example above, `buffer.length` is 4096 for all iterations, except
for the last one, in which case `buffer.length` may be less than 4096 (but
always greater than zero).

With the mentioned limitations, `byChunk` works with any algorithm
compatible with input ranges.

Example:
---
// Efficient file copy, 1MB at a time.
import std.algorithm, std.stdio;
void main()
{
    stdin.byChunk(1024 * 1024).copy(stdout.lockingTextWriter());
}
---

$(REF joiner, std,algorithm,iteration) can be used to join chunks together into
a single range lazily.
Example:
---
import std.algorithm, std.stdio;
void main()
{
    //Range of ranges
    static assert(is(typeof(stdin.byChunk(4096).front) == ubyte[]));
    //Range of elements
    static assert(is(typeof(stdin.byChunk(4096).joiner.front) == ubyte));
}
---

Returns: A call to `byChunk` returns a range initialized with the `File`
object and the appropriate buffer.

Throws: If the user-provided size is zero or the user-provided buffer
is empty, throws an `Exception`. In case of an I/O error throws
`StdioException`.
 */
    auto byChunk(size_t chunkSize)
    {
        return ByChunkImpl(this, chunkSize);
    }
/// Ditto
    auto byChunk(ubyte[] buffer)
    {
        return ByChunkImpl(this, buffer);
    }

    @system unittest
    {
        static import std.file;

        scope(failure) printf("Failed test at line %d\n", __LINE__);

        auto deleteme = testFilename();
        std.file.write(deleteme, "asd\ndef\nasdf");

        auto witness = ["asd\n", "def\n", "asdf" ];
        auto f = File(deleteme);
        scope(exit)
        {
            f.close();
            assert(!f.isOpen);
            std.file.remove(deleteme);
        }

        uint i;
        foreach (chunk; f.byChunk(4))
            assert(chunk == cast(ubyte[]) witness[i++]);

        assert(i == witness.length);
    }

    @system unittest
    {
        static import std.file;

        scope(failure) printf("Failed test at line %d\n", __LINE__);

        auto deleteme = testFilename();
        std.file.write(deleteme, "asd\ndef\nasdf");

        auto witness = ["asd\n", "def\n", "asdf" ];
        auto f = File(deleteme);
        scope(exit)
        {
            f.close();
            assert(!f.isOpen);
            std.file.remove(deleteme);
        }

        uint i;
        foreach (chunk; f.byChunk(new ubyte[4]))
            assert(chunk == cast(ubyte[]) witness[i++]);

        assert(i == witness.length);
    }

    // Note: This was documented until 2013/08
/*
`Range` that locks the file and allows fast writing to it.
 */
    struct LockingTextWriter
    {
    private:
        import std.range.primitives : ElementType, isInfinite, isInputRange;
        // Access the FILE* handle through the 'file_' member
        // to keep the object alive through refcounting
        File file_;

        // the unshared version of FILE* handle, extracted from the File object
        @property _iobuf* handle_() @trusted { return cast(_iobuf*) file_._p.handle; }

        // the file's orientation (byte- or wide-oriented)
        int orientation_;

        // Buffers for when we need to transcode.
        wchar highSurrogate = '\0'; // '\0' indicates empty
        void highSurrogateShouldBeEmpty() @safe
        {
            import std.utf : UTFException;
            if (highSurrogate != '\0')
                throw new UTFException("unpaired surrogate UTF-16 value");
        }
        char[4] rbuf8;
        size_t rbuf8Filled = 0;
    public:

        this(ref File f) @trusted
        {
            import std.exception : enforce;

            enforce(f._p && f._p.handle, "Attempting to write to closed File");
            file_ = f;
            FILE* fps = f._p.handle;

            version (CRuntime_Microsoft)
            {
                // Microsoft doesn't implement fwide. Instead, there's the
                // concept of ANSI/UNICODE mode. fputc doesn't work in UNICODE
                // mode; fputwc has to be used. So that essentially means
                // "wide-oriented" for us.
                immutable int mode = _setmode(f.fileno, _O_TEXT);
                    // Set some arbitrary mode to obtain the previous one.
                if (mode != -1) // _setmode() succeeded
                {
                    _setmode(f.fileno, mode); // Restore previous mode.
                    if (mode & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT))
                    {
                        orientation_ = 1; // wide
                    }
                }
            }
            else
            {
                import core.stdc.wchar_ : fwide;
                orientation_ = fwide(fps, 0);
            }

            _FLOCK(fps);
        }

        ~this() @trusted
        {
            if (auto p = file_._p)
            {
                if (p.handle) _FUNLOCK(p.handle);
            }
            file_ = File.init;
                /* Destroy file_ before possibly throwing. Else it wouldn't be
                destroyed, and its reference count would be wrong. */
            highSurrogateShouldBeEmpty();
        }

        this(this) @trusted
        {
            if (auto p = file_._p)
            {
                if (p.handle) _FLOCK(p.handle);
            }
        }

        /// Range primitive implementations.
        void put(A)(scope A writeme)
        if ((isSomeChar!(ElementType!A) ||
            is(ElementType!A : const(ubyte))) &&
            isInputRange!A &&
            !isInfinite!A)
        {
            import std.exception : errnoEnforce;

            alias C = ElementEncodingType!A;
            static assert(!is(C == void));
            static if (isSomeString!A && C.sizeof == 1 || is(A : const(ubyte)[]))
            {
                if (orientation_ <= 0)
                {
                    //file.write(writeme); causes infinite recursion!!!
                    //file.rawWrite(writeme);
                    auto result = trustedFwrite(file_._p.handle, writeme);
                    if (result != writeme.length) errnoEnforce(0);
                    return;
                }
            }

            // put each element in turn.
            foreach (c; writeme)
            {
                put(c);
            }
        }

        /// ditto
        void put(C)(scope C c) @safe
        if (isSomeChar!C || is(C : const(ubyte)))
        {
            import std.utf : decodeFront, encode, stride;

            static if (c.sizeof == 1)
            {
                highSurrogateShouldBeEmpty();
                if (orientation_ <= 0) trustedFPUTC(c, handle_);
                else if (c <= 0x7F) trustedFPUTWC(c, handle_);
                else if (c >= 0b1100_0000) // start byte of multibyte sequence
                {
                    rbuf8[0] = c;
                    rbuf8Filled = 1;
                }
                else // continuation byte of multibyte sequence
                {
                    rbuf8[rbuf8Filled] = c;
                    ++rbuf8Filled;
                    if (stride(rbuf8[]) == rbuf8Filled) // sequence is complete
                    {
                        char[] str = rbuf8[0 .. rbuf8Filled];
                        immutable dchar d = decodeFront(str);
                        wchar_t[4 / wchar_t.sizeof] wbuf;
                        immutable size = encode(wbuf, d);
                        foreach (i; 0 .. size)
                            trustedFPUTWC(wbuf[i], handle_);
                        rbuf8Filled = 0;
                    }
                }
            }
            else static if (c.sizeof == 2)
            {
                import std.utf : decode;

                if (c <= 0x7F)
                {
                    highSurrogateShouldBeEmpty();
                    if (orientation_ <= 0) trustedFPUTC(c, handle_);
                    else trustedFPUTWC(c, handle_);
                }
                else if (0xD800 <= c && c <= 0xDBFF) // high surrogate
                {
                    highSurrogateShouldBeEmpty();
                    highSurrogate = c;
                }
                else // standalone or low surrogate
                {
                    dchar d = c;
                    if (highSurrogate != '\0')
                    {
                        immutable wchar[2] rbuf = [highSurrogate, c];
                        size_t index = 0;
                        d = decode(rbuf[], index);
                        highSurrogate = 0;
                    }
                    if (orientation_ <= 0)
                    {
                        char[4] wbuf;
                        immutable size = encode(wbuf, d);
                        foreach (i; 0 .. size)
                            trustedFPUTC(wbuf[i], handle_);
                    }
                    else
                    {
                        wchar_t[4 / wchar_t.sizeof] wbuf;
                        immutable size = encode(wbuf, d);
                        foreach (i; 0 .. size)
                            trustedFPUTWC(wbuf[i], handle_);
                    }
                    rbuf8Filled = 0;
                }
            }
            else // 32-bit characters
            {
                import std.utf : encode;

                highSurrogateShouldBeEmpty();
                if (orientation_ <= 0)
                {
                    if (c <= 0x7F)
                    {
                        trustedFPUTC(c, handle_);
                    }
                    else
                    {
                        char[4] buf = void;
                        immutable len = encode(buf, c);
                        foreach (i ; 0 .. len)
                            trustedFPUTC(buf[i], handle_);
                    }
                }
                else
                {
                    version (Windows)
                    {
                        import std.utf : isValidDchar;

                        assert(isValidDchar(c));
                        if (c <= 0xFFFF)
                        {
                            trustedFPUTWC(cast(wchar_t) c, handle_);
                        }
                        else
                        {
                            trustedFPUTWC(cast(wchar_t)
                                    ((((c - 0x10000) >> 10) & 0x3FF)
                                            + 0xD800), handle_);
                            trustedFPUTWC(cast(wchar_t)
                                    (((c - 0x10000) & 0x3FF) + 0xDC00),
                                    handle_);
                        }
                    }
                    else version (Posix)
                    {
                        trustedFPUTWC(cast(wchar_t) c, handle_);
                    }
                    else
                    {
                        static assert(0);
                    }
                }
            }
        }
    }

    /**
     * Output range which locks the file when created, and unlocks the file when it goes
     * out of scope.
     *
     * Returns: An $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)
     * which accepts string types, `ubyte[]`, individual character types, and
     * individual `ubyte`s.
     *
     * Note: Writing either arrays of `char`s or `ubyte`s is faster than
     * writing each character individually from a range. For large amounts of data,
     * writing the contents in chunks using an intermediary array can result
     * in a speed increase.
     *
     * Throws: $(REF UTFException, std, utf) if the data given is a `char` range
     * and it contains malformed UTF data.
     *
     * See_Also: $(LREF byChunk) for an example.
     */
    auto lockingTextWriter() @safe
    {
        return LockingTextWriter(this);
    }

    // An output range which optionally locks the file and puts it into
    // binary mode (similar to rawWrite). Because it needs to restore
    // the file mode on destruction, it is RefCounted on Windows.
    struct BinaryWriterImpl(bool locking)
    {
        import std.traits : hasIndirections;
    private:
        // Access the FILE* handle through the 'file_' member
        // to keep the object alive through refcounting
        File file_;
        string name;

        version (Windows)
        {
            fileno_t fd;
            int oldMode;
        }

    public:
        // Don't use this, but `File.lockingBinaryWriter()` instead.
        // Must be public for RefCounted and emplace() in druntime.
        this(scope ref File f)
        {
            import std.exception : enforce;
            file_ = f;
            enforce(f._p && f._p.handle);
            name = f._name;
            FILE* fps = f._p.handle;
            static if (locking)
                _FLOCK(fps);

            version (Windows)
            {
                .fflush(fps); // before changing translation mode
                fd = .fileno(fps);
                oldMode = ._setmode(fd, _O_BINARY);
            }
        }

        ~this()
        {
            if (!file_._p || !file_._p.handle)
                return;

            FILE* fps = file_._p.handle;

            version (Windows)
            {
                .fflush(fps); // before restoring translation mode
                ._setmode(fd, oldMode);
            }

            _FUNLOCK(fps);
        }

        void rawWrite(T)(in T[] buffer)
        {
            import std.conv : text;
            import std.exception : errnoEnforce;

            auto result = trustedFwrite(file_._p.handle, buffer);
            if (result == result.max) result = 0;
            errnoEnforce(result == buffer.length,
                    text("Wrote ", result, " instead of ", buffer.length,
                            " objects of type ", T.stringof, " to file `",
                            name, "'"));
        }

        version (Windows)
        {
            @disable this(this);
        }
        else
        {
            this(this)
            {
                if (auto p = file_._p)
                {
                    if (p.handle) _FLOCK(p.handle);
                }
            }
        }

        void put(T)(auto ref scope const T value)
        if (!hasIndirections!T &&
            !isInputRange!T)
        {
            rawWrite((&value)[0 .. 1]);
        }

        void put(T)(scope const(T)[] array)
        if (!hasIndirections!T &&
            !isInputRange!T)
        {
            rawWrite(array);
        }
    }

/** Returns an output range that locks the file and allows fast writing to it.

Example:
Produce a grayscale image of the $(LINK2 https://en.wikipedia.org/wiki/Mandelbrot_set, Mandelbrot set)
in binary $(LINK2 https://en.wikipedia.org/wiki/Netpbm_format, Netpbm format) to standard output.
---
import std.algorithm, std.complex, std.range, std.stdio;

void main()
{
    enum size = 500;
    writef("P5\n%d %d %d\n", size, size, ubyte.max);

    iota(-1, 3, 2.0/size).map!(y =>
        iota(-1.5, 0.5, 2.0/size).map!(x =>
            cast(ubyte)(1+
                recurrence!((a, n) => x + y * complex(0, 1) + a[n-1]^^2)(complex(0))
                .take(ubyte.max)
                .countUntil!(z => z.re^^2 + z.im^^2 > 4))
        )
    )
    .copy(stdout.lockingBinaryWriter);
}
---
*/
    auto lockingBinaryWriter()
    {
        alias LockingBinaryWriterImpl = BinaryWriterImpl!true;

        version (Windows)
        {
            import std.typecons : RefCounted;
            alias LockingBinaryWriter = RefCounted!LockingBinaryWriterImpl;
        }
        else
            alias LockingBinaryWriter = LockingBinaryWriterImpl;

        return LockingBinaryWriter(this);
    }

    @system unittest
    {
        import std.algorithm.mutation : reverse;
        import std.exception : collectException;
        static import std.file;
        import std.range : only, retro;
        import std.string : format;

        auto deleteme = testFilename();
        scope(exit) collectException(std.file.remove(deleteme));

        {
            auto writer = File(deleteme, "wb").lockingBinaryWriter();
            auto input = File(deleteme, "rb");

            ubyte[1] byteIn = [42];
            writer.rawWrite(byteIn);
            destroy(writer);

            ubyte[1] byteOut = input.rawRead(new ubyte[1]);
            assert(byteIn[0] == byteOut[0]);
        }

        auto output = File(deleteme, "wb");
        auto writer = output.lockingBinaryWriter();
        auto input = File(deleteme, "rb");

        T[] readExact(T)(T[] buf)
        {
            auto result = input.rawRead(buf);
            assert(result.length == buf.length,
                "Read %d out of %d bytes"
                .format(result.length, buf.length));
            return result;
        }

        // test raw values
        ubyte byteIn = 42;
        byteIn.only.copy(writer); output.flush();
        ubyte byteOut = readExact(new ubyte[1])[0];
        assert(byteIn == byteOut);

        // test arrays
        ubyte[] bytesIn = [1, 2, 3, 4, 5];
        bytesIn.copy(writer); output.flush();
        ubyte[] bytesOut = readExact(new ubyte[bytesIn.length]);
        scope(failure) .writeln(bytesOut);
        assert(bytesIn == bytesOut);

        // test ranges of values
        bytesIn.retro.copy(writer); output.flush();
        bytesOut = readExact(bytesOut);
        bytesOut.reverse();
        assert(bytesIn == bytesOut);

        // test string
        "foobar".copy(writer); output.flush();
        char[] charsOut = readExact(new char[6]);
        assert(charsOut == "foobar");

        // test ranges of arrays
        only("foo", "bar").copy(writer); output.flush();
        charsOut = readExact(charsOut);
        assert(charsOut == "foobar");

        // test that we are writing arrays as is,
        // without UTF-8 transcoding
        "foo"d.copy(writer); output.flush();
        dchar[] dcharsOut = readExact(new dchar[3]);
        assert(dcharsOut == "foo");
    }

/** Returns the size of the file in bytes, ulong.max if file is not searchable or throws if the operation fails.
Example:
---
import std.stdio, std.file;

void main()
{
    string deleteme = "delete.me";
    auto file_handle = File(deleteme, "w");
    file_handle.write("abc"); //create temporary file
    scope(exit) deleteme.remove; //remove temporary file at scope exit

    assert(file_handle.size() == 3); //check if file size is 3 bytes
}
---
*/
    @property ulong size() @safe
    {
        import std.exception : collectException;

        ulong pos = void;
        if (collectException(pos = tell)) return ulong.max;
        scope(exit) seek(pos);
        seek(0, SEEK_END);
        return tell;
    }
}

@system unittest
{
    @system struct SystemToString
    {
        string toString()
        {
            return "system";
        }
    }

    @trusted struct TrustedToString
    {
        string toString()
        {
            return "trusted";
        }
    }

    @safe struct SafeToString
    {
        string toString()
        {
            return "safe";
        }
    }

    @system void systemTests()
    {
        //system code can write to files/stdout with anything!
        if (false)
        {
            auto f = File();

            f.write("just a string");
            f.write("string with arg: ", 47);
            f.write(SystemToString());
            f.write(TrustedToString());
            f.write(SafeToString());

            write("just a string");
            write("string with arg: ", 47);
            write(SystemToString());
            write(TrustedToString());
            write(SafeToString());

            f.writeln("just a string");
            f.writeln("string with arg: ", 47);
            f.writeln(SystemToString());
            f.writeln(TrustedToString());
            f.writeln(SafeToString());

            writeln("just a string");
            writeln("string with arg: ", 47);
            writeln(SystemToString());
            writeln(TrustedToString());
            writeln(SafeToString());

            f.writef("string with arg: %s", 47);
            f.writef("%s", SystemToString());
            f.writef("%s", TrustedToString());
            f.writef("%s", SafeToString());

            writef("string with arg: %s", 47);
            writef("%s", SystemToString());
            writef("%s", TrustedToString());
            writef("%s", SafeToString());

            f.writefln("string with arg: %s", 47);
            f.writefln("%s", SystemToString());
            f.writefln("%s", TrustedToString());
            f.writefln("%s", SafeToString());

            writefln("string with arg: %s", 47);
            writefln("%s", SystemToString());
            writefln("%s", TrustedToString());
            writefln("%s", SafeToString());
        }
    }

    @safe void safeTests()
    {
        auto f = File();

        //safe code can write to files only with @safe and @trusted code...
        if (false)
        {
            f.write("just a string");
            f.write("string with arg: ", 47);
            f.write(TrustedToString());
            f.write(SafeToString());

            write("just a string");
            write("string with arg: ", 47);
            write(TrustedToString());
            write(SafeToString());

            f.writeln("just a string");
            f.writeln("string with arg: ", 47);
            f.writeln(TrustedToString());
            f.writeln(SafeToString());

            writeln("just a string");
            writeln("string with arg: ", 47);
            writeln(TrustedToString());
            writeln(SafeToString());

            f.writef("string with arg: %s", 47);
            f.writef("%s", TrustedToString());
            f.writef("%s", SafeToString());

            writef("string with arg: %s", 47);
            writef("%s", TrustedToString());
            writef("%s", SafeToString());

            f.writefln("string with arg: %s", 47);
            f.writefln("%s", TrustedToString());
            f.writefln("%s", SafeToString());

            writefln("string with arg: %s", 47);
            writefln("%s", TrustedToString());
            writefln("%s", SafeToString());
        }

        static assert(!__traits(compiles, f.write(SystemToString().toString())));
        static assert(!__traits(compiles, f.writeln(SystemToString())));
        static assert(!__traits(compiles, f.writef("%s", SystemToString())));
        static assert(!__traits(compiles, f.writefln("%s", SystemToString())));

        static assert(!__traits(compiles, write(SystemToString().toString())));
        static assert(!__traits(compiles, writeln(SystemToString())));
        static assert(!__traits(compiles, writef("%s", SystemToString())));
        static assert(!__traits(compiles, writefln("%s", SystemToString())));
    }

    systemTests();
    safeTests();
}

@safe unittest
{
    import std.exception : collectException;
    static import std.file;

    auto deleteme = testFilename();
    scope(exit) collectException(std.file.remove(deleteme));
    std.file.write(deleteme, "1 2 3");
    auto f = File(deleteme);
    assert(f.size == 5);
    assert(f.tell == 0);
}

@safe unittest
{
    static import std.file;
    import std.range : chain, only, repeat;
    import std.range.primitives : isOutputRange;

    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);

    {
        auto writer = File(deleteme, "w").lockingTextWriter();
        static assert(isOutputRange!(typeof(writer), dchar));
        writer.put("日本語");
        writer.put("日本語"w);
        writer.put("日本語"d);
        writer.put('日');
        writer.put(chain(only('本'), only('語')));
        // https://issues.dlang.org/show_bug.cgi?id=11945
        writer.put(repeat('#', 12));
        // https://issues.dlang.org/show_bug.cgi?id=17229
        writer.put(cast(immutable(ubyte)[])"日本語");
    }
    assert(File(deleteme).readln() == "日本語日本語日本語日本語############日本語");
}

@safe unittest // wchar -> char
{
    static import std.file;
    import std.exception : assertThrown;
    import std.utf : UTFException;

    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);

    {
        auto writer = File(deleteme, "w").lockingTextWriter();
        writer.put("\U0001F608"w);
    }
    assert(std.file.readText!string(deleteme) == "\U0001F608");

    // Test invalid input: unpaired high surrogate
    {
        immutable wchar surr = "\U0001F608"w[0];
        auto f = File(deleteme, "w");
        assertThrown!UTFException(() {
            auto writer = f.lockingTextWriter();
            writer.put('x');
            writer.put(surr);
            assertThrown!UTFException(writer.put(char('y')));
            assertThrown!UTFException(writer.put(wchar('y')));
            assertThrown!UTFException(writer.put(dchar('y')));
            assertThrown!UTFException(writer.put(surr));
            // First `surr` is still unpaired at this point. `writer` gets
            // destroyed now, and the destructor throws a UTFException for
            // the unpaired surrogate.
        } ());
    }
    assert(std.file.readText!string(deleteme) == "x");

    // Test invalid input: unpaired low surrogate
    {
        immutable wchar surr = "\U0001F608"w[1];
        auto writer = File(deleteme, "w").lockingTextWriter();
        assertThrown!UTFException(writer.put(surr));
        writer.put('y');
        assertThrown!UTFException(writer.put(surr));
    }
    assert(std.file.readText!string(deleteme) == "y");
}

@safe unittest // https://issues.dlang.org/show_bug.cgi?id=18801
{
    static import std.file;
    import std.string : stripLeft;

    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);

    {
        auto writer = File(deleteme, "w,ccs=UTF-8").lockingTextWriter();
        writer.put("foo");
    }
    assert(std.file.readText!string(deleteme).stripLeft("\uFEFF") == "foo");

    {
        auto writer = File(deleteme, "a,ccs=UTF-8").lockingTextWriter();
        writer.put("bar");
    }
    assert(std.file.readText!string(deleteme).stripLeft("\uFEFF") == "foobar");
}
@safe unittest // char/wchar -> wchar_t
{
    import core.stdc.locale : LC_CTYPE, setlocale;
    import core.stdc.wchar_ : fwide;
    import core.stdc.string : strlen;
    import std.algorithm.searching : any, endsWith;
    import std.conv : text;
    import std.meta : AliasSeq;
    import std.string : fromStringz, stripLeft;
    static import std.file;
    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);
    const char* oldCt = () @trusted {
        const(char)* p = setlocale(LC_CTYPE, null);
        // Subsequent calls to `setlocale` might invalidate this return value,
        // so duplicate it.
        // See: https://github.com/dlang/phobos/pull/7660
        return p ? p[0 .. strlen(p) + 1].idup.ptr : null;
    }();
    const utf8 = ["en_US.UTF-8", "C.UTF-8", ".65001"].any!((loc) @trusted {
        return setlocale(LC_CTYPE, loc.ptr).fromStringz.endsWith(loc);
    });
    scope(exit) () @trusted { setlocale(LC_CTYPE, oldCt); } ();
    alias strs = AliasSeq!("xä\U0001F607", "yö\U0001F608"w);
    {
        auto f = File(deleteme, "w");
        version (CRuntime_Microsoft)
        {
            () @trusted { _setmode(fileno(f.getFP()), _O_U8TEXT); } ();
        }
        else
        {
            assert(fwide(f.getFP(), 1) == 1);
        }
        auto writer = f.lockingTextWriter();
        assert(writer.orientation_ == 1);
        static foreach (s; strs) writer.put(s);
    }
    assert(std.file.readText!string(deleteme).stripLeft("\uFEFF") ==
        text(strs));
}
@safe unittest // https://issues.dlang.org/show_bug.cgi?id=18789
{
    static import std.file;
    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);
    // converting to char
    {
        auto f = File(deleteme, "w");
        f.writeln("\U0001F608"w); // UTFException
    }
    // converting to wchar_t
    {
        auto f = File(deleteme, "w,ccs=UTF-16LE");
        // from char
        f.writeln("ö"); // writes garbage
        f.writeln("\U0001F608"); // ditto
        // from wchar
        f.writeln("\U0001F608"w); // leads to ErrnoException
    }
}

@safe unittest
{
    import std.exception : collectException;
    auto e = collectException({ File f; f.writeln("Hello!"); }());
    assert(e && e.msg == "Attempting to write to closed File");
}

@safe unittest // https://issues.dlang.org/show_bug.cgi?id=21592
{
    import std.exception : collectException;
    import std.utf : UTFException;
    static import std.file;
    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);
    auto f = File(deleteme, "w");
    auto e = collectException!UTFException(f.writeln(wchar(0xD801)));
    assert(e.next is null);
}

version (StdStressTest)
{
    // https://issues.dlang.org/show_bug.cgi?id=15768
    @system unittest
    {
        import std.parallelism : parallel;
        import std.range : iota;

        auto deleteme = testFilename();
        stderr = File(deleteme, "w");

        foreach (t; 1_000_000.iota.parallel)
        {
            stderr.write("aaa");
        }
    }
}

/// Used to specify the lock type for `File.lock` and `File.tryLock`.
enum LockType
{
    /**
     * Specifies a _read (shared) lock. A _read lock denies all processes
     * write access to the specified region of the file, including the
     * process that first locks the region. All processes can _read the
     * locked region. Multiple simultaneous _read locks are allowed, as
     * long as there are no exclusive locks.
     */
    read,

    /**
     * Specifies a read/write (exclusive) lock. A read/write lock denies all
     * other processes both read and write access to the locked file region.
     * If a segment has an exclusive lock, it may not have any shared locks
     * or other exclusive locks.
     */
    readWrite
}

struct LockingTextReader
{
    private File _f;
    private char _front;
    private bool _hasChar;

    this(File f)
    {
        import std.exception : enforce;
        enforce(f.isOpen, "LockingTextReader: File must be open");
        _f = f;
        _FLOCK(_f._p.handle);
    }

    this(this)
    {
        _FLOCK(_f._p.handle);
    }

    ~this()
    {
        if (_hasChar)
            ungetc(_front, cast(FILE*)_f._p.handle);

        // File locking has its own reference count
        if (_f.isOpen) _FUNLOCK(_f._p.handle);
    }

    void opAssign(LockingTextReader r)
    {
        import std.algorithm.mutation : swap;
        swap(this, r);
    }

    @property bool empty()
    {
        if (!_hasChar)
        {
            if (!_f.isOpen || _f.eof)
                return true;
            immutable int c = _FGETC(cast(_iobuf*) _f._p.handle);
            if (c == EOF)
            {
                .destroy(_f);
                return true;
            }
            _front = cast(char) c;
            _hasChar = true;
        }
        return false;
    }

    @property char front()
    {
        if (!_hasChar)
        {
            version (assert)
            {
                import core.exception : RangeError;
                if (empty)
                    throw new RangeError();
            }
            else
            {
                empty;
            }
        }
        return _front;
    }

    void popFront()
    {
        if (!_hasChar)
            empty;
        _hasChar = false;
    }
}

@system unittest
{
    // @system due to readf
    static import std.file;
    import std.range.primitives : isInputRange;

    static assert(isInputRange!LockingTextReader);
    auto deleteme = testFilename();
    std.file.write(deleteme, "1 2 3");
    scope(exit) std.file.remove(deleteme);
    int x;
    auto f = File(deleteme);
    f.readf("%s ", &x);
    assert(x == 1);
    f.readf("%d ", &x);
    assert(x == 2);
    f.readf("%d ", &x);
    assert(x == 3);
}

// https://issues.dlang.org/show_bug.cgi?id=13686
@system unittest
{
    import std.algorithm.comparison : equal;
    static import std.file;
    import std.utf : byDchar;

    auto deleteme = testFilename();
    std.file.write(deleteme, "Тест");
    scope(exit) std.file.remove(deleteme);

    string s;
    File(deleteme).readf("%s", &s);
    assert(s == "Тест");

    auto ltr = LockingTextReader(File(deleteme)).byDchar;
    assert(equal(ltr, "Тест".byDchar));
}

// https://issues.dlang.org/show_bug.cgi?id=12320
@system unittest
{
    static import std.file;
    auto deleteme = testFilename();
    std.file.write(deleteme, "ab");
    scope(exit) std.file.remove(deleteme);
    auto ltr = LockingTextReader(File(deleteme));
    assert(ltr.front == 'a');
    ltr.popFront();
    assert(ltr.front == 'b');
    ltr.popFront();
    assert(ltr.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=14861
@system unittest
{
    // @system due to readf
    static import std.file;
    auto deleteme = testFilename();
    File fw = File(deleteme, "w");
    for (int i; i != 5000; i++)
        fw.writeln(i, ";", "Иванов;Пётр;Петрович");
    fw.close();
    scope(exit) std.file.remove(deleteme);
    // Test read
    File fr = File(deleteme, "r");
    scope (exit) fr.close();
    int nom; string fam, nam, ot;
    // Error format read
    while (!fr.eof)
        fr.readf("%s;%s;%s;%s\n", &nom, &fam, &nam, &ot);
}

/**
 * Indicates whether `T` is a file handle, i.e. the type
 * is implicitly convertable to $(LREF File) or a pointer to a
 * $(REF FILE, core,stdc,stdio).
 *
 * Returns:
 *      `true` if `T` is a file handle, `false` otherwise.
 */
template isFileHandle(T)
{
    enum isFileHandle = is(T : FILE*) ||
        is(T : File);
}

///
@safe unittest
{
    static assert(isFileHandle!(FILE*));
    static assert(isFileHandle!(File));
}

/**
 * Property used by writeln/etc. so it can infer @safe since stdout is __gshared
 */
private @property File trustedStdout() @trusted
{
    return stdout;
}

/***********************************
Writes its arguments in text format to standard output (without a trailing newline).

Params:
    args = the items to write to `stdout`

Throws: In case of an I/O error, throws an `StdioException`.

Example:
    Reads `stdin` and writes it to `stdout` with an argument
    counter.
---
import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         write("Input ", count, ": ", line, "\n");
    }
}
---
 */
void write(T...)(T args)
if (!is(T[0] : File))
{
    trustedStdout.write(args);
}

@system unittest
{
    static import std.file;

    scope(failure) printf("Failed test at line %d\n", __LINE__);
    void[] buf;
    if (false) write(buf);
    // test write
    auto deleteme = testFilename();
    auto f = File(deleteme, "w");
    f.write("Hello, ",  "world number ", 42, "!");
    f.close();
    scope(exit) { std.file.remove(deleteme); }
    assert(cast(char[]) std.file.read(deleteme) == "Hello, world number 42!");
}

/***********************************
 * Equivalent to `write(args, '\n')`.  Calling `writeln` without
 * arguments is valid and just prints a newline to the standard
 * output.
 *
 * Params:
 *      args = the items to write to `stdout`
 *
 * Throws:
 *      In case of an I/O error, throws an $(LREF StdioException).
 * Example:
 *        Reads `stdin` and writes it to `stdout` with an argument
 *        counter.
---
import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
---
 */
void writeln(T...)(T args)
{
    static if (T.length == 0)
    {
        import std.exception : enforce;

        enforce(fputc('\n', .trustedStdout._p.handle) != EOF, "fputc failed");
    }
    else static if (T.length == 1 &&
                    is(T[0] : const(char)[]) &&
                    (is(T[0] == U[], U) || __traits(isStaticArray, T[0])))
    {
        // Specialization for strings - a very frequent case
        auto w = .trustedStdout.lockingTextWriter();

        static if (__traits(isStaticArray, T[0]))
        {
            w.put(args[0][]);
        }
        else
        {
            w.put(args[0]);
        }
        w.put('\n');
    }
    else
    {
        // Most general instance
        trustedStdout.write(args, '\n');
    }
}

@safe unittest
{
    // Just make sure the call compiles
    if (false) writeln();

    if (false) writeln("wyda");

    // https://issues.dlang.org/show_bug.cgi?id=8040
    if (false) writeln(null);
    if (false) writeln(">", null, "<");

    // https://issues.dlang.org/show_bug.cgi?id=14041
    if (false)
    {
        char[8] a;
        writeln(a);
        immutable b = a;
        b.writeln;
        const c = a[];
        c.writeln;
    }
}

@system unittest
{
    static import std.file;

    scope(failure) printf("Failed test at line %d\n", __LINE__);

    // test writeln
    auto deleteme = testFilename();
    auto f = File(deleteme, "w");
    scope(exit) { std.file.remove(deleteme); }
    f.writeln("Hello, ",  "world number ", 42, "!");
    f.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, world number 42!\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, world number 42!\n");

    // test writeln on stdout
    auto saveStdout = stdout;
    scope(exit) stdout = saveStdout;
    stdout.open(deleteme, "w");
    writeln("Hello, ",  "world number ", 42, "!");
    stdout.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, world number 42!\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, world number 42!\n");

    stdout.open(deleteme, "w");
    writeln("Hello!"c);
    writeln("Hello!"w);    // https://issues.dlang.org/show_bug.cgi?id=8386
    writeln("Hello!"d);    // https://issues.dlang.org/show_bug.cgi?id=8386
    writeln("embedded\0null"c); // https://issues.dlang.org/show_bug.cgi?id=8730
    stdout.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
            "Hello!\r\nHello!\r\nHello!\r\nembedded\0null\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
            "Hello!\nHello!\nHello!\nembedded\0null\n");
}

@system unittest
{
    static import std.file;

    auto deleteme = testFilename();
    auto f = File(deleteme, "w");
    scope(exit) { std.file.remove(deleteme); }

    enum EI : int    { A, B }
    enum ED : double { A = 0, B } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle
    enum EC : char   { A = 0, B } // NOTE: explicit initialization to 0 required during Enum init deprecation cycle
    enum ES : string { A = "aaa", B = "bbb" }

    f.writeln(EI.A);  // false, but A on 2.058
    f.writeln(EI.B);  // true, but B on 2.058

    f.writeln(ED.A);  // A
    f.writeln(ED.B);  // B

    f.writeln(EC.A);  // A
    f.writeln(EC.B);  // B

    f.writeln(ES.A);  // A
    f.writeln(ES.B);  // B

    f.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
                "A\r\nB\r\nA\r\nB\r\nA\r\nB\r\nA\r\nB\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
                "A\nB\nA\nB\nA\nB\nA\nB\n");
}

@system unittest
{
    static auto useInit(T)(T ltw)
    {
        T val;
        val = ltw;
        val = T.init;
        return val;
    }
    useInit(stdout.lockingTextWriter());
}

@system unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=21920
    void function(string) printer = &writeln!string;
    if (false) printer("Hello");
}


/***********************************
Writes formatted data to standard output (without a trailing newline).

Params:
fmt = The $(REF_ALTTEXT format string, formattedWrite, std, _format).
When passed as a compile-time argument, the string will be statically checked
against the argument types passed.
args = Items to write.

Note: In older versions of Phobos, it used to be possible to write:

------
writef(stderr, "%s", "message");
------

to print a message to `stderr`. This syntax is no longer supported, and has
been superceded by:

------
stderr.writef("%s", "message");
------

*/
void writef(alias fmt, A...)(A args)
if (isSomeString!(typeof(fmt)))
{
    import std.format : checkFormatException;

    alias e = checkFormatException!(fmt, A);
    static assert(!e, e);
    return .writef(fmt, args);
}

/// ditto
void writef(Char, A...)(in Char[] fmt, A args)
{
    trustedStdout.writef(fmt, args);
}

@system unittest
{
    static import std.file;

    scope(failure) printf("Failed test at line %d\n", __LINE__);

    // test writef
    auto deleteme = testFilename();
    auto f = File(deleteme, "w");
    scope(exit) { std.file.remove(deleteme); }
    f.writef!"Hello, %s world number %s!"("nice", 42);
    f.close();
    assert(cast(char[]) std.file.read(deleteme) ==  "Hello, nice world number 42!");
    // test write on stdout
    auto saveStdout = stdout;
    scope(exit) stdout = saveStdout;
    stdout.open(deleteme, "w");
    writef!"Hello, %s world number %s!"("nice", 42);
    stdout.close();
    assert(cast(char[]) std.file.read(deleteme) == "Hello, nice world number 42!");
}

/***********************************
 * Equivalent to $(D writef(fmt, args, '\n')).
 */
void writefln(alias fmt, A...)(A args)
if (isSomeString!(typeof(fmt)))
{
    import std.format : checkFormatException;

    alias e = checkFormatException!(fmt, A);
    static assert(!e, e);
    return .writefln(fmt, args);
}

/// ditto
void writefln(Char, A...)(in Char[] fmt, A args)
{
    trustedStdout.writefln(fmt, args);
}

@system unittest
{
    static import std.file;

    scope(failure) printf("Failed test at line %d\n", __LINE__);

    // test File.writefln
    auto deleteme = testFilename();
    auto f = File(deleteme, "w");
    scope(exit) { std.file.remove(deleteme); }
    f.writefln!"Hello, %s world number %s!"("nice", 42);
    f.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, nice world number 42!\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, nice world number 42!\n",
                cast(char[]) std.file.read(deleteme));

    // test writefln
    auto saveStdout = stdout;
    scope(exit) stdout = saveStdout;
    stdout.open(deleteme, "w");
    writefln!"Hello, %s world number %s!"("nice", 42);
    stdout.close();
    version (Windows)
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, nice world number 42!\r\n");
    else
        assert(cast(char[]) std.file.read(deleteme) ==
                "Hello, nice world number 42!\n");
}

/**
 * Reads formatted data from `stdin` using $(REF formattedRead, std,_format).
 * Params:
 * format = The $(REF_ALTTEXT format string, formattedWrite, std, _format).
 * When passed as a compile-time argument, the string will be statically checked
 * against the argument types passed.
 * args = Items to be read.
 * Returns:
 *      Same as `formattedRead`: The number of variables filled. If the input range `r` ends early,
 *      this number will be less than the number of variables provided.
 * Example:
----
// test.d
void main()
{
    import std.stdio;
    foreach (_; 0 .. 3)
    {
        int a;
        readf!" %d"(a);
        writeln(++a);
    }
}
----
$(CONSOLE
% echo "1 2 3" | rdmd test.d
2
3
4
)
 */
uint readf(alias format, A...)(auto ref A args)
if (isSomeString!(typeof(format)))
{
    import std.format : checkFormatException;

    alias e = checkFormatException!(format, A);
    static assert(!e, e);
    return .readf(format, args);
}

/// ditto
uint readf(A...)(scope const(char)[] format, auto ref A args)
{
    return stdin.readf(format, args);
}

@system unittest
{
    float f;
    if (false) readf("%s", &f);

    char a;
    wchar b;
    dchar c;
    if (false) readf("%s %s %s", a, b, c);
    // backwards compatibility with pointers
    if (false) readf("%s %s %s", a, &b, c);
    if (false) readf("%s %s %s", &a, &b, &c);
}

/**********************************
 * Read line from `stdin`.
 *
 * This version manages its own read buffer, which means one memory allocation per call. If you are not
 * retaining a reference to the read data, consider the `readln(buf)` version, which may offer
 * better performance as it can reuse its read buffer.
 *
 * Returns:
 *        The line that was read, including the line terminator character.
 * Params:
 *        S = Template parameter; the type of the allocated buffer, and the type returned. Defaults to `string`.
 *        terminator = Line terminator (by default, `'\n'`).
 * Note:
 *        String terminators are not supported due to ambiguity with readln(buf) below.
 * Throws:
 *        `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.
 * Example:
 *        Reads `stdin` and writes it to `stdout`.
---
import std.stdio;

void main()
{
    string line;
    while ((line = readln()) !is null)
        write(line);
}
---
*/
S readln(S = string)(dchar terminator = '\n')
if (isSomeString!S)
{
    return stdin.readln!S(terminator);
}

/**********************************
 * Read line from `stdin` and write it to buf[], including terminating character.
 *
 * This can be faster than $(D line = readln()) because you can reuse
 * the buffer for each call. Note that reusing the buffer means that you
 * must copy the previous contents if you wish to retain them.
 *
 * Returns:
 *        `size_t` 0 for end of file, otherwise number of characters read
 * Params:
 *        buf = Buffer used to store the resulting line data. buf is resized as necessary.
 *        terminator = Line terminator (by default, `'\n'`). Use $(REF newline, std,ascii)
 *        for portability (unless the file was opened in text mode).
 * Throws:
 *        `StdioException` on I/O error, or `UnicodeException` on Unicode conversion error.
 * Example:
 *        Reads `stdin` and writes it to `stdout`.
---
import std.stdio;

void main()
{
    char[] buf;
    while (readln(buf))
        write(buf);
}
---
*/
size_t readln(C)(ref C[] buf, dchar terminator = '\n')
if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
{
    return stdin.readln(buf, terminator);
}

/** ditto */
size_t readln(C, R)(ref C[] buf, R terminator)
if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
    isBidirectionalRange!R && is(typeof(terminator.front == dchar.init)))
{
    return stdin.readln(buf, terminator);
}

@safe unittest
{
    import std.meta : AliasSeq;

    //we can't actually test readln, so at the very least,
    //we test compilability
    void foo()
    {
        readln();
        readln('\t');
        static foreach (String; AliasSeq!(string, char[], wstring, wchar[], dstring, dchar[]))
        {
            readln!String();
            readln!String('\t');
        }
        static foreach (String; AliasSeq!(char[], wchar[], dchar[]))
        {{
            String buf;
            readln(buf);
            readln(buf, '\t');
            readln(buf, "<br />");
        }}
    }
}

/**
Reads a line from `stdin` and parses it using $(REF formattedRead, std,format,read).

Params:
  format = The $(MREF_ALTTEXT format string, std,format). When passed as a
  compile-time argument, the string will be statically checked against the
  argument types passed.
  data = Items to be read.

Returns: Same as `formattedRead`: the number of variables filled. If the
input ends early, this number will be less that the number of variables
provided.

Example:
---
// sum_rows.d
void main()
{
    import std.stdio;
    int a, b, c;
    while (readfln("%d %d %d", a, b, c) == 3)
    {
        writeln(a + b + c);
    }
}
---
$(CONSOLE
% cat << EOF > input
1 2 3
4 5 6
7 8 9
EOF
% rdmd sum_rows.d < input
6
15
24
)
*/
uint readfln(alias format, Data...)(auto ref Data data)
{
    import std.format : checkFormatException;

    alias e = checkFormatException!(format, Data);
    static assert(!e, e);
    return .readfln(format, data);
}

/// ditto
uint readfln(Data...)(scope const(char)[] format, auto ref Data data)
{
    return stdin.readfln(format, data);
}

@system unittest
{
    float f;
    string s;
    char c;
    int n;
    if (false) readfln("%f %s %c %d", f, s, c, n);
    if (false) readfln!"%f %s %c %d"(f, s, c, n);

}

/*
 * Convenience function that forwards to `core.sys.posix.stdio.fopen`
 * (to `_wfopen` on Windows)
 * with appropriately-constructed C-style strings.
 */
private FILE* _fopen(R1, R2)(R1 name, R2 mode = "r")
if ((isSomeFiniteCharInputRange!R1 || isSomeString!R1) &&
    (isSomeFiniteCharInputRange!R2 || isSomeString!R2))
{
    import std.internal.cstring : tempCString;

    auto namez = name.tempCString!FSChar();
    auto modez = mode.tempCString!FSChar();

    static _fopenImpl(scope const(FSChar)* namez, scope const(FSChar)* modez) @trusted nothrow @nogc
    {
        version (Windows)
        {
            return _wfopen(namez, modez);
        }
        else version (Posix)
        {
            /*
             * The new opengroup large file support API is transparently
             * included in the normal C bindings. https://www.opengroup.org/platform/lfs.html#1.0
             * if _FILE_OFFSET_BITS in druntime is 64, off_t is 64 bit and
             * the normal functions work fine. If not, then large file support
             * probably isn't available. Do not use the old transitional API
             * (the native extern(C) fopen64, https://unix.org/version2/whatsnew/lfs20mar.html#3.0)
             */
            import core.sys.posix.stdio : fopen;
            return fopen(namez, modez);
        }
        else
        {
            return fopen(namez, modez);
        }
    }
    return _fopenImpl(namez, modez);
}

version (Posix)
{
    /***********************************
     * Convenience function that forwards to `core.sys.posix.stdio.popen`
     * with appropriately-constructed C-style strings.
     */
    FILE* _popen(R1, R2)(R1 name, R2 mode = "r") @trusted nothrow @nogc
    if ((isSomeFiniteCharInputRange!R1 || isSomeString!R1) &&
        (isSomeFiniteCharInputRange!R2 || isSomeString!R2))
    {
        import std.internal.cstring : tempCString;

        auto namez = name.tempCString!FSChar();
        auto modez = mode.tempCString!FSChar();

        static popenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc
        {
            import core.sys.posix.stdio : popen;
            return popen(namez, modez);
        }
        return popenImpl(namez, modez);
    }
}

/*
 * Convenience function that forwards to `core.stdc.stdio.fwrite`
 */
private auto trustedFwrite(T)(FILE* f, const T[] obj) @trusted
{
    return fwrite(obj.ptr, T.sizeof, obj.length, f);
}

/*
 * Convenience function that forwards to `core.stdc.stdio.fread`
 */
private auto trustedFread(T)(FILE* f, T[] obj) @trusted
if (!imported!"std.traits".hasIndirections!T)
{
    return fread(obj.ptr, T.sizeof, obj.length, f);
}

private auto trustedFread(T)(FILE* f, T[] obj) @system
if (imported!"std.traits".hasIndirections!T)
{
    return fread(obj.ptr, T.sizeof, obj.length, f);
}

/**
 * Iterates through the lines of a file by using `foreach`.
 *
 * Example:
 *
---------
void main()
{
  foreach (string line; lines(stdin))
  {
    ... use line ...
  }
}
---------
The line terminator (`'\n'` by default) is part of the string read (it
could be missing in the last line of the file). Several types are
supported for `line`, and the behavior of `lines`
changes accordingly:

$(OL $(LI If `line` has type `string`, $(D
wstring), or `dstring`, a new string of the respective type
is allocated every read.) $(LI If `line` has type $(D
char[]), `wchar[]`, `dchar[]`, the line's content
will be reused (overwritten) across reads.) $(LI If `line`
has type `immutable(ubyte)[]`, the behavior is similar to
case (1), except that no UTF checking is attempted upon input.) $(LI
If `line` has type `ubyte[]`, the behavior is
similar to case (2), except that no UTF checking is attempted upon
input.))

In all cases, a two-symbols versions is also accepted, in which case
the first symbol (of integral type, e.g. `ulong` or $(D
uint)) tracks the zero-based number of the current line.

Example:
----
  foreach (ulong i, string line; lines(stdin))
  {
    ... use line ...
  }
----

 In case of an I/O error, an `StdioException` is thrown.

See_Also:
$(LREF byLine)
 */

struct lines
{
    private File f;
    private dchar terminator = '\n';

    /**
    Constructor.
    Params:
    f = File to read lines from.
    terminator = Line separator (`'\n'` by default).
    */
    this(File f, dchar terminator = '\n') @safe
    {
        this.f = f;
        this.terminator = terminator;
    }

    int opApply(D)(scope D dg)
    {
        import std.traits : Parameters;
        alias Parms = Parameters!(dg);
        static if (isSomeString!(Parms[$ - 1]))
        {
            int result = 0;
            static if (is(Parms[$ - 1] : const(char)[]))
                alias C = char;
            else static if (is(Parms[$ - 1] : const(wchar)[]))
                alias C = wchar;
            else static if (is(Parms[$ - 1] : const(dchar)[]))
                alias C = dchar;
            C[] line;
            static if (Parms.length == 2)
                Parms[0] i = 0;
            for (;;)
            {
                import std.conv : to;

                if (!f.readln(line, terminator)) break;
                auto copy = to!(Parms[$ - 1])(line);
                static if (Parms.length == 2)
                {
                    result = dg(i, copy);
                    ++i;
                }
                else
                {
                    result = dg(copy);
                }
                if (result != 0) break;
            }
            return result;
        }
        else
        {
            // raw read
            return opApplyRaw(dg);
        }
    }
    // no UTF checking
    int opApplyRaw(D)(scope D dg)
    {
        import std.conv : to;
        import std.exception : assumeUnique;
        import std.traits : Parameters;

        alias Parms = Parameters!(dg);
        enum duplicate = is(Parms[$ - 1] : immutable(ubyte)[]);
        int result = 1;
        int c = void;
        _FLOCK(f._p.handle);
        scope(exit) _FUNLOCK(f._p.handle);
        ubyte[] buffer;
        static if (Parms.length == 2)
            Parms[0] line = 0;
        while ((c = _FGETC(cast(_iobuf*) f._p.handle)) != -1)
        {
            buffer ~= to!(ubyte)(c);
            if (c == terminator)
            {
                static if (duplicate)
                    auto arg = assumeUnique(buffer);
                else
                    alias arg = buffer;
                // unlock the file while calling the delegate
                _FUNLOCK(f._p.handle);
                scope(exit) _FLOCK(f._p.handle);
                static if (Parms.length == 1)
                {
                    result = dg(arg);
                }
                else
                {
                    result = dg(line, arg);
                    ++line;
                }
                if (result) break;
                static if (!duplicate)
                    buffer.length = 0;
            }
        }
        // can only reach when _FGETC returned -1
        if (!f.eof) throw new StdioException("Error in reading file"); // error occured
        return result;
    }
}

@safe unittest
{
    /*
        As pointed out in <https://github.com/dlang/phobos/issues/10605>,
        it's a pity that `byLine()` & co. aren't @safe to use yet.

        This is a first attempt at working towards that goal.
        For now, this test doesn't do much; as there isn't much to do safely yet.
     */
    auto deleteMe = testFilename();
    scope(exit) { imported!"std.file".remove(deleteMe); }

    // Setup
    {
        auto f = File(deleteMe, "w");
        scope(exit) { f.close(); }
        foreach (i; 1 .. 11)
            f.writeln(i);
    }

    // Actual tests
    {
        auto f = File(deleteMe, "r");
        scope(exit) { f.close(); }

        auto myLines = lines(f);
        foreach (string line; myLines)
            continue;
    }


    {
        auto f = File(deleteMe, "r");
        scope(exit) { f.close(); }

        auto myByLineCopy = f.byLineCopy;
        foreach (line; myByLineCopy)
            continue;
    }

    {
        auto f = File(deleteMe, "r");
        scope(exit) { f.close(); }

        auto myByLine = f.byLine;
        foreach (line; myByLine)
            continue;
    }
}

@system unittest
{
    static import std.file;
    import std.meta : AliasSeq;

    scope(failure) printf("Failed test at line %d\n", __LINE__);

    auto deleteme = testFilename();
    scope(exit) { std.file.remove(deleteme); }

    alias TestedWith =
          AliasSeq!(string, wstring, dstring,
                    char[], wchar[], dchar[]);
    foreach (T; TestedWith)
    {
        // test looping with an empty file
        std.file.write(deleteme, "");
        auto f = File(deleteme, "r");
        foreach (T line; lines(f))
        {
            assert(false);
        }
        f.close();

        // test looping with a file with three lines
        std.file.write(deleteme, "Line one\nline two\nline three\n");
        f.open(deleteme, "r");
        uint i = 0;
        foreach (T line; lines(f))
        {
            if (i == 0) assert(line == "Line one\n");
            else if (i == 1) assert(line == "line two\n");
            else if (i == 2) assert(line == "line three\n");
            else assert(false);
            ++i;
        }
        f.close();

        // test looping with a file with three lines, last without a newline
        std.file.write(deleteme, "Line one\nline two\nline three");
        f.open(deleteme, "r");
        i = 0;
        foreach (T line; lines(f))
        {
            if (i == 0) assert(line == "Line one\n");
            else if (i == 1) assert(line == "line two\n");
            else if (i == 2) assert(line == "line three");
            else assert(false);
            ++i;
        }
        f.close();
    }

    // test with ubyte[] inputs
    alias TestedWith2 = AliasSeq!(immutable(ubyte)[], ubyte[]);
    foreach (T; TestedWith2)
    {
        // test looping with an empty file
        std.file.write(deleteme, "");
        auto f = File(deleteme, "r");
        foreach (T line; lines(f))
        {
            assert(false);
        }
        f.close();

        // test looping with a file with three lines
        std.file.write(deleteme, "Line one\nline two\nline three\n");
        f.open(deleteme, "r");
        uint i = 0;
        foreach (T line; lines(f))
        {
            if (i == 0) assert(cast(char[]) line == "Line one\n");
            else if (i == 1) assert(cast(char[]) line == "line two\n",
                T.stringof ~ " " ~ cast(char[]) line);
            else if (i == 2) assert(cast(char[]) line == "line three\n");
            else assert(false);
            ++i;
        }
        f.close();

        // test looping with a file with three lines, last without a newline
        std.file.write(deleteme, "Line one\nline two\nline three");
        f.open(deleteme, "r");
        i = 0;
        foreach (T line; lines(f))
        {
            if (i == 0) assert(cast(char[]) line == "Line one\n");
            else if (i == 1) assert(cast(char[]) line == "line two\n");
            else if (i == 2) assert(cast(char[]) line == "line three");
            else assert(false);
            ++i;
        }
        f.close();

    }

    static foreach (T; AliasSeq!(ubyte[]))
    {
        // test looping with a file with three lines, last without a newline
        // using a counter too this time
        std.file.write(deleteme, "Line one\nline two\nline three");
        auto f = File(deleteme, "r");
        uint i = 0;
        foreach (ulong j, T line; lines(f))
        {
            if (i == 0) assert(cast(char[]) line == "Line one\n");
            else if (i == 1) assert(cast(char[]) line == "line two\n");
            else if (i == 2) assert(cast(char[]) line == "line three");
            else assert(false);
            ++i;
        }
        f.close();
    }
}

/**
Iterates through a file a chunk at a time by using `foreach`.

Example:

---------
void main()
{
    foreach (ubyte[] buffer; chunks(stdin, 4096))
    {
        ... use buffer ...
    }
}
---------

The content of `buffer` is reused across calls. In the
 example above, `buffer.length` is 4096 for all iterations,
 except for the last one, in which case `buffer.length` may
 be less than 4096 (but always greater than zero).

 In case of an I/O error, an `StdioException` is thrown.
*/
auto chunks(File f, size_t size)
{
    return ChunksImpl(f, size);
}
private struct ChunksImpl
{
    private File f;
    private size_t size;
    // private string fileName; // Currently, no use

    this(File f, size_t size)
    in
    {
        assert(size, "size must be larger than 0");
    }
    do
    {
        this.f = f;
        this.size = size;
    }

    int opApply(D)(scope D dg)
    {
        import core.stdc.stdlib : alloca;
        import std.exception : enforce;

        enforce(f.isOpen, "Attempting to read from an unopened file");
        enum maxStackSize = 1024 * 16;
        ubyte[] buffer = void;
        if (size < maxStackSize)
            buffer = (cast(ubyte*) alloca(size))[0 .. size];
        else
            buffer = new ubyte[size];
        size_t r = void;
        int result = 1;
        uint tally = 0;
        while ((r = trustedFread(f._p.handle, buffer)) > 0)
        {
            assert(r <= size);
            if (r != size)
            {
                // error occured
                if (!f.eof) throw new StdioException(null);
                buffer.length = r;
            }
            static if (is(typeof(dg(tally, buffer))))
            {
                if ((result = dg(tally, buffer)) != 0) break;
            }
            else
            {
                if ((result = dg(buffer)) != 0) break;
            }
            ++tally;
        }
        return result;
    }
}

@system unittest
{
    static import std.file;

    scope(failure) printf("Failed test at line %d\n", __LINE__);

    auto deleteme = testFilename();
    scope(exit) { std.file.remove(deleteme); }

    // test looping with an empty file
    std.file.write(deleteme, "");
    auto f = File(deleteme, "r");
    foreach (ubyte[] line; chunks(f, 4))
    {
        assert(false);
    }
    f.close();

    // test looping with a file with three lines
    std.file.write(deleteme, "Line one\nline two\nline three\n");
    f = File(deleteme, "r");
    uint i = 0;
    foreach (ubyte[] line; chunks(f, 3))
    {
        if (i == 0) assert(cast(char[]) line == "Lin");
        else if (i == 1) assert(cast(char[]) line == "e o");
        else if (i == 2) assert(cast(char[]) line == "ne\n");
        else break;
        ++i;
    }
    f.close();
}

// Issue 21730 - null ptr dereferenced in ChunksImpl.opApply (SIGSEGV)
@system unittest
{
    import std.exception : assertThrown;
    static import std.file;

    auto deleteme = testFilename();
    scope(exit) { if (std.file.exists(deleteme)) std.file.remove(deleteme); }

    auto err1 = File(deleteme, "w+x");
    err1.close;
    std.file.remove(deleteme);
    assertThrown(() {foreach (ubyte[] buf; chunks(err1, 4096)) {}}());
}

/**
Writes an array or range to a file.
Shorthand for $(D data.copy(File(fileName, "wb").lockingBinaryWriter)).
Similar to $(REF write, std,file), strings are written as-is,
rather than encoded according to the `File`'s $(HTTP
en.cppreference.com/w/c/io#Narrow_and_wide_orientation,
orientation).
*/
void toFile(T)(T data, string fileName)
if (is(typeof(copy(data, stdout.lockingBinaryWriter))))
{
    copy(data, File(fileName, "wb").lockingBinaryWriter);
}

@system unittest
{
    static import std.file;

    auto deleteme = testFilename();
    scope(exit) { std.file.remove(deleteme); }

    "Test".toFile(deleteme);
    assert(std.file.readText(deleteme) == "Test");
}

/*********************
 * Thrown if I/O errors happen.
 */
class StdioException : Exception
{
    static import core.stdc.errno;
    /// Operating system error code.
    uint errno;

/**
Initialize with a message and an error code.
*/
    this(string message, uint e = core.stdc.errno.errno) @trusted
    {
        import std.exception : errnoString;
        errno = e;
        auto sysmsg = errnoString(errno);
        // If e is 0, we don't use the system error message.  (The message
        // is "Success", which is rather pointless for an exception.)
        super(e == 0 ? message
                     : (message ? message ~ " (" ~ sysmsg ~ ")" : sysmsg));
    }

/** Convenience functions that throw an `StdioException`. */
    static void opCall(string msg) @safe
    {
        throw new StdioException(msg);
    }

/// ditto
    static void opCall() @safe
    {
        throw new StdioException(null, core.stdc.errno.errno);
    }
}

enum StdFileHandle: string
{
    stdin  = "core.stdc.stdio.stdin",
    stdout = "core.stdc.stdio.stdout",
    stderr = "core.stdc.stdio.stderr",
}

// Undocumented but public because the std* handles are aliasing it.
@property ref File makeGlobal(StdFileHandle _iob)()
{
    __gshared File.Impl impl;
    __gshared File result;

    // Use an inline spinlock to make sure the initializer is only run once.
    // We assume there will be at most uint.max / 2 threads trying to initialize
    // `handle` at once and steal the high bit to indicate that the globals have
    // been initialized.
    static shared uint spinlock;
    import core.atomic : atomicLoad, atomicOp, MemoryOrder;
    if (atomicLoad!(MemoryOrder.acq)(spinlock) <= uint.max / 2)
    {
        for (;;)
        {
            if (atomicLoad!(MemoryOrder.acq)(spinlock) > uint.max / 2)
                break;
            if (atomicOp!"+="(spinlock, 1) == 1)
            {
                with (StdFileHandle)
                    assert(_iob == stdin || _iob == stdout || _iob == stderr);
                impl.handle = cast() mixin(_iob);
                result._p = &impl;
                atomicOp!"+="(spinlock, uint.max / 2);
                break;
            }
            atomicOp!"-="(spinlock, 1);
        }
    }
    return result;
}

/** The standard input stream.

    Returns:
        stdin as a $(LREF File).

    Note:
        The returned $(LREF File) wraps $(REF stdin,core,stdc,stdio), and
        is therefore thread global. Reassigning `stdin` to a different
        `File` must be done in a single-threaded or locked context in
        order to avoid race conditions.

        All reading from `stdin` automatically locks the file globally,
        and will cause all other threads calling `read` to wait until
        the lock is released.
*/
alias stdin = makeGlobal!(StdFileHandle.stdin);

///
@safe unittest
{
    // Read stdin, sort lines, write to stdout
    import std.algorithm.mutation : copy;
    import std.algorithm.sorting : sort;
    import std.array : array;
    import std.typecons : Yes;

    void main()
    {
        stdin                       // read from stdin
        .byLineCopy(Yes.keepTerminator) // copying each line
        .array()                    // convert to array of lines
        .sort()                     // sort the lines
        .copy(                      // copy output of .sort to an OutputRange
            stdout.lockingTextWriter()); // the OutputRange
    }
}

/**
    The standard output stream.

    Returns:
        stdout as a $(LREF File).

    Note:
        The returned $(LREF File) wraps $(REF stdout,core,stdc,stdio), and
        is therefore thread global. Reassigning `stdout` to a different
        `File` must be done in a single-threaded or locked context in
        order to avoid race conditions.

        All writing to `stdout` automatically locks the file globally,
        and will cause all other threads calling `write` to wait until
        the lock is released.
*/
alias stdout = makeGlobal!(StdFileHandle.stdout);

///
@safe unittest
{
    void main()
    {
        stdout.writeln("Write a message to stdout.");
    }
}

///
@safe unittest
{
    void main()
    {
        import std.algorithm.iteration : filter, map, sum;
        import std.format : format;
        import std.range : iota, tee;

        int len;
        const r = 6.iota
                  .filter!(a => a % 2) // 1 3 5
                  .map!(a => a * 2) // 2 6 10
                  .tee!(_ => stdout.writefln("len: %d", len++))
                  .sum;

        assert(r == 18);
    }
}

///
@safe unittest
{
    void main()
    {
        import std.algorithm.mutation : copy;
        import std.algorithm.iteration : map;
        import std.format : format;
        import std.range : iota;

        10.iota
        .map!(e => "N: %d".format(e))
        .copy(stdout.lockingTextWriter()); // the OutputRange
    }
}

/**
    The standard error stream.

    Returns:
        stderr as a $(LREF File).

    Note:
        The returned $(LREF File) wraps $(REF stderr,core,stdc,stdio), and
        is therefore thread global. Reassigning `stderr` to a different
        `File` must be done in a single-threaded or locked context in
        order to avoid race conditions.

        All writing to `stderr` automatically locks the file globally,
        and will cause all other threads calling `write` to wait until
        the lock is released.
*/
alias stderr = makeGlobal!(StdFileHandle.stderr);

///
@safe unittest
{
    void main()
    {
        stderr.writeln("Write a message to stderr.");
    }
}

@system unittest
{
    static import std.file;
    import std.typecons : tuple;

    scope(failure) printf("Failed test at line %d\n", __LINE__);
    auto deleteme = testFilename();

    std.file.write(deleteme, "1 2\n4 1\n5 100");
    scope(exit) std.file.remove(deleteme);
    {
        File f = File(deleteme);
        scope(exit) f.close();
        auto t = [ tuple(1, 2), tuple(4, 1), tuple(5, 100) ];
        uint i;
        foreach (e; f.byRecord!(int, int)("%s %s"))
        {
            //writeln(e);
            assert(e == t[i++]);
        }
        assert(i == 3);
    }
}

@safe unittest
{
    // Retain backwards compatibility
    // https://issues.dlang.org/show_bug.cgi?id=17472
    static assert(is(typeof(stdin) == File));
    static assert(is(typeof(stdout) == File));
    static assert(is(typeof(stderr) == File));
}

// roll our own appender, but with "safe" arrays
private struct ReadlnAppender
{
    char[] buf;
    size_t pos;
    bool safeAppend = false;

    void initialize(char[] b) @safe
    {
        buf = b;
        pos = 0;
    }
    @property char[] data() @trusted
    {
        if (safeAppend)
            assumeSafeAppend(buf.ptr[0 .. pos]);
        return buf.ptr[0 .. pos];
    }

    bool reserveWithoutAllocating(size_t n)
    {
        if (buf.length >= pos + n) // buf is already large enough
            return true;

        immutable curCap = buf.capacity;
        if (curCap >= pos + n)
        {
            buf.length = curCap;
            /* Any extra capacity we end up not using can safely be claimed
            by someone else. */
            safeAppend = true;
            return true;
        }

        return false;
    }
    void reserve(size_t n) @trusted
    {
        import core.stdc.string : memcpy;
        if (!reserveWithoutAllocating(n))
        {
            size_t ncap = buf.length * 2 + 128 + n;
            char[] nbuf = new char[ncap];
            memcpy(nbuf.ptr, buf.ptr, pos);
            buf = nbuf;
            // Allocated a new buffer. No one else knows about it.
            safeAppend = true;
        }
    }
    void putchar(char c) @trusted
    {
        reserve(1);
        buf.ptr[pos++] = c;
    }
    void putdchar(dchar dc) @trusted
    {
        import std.utf : encode, UseReplacementDchar;

        char[4] ubuf;
        immutable size = encode!(UseReplacementDchar.yes)(ubuf, dc);
        reserve(size);
        foreach (c; ubuf)
            buf.ptr[pos++] = c;
    }
    void putonly(const char[] b) @trusted
    {
        import core.stdc.string : memcpy;
        assert(pos == 0);   // assume this is the only put call
        if (reserveWithoutAllocating(b.length))
            memcpy(buf.ptr + pos, b.ptr, b.length);
        else
            buf = b.dup;
        pos = b.length;
    }
}

private struct LockedFile
{
    private @system _iobuf* fp;

    this(FILE* fps) @trusted
    {
        _FLOCK(fps);
        // Since fps is now locked, we can cast away shared
        fp = cast(_iobuf*) fps;
    }

    @disable this();
    @disable this(this);
    @disable void opAssign(LockedFile);

    // these use unlocked fgetc calls
    @trusted fgetc() { return _FGETC(fp); }
    @trusted fgetwc() { return _FGETWC(fp); }

    ~this() @trusted
    {
        _FUNLOCK(cast(FILE*) fp);
    }
}

@safe unittest
{
    void f() @safe
    {
        FILE* fps;
        auto lf = LockedFile(fps);
        static assert(!__traits(compiles, lf = LockedFile(fps)));
        version (ShouldFail)
        {
            lf.fps = null; // error with -preview=systemVariables
        }
    }
}

// Private implementation of readln
private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator, File.Orientation orientation) @safe
{
    version (CRuntime_Microsoft)
    {
        auto lf = LockedFile(fps);

        ReadlnAppender app;
        app.initialize(buf);

        int c;
        while ((c = lf.fgetc()) != -1)
        {
            app.putchar(cast(char) c);
            if (c == terminator)
            {
                buf = app.data;
                return buf.length;
            }

        }

        if (ferror(fps))
            StdioException();
        buf = app.data;
        return buf.length;
    }
    else static if (__traits(compiles, core.sys.posix.stdio.getdelim))
    {
        if (orientation == File.Orientation.wide)
        {
            import core.stdc.wchar_ : fwide;

            auto lf = LockedFile(fps);
            /* Stream is in wide characters.
             * Read them and convert to chars.
             */
            version (Windows)
            {
                buf.length = 0;
                for (int c = void; (c = lf.fgetwc()) != -1; )
                {
                    if ((c & ~0x7F) == 0)
                    {   buf ~= c;
                        if (c == terminator)
                            break;
                    }
                    else
                    {
                        if (c >= 0xD800 && c <= 0xDBFF)
                        {
                            int c2 = void;
                            if ((c2 = lf.fgetwc()) != -1 ||
                                    c2 < 0xDC00 && c2 > 0xDFFF)
                            {
                                StdioException("unpaired UTF-16 surrogate");
                            }
                            c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
                        }
                        import std.utf : encode;
                        encode(buf, c);
                    }
                }
                if (ferror(fps))
                    StdioException();
                return buf.length;
            }
            else version (Posix)
            {
                buf.length = 0;
                for (int c; (c = lf.fgetwc()) != -1; )
                {
                    import std.utf : encode;

                    if ((c & ~0x7F) == 0)
                        buf ~= cast(char) c;
                    else
                        encode(buf, cast(dchar) c);
                    if (c == terminator)
                        break;
                }
                if (ferror(fps))
                    StdioException();
                return buf.length;
            }
            else
            {
                static assert(0);
            }
        }
        return () @trusted {
            import core.stdc.stdlib : free;

            static char *lineptr = null;
            static size_t n = 0;
            scope(exit)
            {
                if (n > 128 * 1024)
                {
                    // Bound memory used by readln
                    free(lineptr);
                    lineptr = null;
                    n = 0;
                }
            }

            const s = core.sys.posix.stdio.getdelim(&lineptr, &n, terminator, fps);
            if (s < 0)
            {
                if (ferror(fps))
                    StdioException();
                buf.length = 0;                // end of file
                return 0;
            }

            const line = lineptr[0 .. s];
            if (s <= buf.length)
            {
                buf = buf[0 .. s];
                buf[] = line;
            }
            else
            {
                buf = line.dup;
            }
            return s;
        }();
    }
    else // version (NO_GETDELIM)
    {
        import core.stdc.wchar_ : fwide;

        auto lf = LockedFile(fps);
        if (orientation == File.Orientation.wide)
        {
            /* Stream is in wide characters.
             * Read them and convert to chars.
             */
            version (Windows)
            {
                buf.length = 0;
                for (int c; (c = lf.fgetwc()) != -1; )
                {
                    if ((c & ~0x7F) == 0)
                    {   buf ~= c;
                        if (c == terminator)
                            break;
                    }
                    else
                    {
                        if (c >= 0xD800 && c <= 0xDBFF)
                        {
                            int c2 = void;
                            if ((c2 = lf.fgetwc()) != -1 ||
                                    c2 < 0xDC00 && c2 > 0xDFFF)
                            {
                                StdioException("unpaired UTF-16 surrogate");
                            }
                            c = ((c - 0xD7C0) << 10) + (c2 - 0xDC00);
                        }
                        import std.utf : encode;
                        encode(buf, c);
                    }
                }
                if (ferror(fps))
                    StdioException();
                return buf.length;
            }
            else version (Posix)
            {
                import std.utf : encode;
                buf.length = 0;
                for (int c; (c = lf.fgetwc()) != -1; )
                {
                    if ((c & ~0x7F) == 0)
                        buf ~= cast(char) c;
                    else
                        encode(buf, cast(dchar) c);
                    if (c == terminator)
                        break;
                }
                if (ferror(fps))
                    StdioException();
                return buf.length;
            }
            else
            {
                static assert(0);
            }
        }

        // Narrow stream
        // First, fill the existing buffer
        for (size_t bufPos = 0; bufPos < buf.length; )
        {
            immutable c = lf.fgetc();
            if (c == -1)
            {
                buf.length = bufPos;
                goto endGame;
            }
            buf[bufPos++] = cast(char) c;
            if (c == terminator)
            {
                // No need to test for errors in file
                buf.length = bufPos;
                return bufPos;
            }
        }
        // Then, append to it
        for (int c; (c = lf.fgetc()) != -1; )
        {
            buf ~= cast(char) c;
            if (c == terminator)
            {
                // No need to test for errors in file
                return buf.length;
            }
        }

    endGame:
        if (ferror(fps))
            StdioException();
        return buf.length;
    }
}

@system unittest
{
    static import std.file;
    auto deleteme = testFilename();
    scope(exit) std.file.remove(deleteme);

    std.file.write(deleteme, "abcd\n0123456789abcde\n1234\n");
    File f = File(deleteme, "rb");

    char[] ln = new char[2];
    f.readln(ln);

    assert(ln == "abcd\n");
    char[] t = ln[0 .. 2];
    t ~= 't';
    assert(t == "abt");
    // https://issues.dlang.org/show_bug.cgi?id=13856: ln stomped to "abtd"
    assert(ln == "abcd\n");

    // it can also stomp the array length
    ln = new char[4];
    f.readln(ln);
    assert(ln == "0123456789abcde\n");

    char[100] buf;
    ln = buf[];
    f.readln(ln);
    assert(ln == "1234\n");
    assert(ln.ptr == buf.ptr); // avoid allocation, buffer is good enough
}

/** Experimental network access via the File interface

        Opens a TCP connection to the given host and port, then returns
        a File struct with read and write access through the same interface
        as any other file (meaning writef and the byLine ranges work!).

        Authors:
                Adam D. Ruppe

        Bugs:
                Only works on Linux
*/
version (linux)
{
    File openNetwork(string host, ushort port)
    {
        import core.stdc.string : memcpy;
        import core.sys.posix.arpa.inet : htons;
        import core.sys.posix.netdb : gethostbyname;
        import core.sys.posix.netinet.in_ : sockaddr_in;
        static import core.sys.posix.unistd;
        static import sock = core.sys.posix.sys.socket;
        import std.conv : to;
        import std.exception : enforce;
        import std.internal.cstring : tempCString;

        auto h = enforce( gethostbyname(host.tempCString()),
            new StdioException("gethostbyname"));

        int s = sock.socket(sock.AF_INET, sock.SOCK_STREAM, 0);
        enforce(s != -1, new StdioException("socket"));

        scope(failure)
        {
            // want to make sure it doesn't dangle if something throws. Upon
            // normal exit, the File struct's reference counting takes care of
            // closing, so we don't need to worry about success
            core.sys.posix.unistd.close(s);
        }

        sockaddr_in addr;

        addr.sin_family = sock.AF_INET;
        addr.sin_port = htons(port);
        memcpy(&addr.sin_addr.s_addr, h.h_addr, h.h_length);

        enforce(sock.connect(s, cast(sock.sockaddr*) &addr, addr.sizeof) != -1,
            new StdioException("Connect failed"));

        File f;
        f.fdopen(s, "w+", host ~ ":" ~ to!string(port));
        return f;
    }
}

version (StdUnittest) private string testFilename(string file = __FILE__, size_t line = __LINE__) @safe
{
    import std.conv : text;
    import std.file : deleteme;
    import std.path : baseName;

    // filename intentionally contains non-ASCII (Russian) characters for
    // https://issues.dlang.org/show_bug.cgi?id=7648
    return text(deleteme, "-детка.", baseName(file), ".", line);
}
