// Written in the D programming language.

/**
Utilities for manipulating files and scanning directories. Functions
in this module handle files as a unit, e.g., read or write one file
at a time. For opening files and manipulating them via handles refer
to module $(MREF std, stdio).

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD General) $(TD
          $(LREF exists)
          $(LREF isDir)
          $(LREF isFile)
          $(LREF isSymlink)
          $(LREF rename)
          $(LREF thisExePath)
))
$(TR $(TD Directories) $(TD
          $(LREF chdir)
          $(LREF dirEntries)
          $(LREF getcwd)
          $(LREF mkdir)
          $(LREF mkdirRecurse)
          $(LREF rmdir)
          $(LREF rmdirRecurse)
          $(LREF tempDir)
))
$(TR $(TD Files) $(TD
          $(LREF append)
          $(LREF copy)
          $(LREF read)
          $(LREF readText)
          $(LREF remove)
          $(LREF slurp)
          $(LREF write)
))
$(TR $(TD Symlinks) $(TD
          $(LREF symlink)
          $(LREF readLink)
))
$(TR $(TD Attributes) $(TD
          $(LREF attrIsDir)
          $(LREF attrIsFile)
          $(LREF attrIsSymlink)
          $(LREF getAttributes)
          $(LREF getLinkAttributes)
          $(LREF getSize)
          $(LREF setAttributes)
))
$(TR $(TD Timestamp) $(TD
          $(LREF getTimes)
          $(LREF getTimesWin)
          $(LREF setTimes)
          $(LREF timeLastModified)
          $(LREF timeLastAccessed)
          $(LREF timeStatusChanged)
))
$(TR $(TD Other) $(TD
          $(LREF DirEntry)
          $(LREF FileException)
          $(LREF PreserveAttributes)
          $(LREF SpanMode)
          $(LREF getAvailableDiskSpace)
))
))


Copyright: Copyright The D Language Foundation 2007 - 2011.
See_Also:  The $(HTTP ddili.org/ders/d.en/files.html, official tutorial) for an
introduction to working with files in D, module
$(MREF std, stdio) for opening files and manipulating them via handles,
and module $(MREF std, path) for manipulating path strings.

License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors:   $(HTTP digitalmars.com, Walter Bright),
           $(HTTP erdani.org, Andrei Alexandrescu),
           $(HTTP jmdavisprog.com, Jonathan M Davis)
Source:    $(PHOBOSSRC std/file.d)
 */
module std.file;

import core.stdc.errno, core.stdc.stdlib, core.stdc.string;
import core.time : abs, dur, hnsecs, seconds;

import std.datetime.date : DateTime;
import std.datetime.systime : Clock, SysTime, unixTimeToStdTime;
import std.internal.cstring;
import std.meta;
import std.range;
import std.traits;
import std.typecons;

version (OSX)
    version = Darwin;
else version (iOS)
    version = Darwin;
else version (TVOS)
    version = Darwin;
else version (WatchOS)
    version = Darwin;

version (Windows)
{
    import core.sys.windows.winbase, core.sys.windows.winnt, std.windows.syserror;
}
else version (Posix)
{
    import core.sys.posix.dirent, core.sys.posix.fcntl, core.sys.posix.sys.stat,
        core.sys.posix.sys.time, core.sys.posix.unistd, core.sys.posix.utime;
}
else
    static assert(false, "Module " ~ .stringof ~ " not implemented for this OS.");

// Character type used for operating system filesystem APIs
version (Windows)
{
    private alias FSChar = WCHAR;       // WCHAR can be aliased to wchar or wchar_t
}
else version (Posix)
{
    private alias FSChar = char;
}
else
    static assert(0);

// Purposefully not documented. Use at your own risk
@property string deleteme() @safe
{
    import std.conv : text;
    import std.path : buildPath;
    import std.process : thisProcessID;

    enum base = "deleteme.dmd.unittest.pid";
    static string fileName;

    if (!fileName)
        fileName = text(buildPath(tempDir(), base), thisProcessID);
    return fileName;
}

version (StdUnittest) private struct TestAliasedString
{
    string get() @safe @nogc pure nothrow return scope { return _s; }
    alias get this;
    @disable this(this);
    string _s;
}

version (Android)
{
    package enum system_directory = "/system/etc";
    package enum system_file      = "/system/etc/hosts";
}
else version (Posix)
{
    package enum system_directory = "/usr/include";
    package enum system_file      = "/usr/include/assert.h";
}


/++
    Exception thrown for file I/O errors.
 +/
class FileException : Exception
{
    import std.conv : text, to;

    /++
        OS error code.
     +/
    immutable uint errno;

    private this(scope const(char)[] name, scope const(char)[] msg, string file, size_t line, uint errno) @safe pure
    {
        if (msg.empty)
            super(name is null ? "(null)" : name.idup, file, line);
        else
            super(text(name is null ? "(null)" : name, ": ", msg), file, line);

        this.errno = errno;
    }

    /++
        Constructor which takes an error message.

        Params:
            name = Name of file for which the error occurred.
            msg  = Message describing the error.
            file = The file where the error occurred.
            line = The _line where the error occurred.
     +/
    this(scope const(char)[] name, scope const(char)[] msg, string file = __FILE__, size_t line = __LINE__) @safe pure
    {
        this(name, msg, file, line, 0);
    }

    /++
        Constructor which takes the error number ($(LUCKY GetLastError)
        in Windows, $(D_PARAM errno) in POSIX).

        Params:
            name  = Name of file for which the error occurred.
            errno = The error number.
            file  = The file where the error occurred.
                    Defaults to `__FILE__`.
            line  = The _line where the error occurred.
                    Defaults to `__LINE__`.
     +/
    version (Windows) this(scope const(char)[] name,
                          uint errno = .GetLastError(),
                          string file = __FILE__,
                          size_t line = __LINE__) @safe
    {
        this(name, generateSysErrorMsg(errno), file, line, errno);
    }
    else version (Posix) this(scope const(char)[] name,
                             uint errno = .errno,
                             string file = __FILE__,
                             size_t line = __LINE__) @trusted
    {
        import std.exception : errnoString;
        this(name, errnoString(errno), file, line, errno);
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;

    assertThrown!FileException("non.existing.file.".readText);
}

private T cenforce(T)(T condition, lazy scope const(char)[] name, string file = __FILE__, size_t line = __LINE__)
{
    if (condition)
        return condition;
    version (Windows)
    {
        throw new FileException(name, .GetLastError(), file, line);
    }
    else version (Posix)
    {
        throw new FileException(name, .errno, file, line);
    }
}

version (Windows)
@trusted
private T cenforce(T)(T condition, scope const(char)[] name, scope const(FSChar)* namez,
    string file = __FILE__, size_t line = __LINE__)
{
    if (condition)
        return condition;
    if (!name)
    {
        import core.stdc.wchar_ : wcslen;
        import std.conv : to;

        auto len = namez ? wcslen(namez) : 0;
        name = to!string(namez[0 .. len]);
    }
    throw new FileException(name, .GetLastError(), file, line);
}

version (Posix)
@trusted
private T cenforce(T)(T condition, scope const(char)[] name, scope const(FSChar)* namez,
    string file = __FILE__, size_t line = __LINE__)
{
    if (condition)
        return condition;
    if (!name)
    {
        import core.stdc.string : strlen;

        auto len = namez ? strlen(namez) : 0;
        name = namez[0 .. len].idup;
    }
    throw new FileException(name, .errno, file, line);
}

// https://issues.dlang.org/show_bug.cgi?id=17102
@safe unittest
{
    try
    {
        cenforce(false, null, null,
                __FILE__, __LINE__);
    }
    catch (FileException) {}
}

/* **********************************
 * Basic File operations.
 */

/********************************************
Read entire contents of file `name` and returns it as an untyped
array. If the file size is larger than `upTo`, only `upTo`
bytes are _read.

Params:
    name = string or range of characters representing the file _name
    upTo = if present, the maximum number of bytes to _read

Returns: Untyped array of bytes _read.

Throws: $(LREF FileException) on error.

See_Also: $(REF readText, std,file) for reading and validating a text file.
 */

void[] read(R)(R name, size_t upTo = size_t.max)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        return readImpl(name, name.tempCString!FSChar(), upTo);
    else
        return readImpl(null, name.tempCString!FSChar(), upTo);
}

///
@safe unittest
{
    import std.utf : byChar;
    scope(exit)
    {
        assert(exists(deleteme));
        remove(deleteme);
    }

    std.file.write(deleteme, "1234"); // deleteme is the name of a temporary file
    assert(read(deleteme, 2) == "12");
    assert(read(deleteme.byChar) == "1234");
    assert((cast(const(ubyte)[])read(deleteme)).length == 4);
}

/// ditto
void[] read(R)(auto ref R name, size_t upTo = size_t.max)
if (isConvertibleToString!R)
{
    return read!(StringTypeOf!R)(name, upTo);
}

@safe unittest
{
    static assert(__traits(compiles, read(TestAliasedString(null))));
}

version (Posix) private void[] readImpl(scope const(char)[] name, scope const(FSChar)* namez,
                                        size_t upTo = size_t.max) @trusted
{
    import core.memory : GC;
    import std.algorithm.comparison : min;
    import std.conv : to;
    import std.checkedint : checked;

    // A few internal configuration parameters {
    enum size_t
        minInitialAlloc = 1024 * 4,
        maxInitialAlloc = size_t.max / 2,
        sizeIncrement = 1024 * 16,
        maxSlackMemoryAllowed = 1024;
    // }

    immutable fd = core.sys.posix.fcntl.open(namez,
            core.sys.posix.fcntl.O_RDONLY);
    cenforce(fd != -1, name);
    scope(exit) core.sys.posix.unistd.close(fd);

    stat_t statbuf = void;
    cenforce(fstat(fd, &statbuf) == 0, name, namez);

    immutable initialAlloc = min(upTo, to!size_t(statbuf.st_size
        ? min(statbuf.st_size + 1, maxInitialAlloc)
        : minInitialAlloc));
    void[] result = GC.malloc(initialAlloc, GC.BlkAttr.NO_SCAN)[0 .. initialAlloc];
    scope(failure) GC.free(result.ptr);

    auto size = checked(size_t(0));

    for (;;)
    {
        immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size.get,
                (min(result.length, upTo) - size).get);
        cenforce(actual != -1, name, namez);
        if (actual == 0) break;
        size += actual;
        if (size >= upTo) break;
        if (size < result.length) continue;
        immutable newAlloc = size + sizeIncrement;
        result = GC.realloc(result.ptr, newAlloc.get, GC.BlkAttr.NO_SCAN)[0 .. newAlloc.get];
    }

    return result.length - size >= maxSlackMemoryAllowed
        ? GC.realloc(result.ptr, size.get, GC.BlkAttr.NO_SCAN)[0 .. size.get]
        : result[0 .. size.get];
}

version (Windows)
private extern (Windows) @nogc nothrow
{
    pragma(mangle, CreateFileW.mangleof)
    HANDLE trustedCreateFileW(scope const(wchar)* namez, DWORD dwDesiredAccess,
        DWORD dwShareMode, SECURITY_ATTRIBUTES* lpSecurityAttributes,
        DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
        HANDLE hTemplateFile)  @trusted;

    pragma(mangle, CloseHandle.mangleof) BOOL trustedCloseHandle(HANDLE) @trusted;
}

version (Windows) private void[] readImpl(scope const(char)[] name, scope const(FSChar)* namez,
                                          size_t upTo = size_t.max) @trusted
{
    import core.memory : GC;
    import std.algorithm.comparison : min;
    static trustedGetFileSize(HANDLE hFile, out ulong fileSize)
    {
        DWORD sizeHigh;
        DWORD sizeLow = GetFileSize(hFile, &sizeHigh);
        const bool result = sizeLow != INVALID_FILE_SIZE;
        if (result)
            fileSize = makeUlong(sizeLow, sizeHigh);
        return result;
    }
    static trustedReadFile(HANDLE hFile, void *lpBuffer, size_t nNumberOfBytesToRead)
    {
        // Read by chunks of size < 4GB (Windows API limit)
        size_t totalNumRead = 0;
        while (totalNumRead != nNumberOfBytesToRead)
        {
            const uint chunkSize = min(nNumberOfBytesToRead - totalNumRead, 0xffff_0000);
            DWORD numRead = void;
            const result = ReadFile(hFile, lpBuffer + totalNumRead, chunkSize, &numRead, null);
            if (result == 0 || numRead != chunkSize)
                return false;
            totalNumRead += chunkSize;
        }
        return true;
    }

    alias defaults =
        AliasSeq!(GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE, (SECURITY_ATTRIBUTES*).init,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
            HANDLE.init);
    auto h = trustedCreateFileW(namez, defaults);

    cenforce(h != INVALID_HANDLE_VALUE, name, namez);
    scope(exit) cenforce(trustedCloseHandle(h), name, namez);
    ulong fileSize = void;
    cenforce(trustedGetFileSize(h, fileSize), name, namez);
    size_t size = min(upTo, fileSize);
    auto buf = () { return GC.malloc(size, GC.BlkAttr.NO_SCAN)[0 .. size]; } ();

    scope(failure)
    {
        () { GC.free(buf.ptr); } ();
    }

    if (size)
        cenforce(trustedReadFile(h, &buf[0], size), name, namez);
    return buf[0 .. size];
}

version (linux) @safe unittest
{
    // A file with "zero" length that doesn't have 0 length at all
    auto s = std.file.readText("/proc/cpuinfo");
    assert(s.length > 0);
    //writefln("'%s'", s);
}

@safe unittest
{
    scope(exit) if (exists(deleteme)) remove(deleteme);
    import std.stdio;
    auto f = File(deleteme, "w");
    f.write("abcd"); f.flush();
    assert(read(deleteme) == "abcd");
}

/++
    Reads and validates (using $(REF validate, std, utf)) a text file. S can be
    an array of any character type. However, no width or endian conversions are
    performed. So, if the width or endianness of the characters in the given
    file differ from the width or endianness of the element type of S, then
    validation will fail.

    Params:
        S = the string type of the file
        name = string or range of characters representing the file _name

    Returns: Array of characters read.

    Throws: $(LREF FileException) if there is an error reading the file,
            $(REF UTFException, std, utf) on UTF decoding error.

    See_Also: $(REF read, std,file) for reading a binary file.
+/
S readText(S = string, R)(auto ref R name)
if (isSomeString!S && (isSomeFiniteCharInputRange!R || is(StringTypeOf!R)))
{
    import std.algorithm.searching : startsWith;
    import std.encoding : getBOM, BOM;
    import std.exception : enforce;
    import std.format : format;
    import std.utf : UTFException, validate;

    static if (is(StringTypeOf!R))
        StringTypeOf!R filename = name;
    else
        auto filename = name;

    static auto trustedCast(T)(void[] buf) @trusted { return cast(T) buf; }
    auto data = trustedCast!(ubyte[])(read(filename));

    immutable bomSeq = getBOM(data);
    immutable bom = bomSeq.schema;

    static if (is(immutable ElementEncodingType!S == immutable char))
    {
        with(BOM) switch (bom)
        {
            case utf16be:
            case utf16le: throw new UTFException("UTF-8 requested. BOM is for UTF-16");
            case utf32be:
            case utf32le: throw new UTFException("UTF-8 requested. BOM is for UTF-32");
            default: break;
        }
    }
    else static if (is(immutable ElementEncodingType!S == immutable wchar))
    {
        with(BOM) switch (bom)
        {
            case utf8: throw new UTFException("UTF-16 requested. BOM is for UTF-8");
            case utf16be:
            {
                version (BigEndian)
                    break;
                else
                    throw new UTFException("BOM is for UTF-16 LE on Big Endian machine");
            }
            case utf16le:
            {
                version (BigEndian)
                    throw new UTFException("BOM is for UTF-16 BE on Little Endian machine");
                else
                    break;
            }
            case utf32be:
            case utf32le: throw new UTFException("UTF-8 requested. BOM is for UTF-32");
            default: break;
        }
    }
    else
    {
        with(BOM) switch (bom)
        {
            case utf8: throw new UTFException("UTF-16 requested. BOM is for UTF-8");
            case utf16be:
            case utf16le: throw new UTFException("UTF-8 requested. BOM is for UTF-16");
            case utf32be:
            {
                version (BigEndian)
                    break;
                else
                    throw new UTFException("BOM is for UTF-32 LE on Big Endian machine");
            }
            case utf32le:
            {
                version (BigEndian)
                    throw new UTFException("BOM is for UTF-32 BE on Little Endian machine");
                else
                    break;
            }
            default: break;
        }
    }

    if (data.length % ElementEncodingType!S.sizeof != 0)
        throw new UTFException(format!"The content of %s is not UTF-%s"(filename, ElementEncodingType!S.sizeof * 8));

    auto result = trustedCast!S(data);
    validate(result);
    return result;
}

/// Read file with UTF-8 text.
@safe unittest
{
    write(deleteme, "abc"); // deleteme is the name of a temporary file
    scope(exit) remove(deleteme);
    string content = readText(deleteme);
    assert(content == "abc");
}

// Read file with UTF-8 text but try to read it as UTF-16.
@safe unittest
{
    import std.exception : assertThrown;
    import std.utf : UTFException;

    write(deleteme, "abc");
    scope(exit) remove(deleteme);
    // Throws because the file is not valid UTF-16.
    assertThrown!UTFException(readText!wstring(deleteme));
}

// Read file with UTF-16 text.
@safe unittest
{
    import std.algorithm.searching : skipOver;

    write(deleteme, "\uFEFFabc"w); // With BOM
    scope(exit) remove(deleteme);
    auto content = readText!wstring(deleteme);
    assert(content == "\uFEFFabc"w);
    // Strips BOM if present.
    content.skipOver('\uFEFF');
    assert(content == "abc"w);
}

@safe unittest
{
    static assert(__traits(compiles, readText(TestAliasedString(null))));
}

@safe unittest
{
    import std.array : appender;
    import std.bitmanip : append, Endian;
    import std.exception : assertThrown;
    import std.path : buildPath;
    import std.string : representation;
    import std.utf : UTFException;

    mkdir(deleteme);
    scope(exit) rmdirRecurse(deleteme);

    immutable none8 = buildPath(deleteme, "none8");
    immutable none16 = buildPath(deleteme, "none16");
    immutable utf8 = buildPath(deleteme, "utf8");
    immutable utf16be = buildPath(deleteme, "utf16be");
    immutable utf16le = buildPath(deleteme, "utf16le");
    immutable utf32be = buildPath(deleteme, "utf32be");
    immutable utf32le = buildPath(deleteme, "utf32le");
    immutable utf7 = buildPath(deleteme, "utf7");

    write(none8, "京都市");
    write(none16, "京都市"w);
    write(utf8, (cast(char[])[0xEF, 0xBB, 0xBF]) ~ "京都市");
    {
        auto str = "\uFEFF京都市"w;
        auto arr = appender!(ubyte[])();
        foreach (c; str)
            arr.append(c);
        write(utf16be, arr.data);
    }
    {
        auto str = "\uFEFF京都市"w;
        auto arr = appender!(ubyte[])();
        foreach (c; str)
            arr.append!(ushort, Endian.littleEndian)(c);
        write(utf16le, arr.data);
    }
    {
        auto str = "\U0000FEFF京都市"d;
        auto arr = appender!(ubyte[])();
        foreach (c; str)
            arr.append(c);
        write(utf32be, arr.data);
    }
    {
        auto str = "\U0000FEFF京都市"d;
        auto arr = appender!(ubyte[])();
        foreach (c; str)
            arr.append!(uint, Endian.littleEndian)(c);
        write(utf32le, arr.data);
    }
    write(utf7, (cast(ubyte[])[0x2B, 0x2F, 0x76, 0x38, 0x2D]) ~ "foobar".representation);

    assertThrown!UTFException(readText(none16));
    assert(readText(utf8) == (cast(char[])[0xEF, 0xBB, 0xBF]) ~ "京都市");
    assertThrown!UTFException(readText(utf16be));
    assertThrown!UTFException(readText(utf16le));
    assertThrown!UTFException(readText(utf32be));
    assertThrown!UTFException(readText(utf32le));
    assert(readText(utf7) == (cast(char[])[0x2B, 0x2F, 0x76, 0x38, 0x2D]) ~ "foobar");

    assertThrown!UTFException(readText!wstring(none8));
    assert(readText!wstring(none16) == "京都市"w);
    assertThrown!UTFException(readText!wstring(utf8));
    version (BigEndian)
    {
        assert(readText!wstring(utf16be) == "\uFEFF京都市"w);
        assertThrown!UTFException(readText!wstring(utf16le));
    }
    else
    {
        assertThrown!UTFException(readText!wstring(utf16be));
        assert(readText!wstring(utf16le) == "\uFEFF京都市"w);
    }
    assertThrown!UTFException(readText!wstring(utf32be));
    assertThrown!UTFException(readText!wstring(utf32le));
    assertThrown!UTFException(readText!wstring(utf7));

    assertThrown!UTFException(readText!dstring(utf8));
    assertThrown!UTFException(readText!dstring(utf16be));
    assertThrown!UTFException(readText!dstring(utf16le));
    version (BigEndian)
    {
       assert(readText!dstring(utf32be) == "\U0000FEFF京都市"d);
       assertThrown!UTFException(readText!dstring(utf32le));
    }
    else
    {
       assertThrown!UTFException(readText!dstring(utf32be));
       assert(readText!dstring(utf32le) == "\U0000FEFF京都市"d);
    }
    assertThrown!UTFException(readText!dstring(utf7));
}

/*********************************************
Write `buffer` to file `name`.

Creates the file if it does not already exist.

Params:
    name = string or range of characters representing the file _name
    buffer = data to be written to file

Throws: $(LREF FileException) on error.

See_also: $(REF toFile, std,stdio)
 */
void write(R)(R name, const void[] buffer)
if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        writeImpl(name, name.tempCString!FSChar(), buffer, false);
    else
        writeImpl(null, name.tempCString!FSChar(), buffer, false);
}

///
@safe unittest
{
   scope(exit)
   {
       assert(exists(deleteme));
       remove(deleteme);
   }

   int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
   write(deleteme, a); // deleteme is the name of a temporary file
   const bytes = read(deleteme);
   const fileInts = () @trusted { return cast(int[]) bytes; }();
   assert(fileInts == a);
}

/// ditto
void write(R)(auto ref R name, const void[] buffer)
if (isConvertibleToString!R)
{
    write!(StringTypeOf!R)(name, buffer);
}

@safe unittest
{
    static assert(__traits(compiles, write(TestAliasedString(null), null)));
}

/*********************************************
Appends `buffer` to file `name`.

Creates the file if it does not already exist.

Params:
    name = string or range of characters representing the file _name
    buffer = data to be appended to file

Throws: $(LREF FileException) on error.
 */
void append(R)(R name, const void[] buffer)
if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        writeImpl(name, name.tempCString!FSChar(), buffer, true);
    else
        writeImpl(null, name.tempCString!FSChar(), buffer, true);
}

///
@safe unittest
{
   scope(exit)
   {
       assert(exists(deleteme));
       remove(deleteme);
   }

   int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
   write(deleteme, a); // deleteme is the name of a temporary file
   int[] b = [ 13, 21 ];
   append(deleteme, b);
   const bytes = read(deleteme);
   const fileInts = () @trusted { return cast(int[]) bytes; }();
   assert(fileInts == a ~ b);
}

/// ditto
void append(R)(auto ref R name, const void[] buffer)
if (isConvertibleToString!R)
{
    append!(StringTypeOf!R)(name, buffer);
}

@safe unittest
{
    static assert(__traits(compiles, append(TestAliasedString("foo"), [0, 1, 2, 3])));
}

// POSIX implementation helper for write and append

version (Posix) private void writeImpl(scope const(char)[] name, scope const(FSChar)* namez,
        scope const(void)[] buffer, bool append) @trusted
{
    import std.conv : octal;

    // append or write
    auto mode = append ? O_CREAT | O_WRONLY | O_APPEND
                       : O_CREAT | O_WRONLY | O_TRUNC;

    immutable fd = core.sys.posix.fcntl.open(namez, mode, octal!666);
    cenforce(fd != -1, name, namez);
    {
        scope(failure) core.sys.posix.unistd.close(fd);

        immutable size = buffer.length;
        size_t sum, cnt = void;
        while (sum != size)
        {
            cnt = (size - sum < 2^^30) ? (size - sum) : 2^^30;
            const numwritten = core.sys.posix.unistd.write(fd, buffer.ptr + sum, cnt);
            if (numwritten != cnt)
                break;
            sum += numwritten;
        }
        cenforce(sum == size, name, namez);
    }
    cenforce(core.sys.posix.unistd.close(fd) == 0, name, namez);
}

// Windows implementation helper for write and append

version (Windows) private void writeImpl(scope const(char)[] name, scope const(FSChar)* namez,
        scope const(void)[] buffer, bool append) @trusted
{
    HANDLE h;
    if (append)
    {
        alias defaults =
            AliasSeq!(GENERIC_WRITE, 0, null, OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
                HANDLE.init);

        h = CreateFileW(namez, defaults);
        cenforce(h != INVALID_HANDLE_VALUE, name, namez);
        cenforce(SetFilePointer(h, 0, null, FILE_END) != INVALID_SET_FILE_POINTER,
            name, namez);
    }
    else // write
    {
        alias defaults =
            AliasSeq!(GENERIC_WRITE, 0, null, CREATE_ALWAYS,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
                HANDLE.init);

        h = CreateFileW(namez, defaults);
        cenforce(h != INVALID_HANDLE_VALUE, name, namez);
    }
    immutable size = buffer.length;
    size_t sum, cnt = void;
    DWORD numwritten = void;
    while (sum != size)
    {
        cnt = (size - sum < 2^^30) ? (size - sum) : 2^^30;
        WriteFile(h, buffer.ptr + sum, cast(uint) cnt, &numwritten, null);
        if (numwritten != cnt)
            break;
        sum += numwritten;
    }
    cenforce(sum == size && CloseHandle(h), name, namez);
}

/***************************************************
 * Rename file `from` _to `to`, moving it between directories if required.
 * If the target file exists, it is overwritten.
 *
 * It is not possible to rename a file across different mount points
 * or drives. On POSIX, the operation is atomic. That means, if `to`
 * already exists there will be no time period during the operation
 * where `to` is missing. See
 * $(HTTP man7.org/linux/man-pages/man2/rename.2.html, manpage for rename)
 * for more details.
 *
 * Params:
 *    from = string or range of characters representing the existing file name
 *    to = string or range of characters representing the target file name
 *
 * Throws: $(LREF FileException) on error.
 */
void rename(RF, RT)(RF from, RT to)
if ((isSomeFiniteCharInputRange!RF || isSomeString!RF) && !isConvertibleToString!RF &&
    (isSomeFiniteCharInputRange!RT || isSomeString!RT) && !isConvertibleToString!RT)
{
    // Place outside of @trusted block
    auto fromz = from.tempCString!FSChar();
    auto toz = to.tempCString!FSChar();

    static if (isNarrowString!RF && is(immutable ElementEncodingType!RF == immutable char))
        alias f = from;
    else
        enum string f = null;

    static if (isNarrowString!RT && is(immutable ElementEncodingType!RT == immutable char))
        alias t = to;
    else
        enum string t = null;

    renameImpl(f, t, fromz, toz);
}

/// ditto
void rename(RF, RT)(auto ref RF from, auto ref RT to)
if (isConvertibleToString!RF || isConvertibleToString!RT)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, RF, RT);
    rename!Types(from, to);
}

@safe unittest
{
    static assert(__traits(compiles, rename(TestAliasedString(null), TestAliasedString(null))));
    static assert(__traits(compiles, rename("", TestAliasedString(null))));
    static assert(__traits(compiles, rename(TestAliasedString(null), "")));
    import std.utf : byChar;
    static assert(__traits(compiles, rename(TestAliasedString(null), "".byChar)));
}

///
@safe unittest
{
    auto t1 = deleteme, t2 = deleteme~"2";
    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();

    t1.write("1");
    t1.rename(t2);
    assert(t2.readText == "1");

    t1.write("2");
    t1.rename(t2);
    assert(t2.readText == "2");
}

private void renameImpl(scope const(char)[] f, scope const(char)[] t,
                        scope const(FSChar)* fromz, scope const(FSChar)* toz) @trusted
{
    version (Windows)
    {
        import std.exception : enforce;

        const result = MoveFileExW(fromz, toz, MOVEFILE_REPLACE_EXISTING);
        if (!result)
        {
            import core.stdc.wchar_ : wcslen;
            import std.conv : to, text;

            if (!f)
                f = fromz ? to!(typeof(f))(fromz[0 .. wcslen(fromz)]) : "(null)";

            if (!t)
                t = toz ? to!(typeof(t))(toz[0 .. wcslen(toz)]) : "(null)";

            enforce(false,
                new FileException(
                    text("Attempting to rename file ", f, " to ", t)));
        }
    }
    else version (Posix)
    {
        static import core.stdc.stdio;

        cenforce(core.stdc.stdio.rename(fromz, toz) == 0, t, toz);
    }
}

@safe unittest
{
    import std.utf : byWchar;

    auto t1 = deleteme, t2 = deleteme~"2";
    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();

    write(t1, "1");
    rename(t1, t2);
    assert(readText(t2) == "1");

    write(t1, "2");
    rename(t1, t2.byWchar);
    assert(readText(t2) == "2");
}

/***************************************************
Delete file `name`.

Params:
    name = string or range of characters representing the file _name

Throws: $(LREF FileException) on error.
 */
void remove(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        removeImpl(name, name.tempCString!FSChar());
    else
        removeImpl(null, name.tempCString!FSChar());
}

/// ditto
void remove(R)(auto ref R name)
if (isConvertibleToString!R)
{
    remove!(StringTypeOf!R)(name);
}

///
@safe unittest
{
    import std.exception : assertThrown;

    deleteme.write("Hello");
    assert(deleteme.readText == "Hello");

    deleteme.remove;
    assertThrown!FileException(deleteme.readText);
}

@safe unittest
{
    static assert(__traits(compiles, remove(TestAliasedString("foo"))));
}

private void removeImpl(scope const(char)[] name, scope const(FSChar)* namez) @trusted
{
    version (Windows)
    {
        cenforce(DeleteFileW(namez), name, namez);
    }
    else version (Posix)
    {
        static import core.stdc.stdio;

        if (!name)
        {
            import core.stdc.string : strlen;

            auto len = namez ? strlen(namez) : 0;
            name = namez[0 .. len];
        }
        cenforce(core.stdc.stdio.remove(namez) == 0,
            "Failed to remove file " ~ (name is null ? "(null)" : name));
    }
}

@safe unittest
{
    import std.exception : collectExceptionMsg, assertThrown;
    import std.algorithm.searching : startsWith;

    string filename = null; // e.g. as returned by File.tmpfile.name

    version (linux)
    {
        // exact exception message is OS-dependent
        auto msg = filename.remove.collectExceptionMsg!FileException;
        assert(msg.startsWith("Failed to remove file (null):"), msg);
    }
    else version (Windows)
    {
        // don't test exact message on windows, it's language dependent
        auto msg = filename.remove.collectExceptionMsg!FileException;
        assert(msg.startsWith("(null):"), msg);
    }
    else
    {
        assertThrown!FileException(filename.remove);
    }
}

version (Windows) private WIN32_FILE_ATTRIBUTE_DATA getFileAttributesWin(R)(R name)
if (isSomeFiniteCharInputRange!R)
{
    auto namez = name.tempCString!FSChar();

    WIN32_FILE_ATTRIBUTE_DATA fad = void;

    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
    {
        static void getFA(scope const(char)[] name, scope const(FSChar)* namez,
                          out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted
        {
            import std.exception : enforce;
            enforce(GetFileAttributesExW(namez, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &fad),
                new FileException(name.idup));
        }
        getFA(name, namez, fad);
    }
    else
    {
        static void getFA(scope const(FSChar)* namez, out WIN32_FILE_ATTRIBUTE_DATA fad) @trusted
        {
            import core.stdc.wchar_ : wcslen;
            import std.conv : to;
            import std.exception : enforce;

            enforce(GetFileAttributesExW(namez, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &fad),
                new FileException(namez[0 .. wcslen(namez)].to!string));
        }
        getFA(namez, fad);
    }
    return fad;
}

version (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure nothrow @nogc
{
    ULARGE_INTEGER li;
    li.LowPart  = dwLow;
    li.HighPart = dwHigh;
    return li.QuadPart;
}

version (Posix) private extern (C) pragma(mangle, stat.mangleof)
int trustedStat(scope const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted;

/**
Get size of file `name` in bytes.

Params:
    name = string or range of characters representing the file _name
Returns:
    The size of file in bytes.
Throws:
    $(LREF FileException) on error (e.g., file not found).
 */
ulong getSize(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        with (getFileAttributesWin(name))
            return makeUlong(nFileSizeLow, nFileSizeHigh);
    }
    else version (Posix)
    {
        auto namez = name.tempCString();

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        stat_t statbuf = void;
        cenforce(trustedStat(namez, statbuf) == 0, names, namez);
        return statbuf.st_size;
    }
}

/// ditto
ulong getSize(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return getSize!(StringTypeOf!R)(name);
}

@safe unittest
{
    static assert(__traits(compiles, getSize(TestAliasedString("foo"))));
}

///
@safe unittest
{
    scope(exit) deleteme.remove;

    // create a file of size 1
    write(deleteme, "a");
    assert(getSize(deleteme) == 1);

    // create a file of size 3
    write(deleteme, "abc");
    assert(getSize(deleteme) == 3);
}

@safe unittest
{
    // create a file of size 1
    write(deleteme, "a");
    scope(exit) deleteme.exists && deleteme.remove;
    assert(getSize(deleteme) == 1);
    // create a file of size 3
    write(deleteme, "abc");
    import std.utf : byChar;
    assert(getSize(deleteme.byChar) == 3);
}

// Reads a time field from a stat_t with full precision.
version (Posix)
private SysTime statTimeToStdTime(char which)(ref const stat_t statbuf)
{
    auto unixTime = mixin(`statbuf.st_` ~ which ~ `time`);
    long stdTime = unixTimeToStdTime(unixTime);

    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `tim`))))
        stdTime += mixin(`statbuf.st_` ~ which ~ `tim.tv_nsec`) / 100;
    else
    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `timensec`))))
        stdTime += mixin(`statbuf.st_` ~ which ~ `timensec`) / 100;
    else
    static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `time_nsec`))))
        stdTime += mixin(`statbuf.st_` ~ which ~ `time_nsec`) / 100;
    else
    static if (is(typeof(mixin(`statbuf.__st_` ~ which ~ `timensec`))))
        stdTime += mixin(`statbuf.__st_` ~ which ~ `timensec`) / 100;

    return SysTime(stdTime);
}

/++
    Get the access and modified times of file or folder `name`.

    Params:
        name             = File/Folder _name to get times for.
        accessTime       = Time the file/folder was last accessed.
        modificationTime = Time the file/folder was last modified.

    Throws:
        $(LREF FileException) on error.
 +/
void getTimes(R)(R name,
              out SysTime accessTime,
              out SysTime modificationTime)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        import std.datetime.systime : FILETIMEToSysTime;

        with (getFileAttributesWin(name))
        {
            accessTime = FILETIMEToSysTime(&ftLastAccessTime);
            modificationTime = FILETIMEToSysTime(&ftLastWriteTime);
        }
    }
    else version (Posix)
    {
        auto namez = name.tempCString();

        stat_t statbuf = void;

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(trustedStat(namez, statbuf) == 0, names, namez);

        accessTime = statTimeToStdTime!'a'(statbuf);
        modificationTime = statTimeToStdTime!'m'(statbuf);
    }
}

/// ditto
void getTimes(R)(auto ref R name,
              out SysTime accessTime,
              out SysTime modificationTime)
if (isConvertibleToString!R)
{
    return getTimes!(StringTypeOf!R)(name, accessTime, modificationTime);
}

///
@safe unittest
{
    import std.datetime : abs, SysTime;

    scope(exit) deleteme.remove;
    write(deleteme, "a");

    SysTime accessTime, modificationTime;

    getTimes(deleteme, accessTime, modificationTime);

    import std.datetime : Clock, seconds;
    auto currTime = Clock.currTime();
    enum leeway = 5.seconds;

    auto diffAccess = accessTime - currTime;
    auto diffModification = modificationTime - currTime;
    assert(abs(diffAccess) <= leeway);
    assert(abs(diffModification) <= leeway);
}

@safe unittest
{
    SysTime atime, mtime;
    static assert(__traits(compiles, getTimes(TestAliasedString("foo"), atime, mtime)));
}

@safe unittest
{
    import std.stdio : writefln;

    auto currTime = Clock.currTime();

    write(deleteme, "a");
    scope(exit) assert(deleteme.exists), deleteme.remove;

    SysTime accessTime1;
    SysTime modificationTime1;

    getTimes(deleteme, accessTime1, modificationTime1);

    enum leeway = 5.seconds;

    {
        auto diffa = accessTime1 - currTime;
        auto diffm = modificationTime1 - currTime;
        scope(failure) writefln("[%s] [%s] [%s] [%s] [%s]", accessTime1, modificationTime1, currTime, diffa, diffm);

        assert(abs(diffa) <= leeway);
        assert(abs(diffm) <= leeway);
    }

    version (fullFileTests)
    {
        import core.thread;
        enum sleepTime = dur!"seconds"(2);
        Thread.sleep(sleepTime);

        currTime = Clock.currTime();
        write(deleteme, "b");

        SysTime accessTime2 = void;
        SysTime modificationTime2 = void;

        getTimes(deleteme, accessTime2, modificationTime2);

        {
            auto diffa = accessTime2 - currTime;
            auto diffm = modificationTime2 - currTime;
            scope(failure) writefln("[%s] [%s] [%s] [%s] [%s]", accessTime2, modificationTime2, currTime, diffa, diffm);

            //There is no guarantee that the access time will be updated.
            assert(abs(diffa) <= leeway + sleepTime);
            assert(abs(diffm) <= leeway);
        }

        assert(accessTime1 <= accessTime2);
        assert(modificationTime1 <= modificationTime2);
    }
}


version (StdDdoc)
{
    /++
     $(BLUE This function is Windows-Only.)

     Get creation/access/modified times of file `name`.

     This is the same as `getTimes` except that it also gives you the file
     creation time - which isn't possible on POSIX systems.

     Params:
     name                 = File _name to get times for.
     fileCreationTime     = Time the file was created.
     fileAccessTime       = Time the file was last accessed.
     fileModificationTime = Time the file was last modified.

     Throws:
     $(LREF FileException) on error.
     +/
    void getTimesWin(R)(R name,
                        out SysTime fileCreationTime,
                        out SysTime fileAccessTime,
                        out SysTime fileModificationTime)
    if (isSomeFiniteCharInputRange!R || isConvertibleToString!R);
    // above line contains both constraints for docs
    // (so users know how it can be called)
}
else version (Windows)
{
    void getTimesWin(R)(R name,
                        out SysTime fileCreationTime,
                        out SysTime fileAccessTime,
                        out SysTime fileModificationTime)
    if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
    {
        import std.datetime.systime : FILETIMEToSysTime;

        with (getFileAttributesWin(name))
        {
            fileCreationTime = FILETIMEToSysTime(&ftCreationTime);
            fileAccessTime = FILETIMEToSysTime(&ftLastAccessTime);
            fileModificationTime = FILETIMEToSysTime(&ftLastWriteTime);
        }
    }

    void getTimesWin(R)(auto ref R name,
                        out SysTime fileCreationTime,
                        out SysTime fileAccessTime,
                        out SysTime fileModificationTime)
    if (isConvertibleToString!R)
    {
        getTimesWin!(StringTypeOf!R)(name, fileCreationTime, fileAccessTime, fileModificationTime);
    }
}

version (Windows) @system unittest
{
    import std.stdio : writefln;
    auto currTime = Clock.currTime();

    write(deleteme, "a");
    scope(exit) { assert(exists(deleteme)); remove(deleteme); }

    SysTime creationTime1 = void;
    SysTime accessTime1 = void;
    SysTime modificationTime1 = void;

    getTimesWin(deleteme, creationTime1, accessTime1, modificationTime1);

    enum leeway = dur!"seconds"(5);

    {
        auto diffc = creationTime1 - currTime;
        auto diffa = accessTime1 - currTime;
        auto diffm = modificationTime1 - currTime;
        scope(failure)
        {
            writefln("[%s] [%s] [%s] [%s] [%s] [%s] [%s]",
                     creationTime1, accessTime1, modificationTime1, currTime, diffc, diffa, diffm);
        }

        // Deleting and recreating a file doesn't seem to always reset the "file creation time"
        //assert(abs(diffc) <= leeway);
        assert(abs(diffa) <= leeway);
        assert(abs(diffm) <= leeway);
    }

    version (fullFileTests)
    {
        import core.thread;
        Thread.sleep(dur!"seconds"(2));

        currTime = Clock.currTime();
        write(deleteme, "b");

        SysTime creationTime2 = void;
        SysTime accessTime2 = void;
        SysTime modificationTime2 = void;

        getTimesWin(deleteme, creationTime2, accessTime2, modificationTime2);

        {
            auto diffa = accessTime2 - currTime;
            auto diffm = modificationTime2 - currTime;
            scope(failure)
            {
                writefln("[%s] [%s] [%s] [%s] [%s]",
                         accessTime2, modificationTime2, currTime, diffa, diffm);
            }

            assert(abs(diffa) <= leeway);
            assert(abs(diffm) <= leeway);
        }

        assert(creationTime1 == creationTime2);
        assert(accessTime1 <= accessTime2);
        assert(modificationTime1 <= modificationTime2);
    }

    {
        SysTime ctime, atime, mtime;
        static assert(__traits(compiles, getTimesWin(TestAliasedString("foo"), ctime, atime, mtime)));
    }
}

version (Darwin)
private
{
    import core.stdc.config : c_ulong;
    enum ATTR_CMN_MODTIME  = 0x00000400, ATTR_CMN_ACCTIME  = 0x00001000;
    alias attrgroup_t = uint;
    static struct attrlist
    {
        ushort bitmapcount, reserved;
        attrgroup_t commonattr, volattr, dirattr, fileattr, forkattr;
    }
    extern(C) int setattrlist(scope const(char)* path, scope ref attrlist attrs,
        scope void* attrbuf, size_t attrBufSize, c_ulong options) nothrow @nogc @system;
}

/++
    Set access/modified times of file or folder `name`.

    Params:
        name             = File/Folder _name to get times for.
        accessTime       = Time the file/folder was last accessed.
        modificationTime = Time the file/folder was last modified.

    Throws:
        $(LREF FileException) on error.
 +/
void setTimes(R)(R name,
              SysTime accessTime,
              SysTime modificationTime)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    auto namez = name.tempCString!FSChar();
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        alias names = name;
    else
        string names = null;
    setTimesImpl(names, namez, accessTime, modificationTime);
}

///
@safe unittest
{
    import std.datetime : DateTime, hnsecs, SysTime;

    scope(exit) deleteme.remove;
    write(deleteme, "a");

    SysTime accessTime = SysTime(DateTime(2010, 10, 4, 0, 0, 30));
    SysTime modificationTime = SysTime(DateTime(2018, 10, 4, 0, 0, 30));
    setTimes(deleteme, accessTime, modificationTime);

    SysTime accessTimeResolved, modificationTimeResolved;
    getTimes(deleteme, accessTimeResolved, modificationTimeResolved);

    assert(accessTime == accessTimeResolved);
    assert(modificationTime == modificationTimeResolved);
}

/// ditto
void setTimes(R)(auto ref R name,
              SysTime accessTime,
              SysTime modificationTime)
if (isConvertibleToString!R)
{
    setTimes!(StringTypeOf!R)(name, accessTime, modificationTime);
}

private void setTimesImpl(scope const(char)[] names, scope const(FSChar)* namez,
    SysTime accessTime, SysTime modificationTime) @trusted
{
    version (Windows)
    {
        import std.datetime.systime : SysTimeToFILETIME;
        const ta = SysTimeToFILETIME(accessTime);
        const tm = SysTimeToFILETIME(modificationTime);
        alias defaults =
            AliasSeq!(FILE_WRITE_ATTRIBUTES,
                      0,
                      null,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL |
                      FILE_ATTRIBUTE_DIRECTORY |
                      FILE_FLAG_BACKUP_SEMANTICS,
                      HANDLE.init);
        auto h = CreateFileW(namez, defaults);

        cenforce(h != INVALID_HANDLE_VALUE, names, namez);

        scope(exit)
            cenforce(CloseHandle(h), names, namez);

        cenforce(SetFileTime(h, null, &ta, &tm), names, namez);
    }
    else
    {
        static if (is(typeof(&utimensat)))
        {
            timespec[2] t = void;
            t[0] = accessTime.toTimeSpec();
            t[1] = modificationTime.toTimeSpec();
            cenforce(utimensat(AT_FDCWD, namez, t, 0) == 0, names, namez);
        }
        else
        {
            version (Darwin)
            {
                // Set modification & access times with setattrlist to avoid precision loss.
                attrlist attrs = { bitmapcount: 5, reserved: 0,
                        commonattr: ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME,
                        volattr: 0, dirattr: 0, fileattr: 0, forkattr: 0 };
                timespec[2] attrbuf = [modificationTime.toTimeSpec(), accessTime.toTimeSpec()];
                if (0 == setattrlist(namez, attrs, &attrbuf, attrbuf.sizeof, 0))
                    return;
                if (.errno != ENOTSUP)
                    cenforce(false, names, namez);
                // Not all volumes support setattrlist. In such cases
                // fall through to the utimes implementation.
            }
            timeval[2] t = void;
            t[0] = accessTime.toTimeVal();
            t[1] = modificationTime.toTimeVal();
            cenforce(utimes(namez, t) == 0, names, namez);
        }
    }
}

@safe unittest
{
    if (false) // Test instatiation
        setTimes(TestAliasedString("foo"), SysTime.init, SysTime.init);
}

@safe unittest
{
    import std.stdio : File;
    string newdir = deleteme ~ r".dir";
    string dir = newdir ~ r"/a/b/c";
    string file = dir ~ "/file";

    if (!exists(dir)) mkdirRecurse(dir);
    { auto f = File(file, "w"); }

    void testTimes(int hnsecValue)
    {
        foreach (path; [file, dir])  // test file and dir
        {
            SysTime atime = SysTime(DateTime(2010, 10, 4, 0, 0, 30), hnsecs(hnsecValue));
            SysTime mtime = SysTime(DateTime(2011, 10, 4, 0, 0, 30), hnsecs(hnsecValue));
            setTimes(path, atime, mtime);

            SysTime atime_res;
            SysTime mtime_res;
            getTimes(path, atime_res, mtime_res);
            assert(atime == atime_res);
            assert(mtime == mtime_res);
        }
    }

    testTimes(0);
    version (linux)
        testTimes(123_456_7);

    rmdirRecurse(newdir);
}

// https://issues.dlang.org/show_bug.cgi?id=23683
@safe unittest
{
    scope(exit) deleteme.remove;
    import std.stdio : File;
    auto f = File(deleteme, "wb");
    SysTime time = SysTime(DateTime(2018, 10, 4, 0, 0, 30));
    setTimes(deleteme, time, time);
}

/++
    Returns the time that the given file was last modified.

    Params:
        name = the name of the file to check
    Returns:
        A $(REF SysTime,std,datetime,systime).
    Throws:
        $(LREF FileException) if the given file does not exist.
+/
SysTime timeLastModified(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        SysTime dummy;
        SysTime ftm;

        getTimesWin(name, dummy, dummy, ftm);

        return ftm;
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        stat_t statbuf = void;

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(trustedStat(namez, statbuf) == 0, names, namez);

        return statTimeToStdTime!'m'(statbuf);
    }
}

/// ditto
SysTime timeLastModified(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return timeLastModified!(StringTypeOf!R)(name);
}

///
@safe unittest
{
    import std.datetime : abs, DateTime, hnsecs, SysTime;
    scope(exit) deleteme.remove;

    import std.datetime : Clock, seconds;
    auto currTime = Clock.currTime();
    enum leeway = 5.seconds;
    deleteme.write("bb");
    assert(abs(deleteme.timeLastModified - currTime) <= leeway);
}

@safe unittest
{
    static assert(__traits(compiles, timeLastModified(TestAliasedString("foo"))));
}

/++
    Returns the time that the given file was last modified. If the
    file does not exist, returns `returnIfMissing`.

    A frequent usage pattern occurs in build automation tools such as
    $(HTTP gnu.org/software/make, make) or $(HTTP
    en.wikipedia.org/wiki/Apache_Ant, ant). To check whether file $(D
    target) must be rebuilt from file `source` (i.e., `target` is
    older than `source` or does not exist), use the comparison
    below. The code throws a $(LREF FileException) if `source` does not
    exist (as it should). On the other hand, the `SysTime.min` default
    makes a non-existing `target` seem infinitely old so the test
    correctly prompts building it.

    Params:
        name = The name of the file to get the modification time for.
        returnIfMissing = The time to return if the given file does not exist.
    Returns:
        A $(REF SysTime,std,datetime,systime).

Example:
--------------------
if (source.timeLastModified >= target.timeLastModified(SysTime.min))
{
    // must (re)build
}
else
{
    // target is up-to-date
}
--------------------
+/
SysTime timeLastModified(R)(R name, SysTime returnIfMissing)
if (isSomeFiniteCharInputRange!R)
{
    version (Windows)
    {
        if (!exists(name))
            return returnIfMissing;

        SysTime dummy;
        SysTime ftm;

        getTimesWin(name, dummy, dummy, ftm);

        return ftm;
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        stat_t statbuf = void;

        return trustedStat(namez, statbuf) != 0 ?
               returnIfMissing :
               statTimeToStdTime!'m'(statbuf);
    }
}

///
@safe unittest
{
    import std.datetime : SysTime;

    assert("file.does.not.exist".timeLastModified(SysTime.min) == SysTime.min);

    auto source = deleteme ~ "source";
    auto target = deleteme ~ "target";
    scope(exit) source.remove, target.remove;

    source.write(".");
    assert(target.timeLastModified(SysTime.min) < source.timeLastModified);
    target.write(".");
    assert(target.timeLastModified(SysTime.min) >= source.timeLastModified);
}

version (StdDdoc)
{
    /++
     $(BLUE This function is POSIX-Only.)

     Returns the time that the given file was last modified.
     Params:
        statbuf = stat_t retrieved from file.
     +/
    SysTime timeLastModified()(auto ref stat_t statbuf) pure nothrow {assert(false);}
    /++
     $(BLUE This function is POSIX-Only.)

     Returns the time that the given file was last accessed.
     Params:
        statbuf = stat_t retrieved from file.
     +/
    SysTime timeLastAccessed()(auto ref stat_t statbuf) pure nothrow {assert(false);}
    /++
     $(BLUE This function is POSIX-Only.)

     Returns the time that the given file was last changed.
     Params:
        statbuf = stat_t retrieved from file.
     +/
    SysTime timeStatusChanged()(auto ref stat_t statbuf) pure nothrow {assert(false);}
}
else version (Posix)
{
    SysTime timeLastModified()(auto ref stat_t statbuf) pure nothrow
    {
        return statTimeToStdTime!'m'(statbuf);
    }
    SysTime timeLastAccessed()(auto ref stat_t statbuf) pure nothrow
    {
        return statTimeToStdTime!'a'(statbuf);
    }
    SysTime timeStatusChanged()(auto ref stat_t statbuf) pure nothrow
    {
        return statTimeToStdTime!'c'(statbuf);
    }

    @safe unittest
    {
        stat_t statbuf;
        // check that both lvalues and rvalues work
        timeLastAccessed(statbuf);
        cast(void) timeLastAccessed(stat_t.init);
    }
}

@safe unittest
{
    //std.process.executeShell("echo a > deleteme");
    if (exists(deleteme))
        remove(deleteme);

    write(deleteme, "a\n");

    scope(exit)
    {
        assert(exists(deleteme));
        remove(deleteme);
    }

    // assert(lastModified("deleteme") >
    //         lastModified("this file does not exist", SysTime.min));
    //assert(lastModified("deleteme") > lastModified(__FILE__));
}


// Tests sub-second precision of querying file times.
// Should pass on most modern systems running on modern filesystems.
// Exceptions:
// - FreeBSD, where one would need to first set the
//   vfs.timestamp_precision sysctl to a value greater than zero.
// - OS X, where the native filesystem (HFS+) stores filesystem
//   timestamps with 1-second precision.
//
// Note: on linux systems, although in theory a change to a file date
// can be tracked with precision of 4 msecs, this test waits 20 msecs
// to prevent possible problems relative to the CI services the dlang uses,
// as they may have the HZ setting that controls the software clock set to 100
// (instead of the more common 250).
// see https://man7.org/linux/man-pages/man7/time.7.html
//     https://stackoverflow.com/a/14393315,
//     https://issues.dlang.org/show_bug.cgi?id=21148
version (FreeBSD) {} else
version (DragonFlyBSD) {} else
version (OSX) {} else
@safe unittest
{
    import core.thread;

    if (exists(deleteme))
        remove(deleteme);

    SysTime lastTime;
    foreach (n; 0 .. 3)
    {
        write(deleteme, "a");
        auto time = timeLastModified(deleteme);
        remove(deleteme);
        assert(time != lastTime);
        lastTime = time;
        () @trusted { Thread.sleep(20.msecs); }();
    }
}


/**
 * Determine whether the given file (or directory) _exists.
 * Params:
 *    name = string or range of characters representing the file _name
 * Returns:
 *    true if the file _name specified as input _exists
 */
bool exists(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    return existsImpl(name.tempCString!FSChar());
}

/// ditto
bool exists(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return exists!(StringTypeOf!R)(name);
}

///
@safe unittest
{
    auto f = deleteme ~ "does.not.exist";
    assert(!f.exists);

    f.write("hello");
    assert(f.exists);

    f.remove;
    assert(!f.exists);
}

private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc
{
    version (Windows)
    {
        // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
        // fileio/base/getfileattributes.asp
        return GetFileAttributesW(namez) != 0xFFFFFFFF;
    }
    else version (Posix)
    {
        /*
            The reason why we use stat (and not access) here is
            the quirky behavior of access for SUID programs: if
            we used access, a file may not appear to "exist",
            despite that the program would be able to open it
            just fine. The behavior in question is described as
            follows in the access man page:

            > The check is done using the calling process's real
            > UID and GID, rather than the effective IDs as is
            > done when actually attempting an operation (e.g.,
            > open(2)) on the file. This allows set-user-ID
            > programs to easily determine the invoking user's
            > authority.

            While various operating systems provide eaccess or
            euidaccess functions, these are not part of POSIX -
            so it's safer to use stat instead.
        */

        stat_t statbuf = void;
        return lstat(namez, &statbuf) == 0;
    }
    else
        static assert(0);
}

///
@safe unittest
{
    assert(".".exists);
    assert(!"this file does not exist".exists);
    deleteme.write("a\n");
    scope(exit) deleteme.remove;
    assert(deleteme.exists);
}

// https://issues.dlang.org/show_bug.cgi?id=16573
@safe unittest
{
    enum S : string { foo = "foo" }
    assert(__traits(compiles, S.foo.exists));
}

/++
 Returns the attributes of the given file.

 Note that the file attributes on Windows and POSIX systems are
 completely different. On Windows, they're what is returned by
 $(HTTP msdn.microsoft.com/en-us/library/aa364944(v=vs.85).aspx,
 GetFileAttributes), whereas on POSIX systems, they're the
 `st_mode` value which is part of the $(D stat struct) gotten by
 calling the $(HTTP en.wikipedia.org/wiki/Stat_%28Unix%29, `stat`)
 function.

 On POSIX systems, if the given file is a symbolic link, then
 attributes are the attributes of the file pointed to by the symbolic
 link.

 Params:
    name = The file to get the attributes of.
 Returns:
    The attributes of the file as a `uint`.
 Throws: $(LREF FileException) on error.
  +/
uint getAttributes(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedGetFileAttributesW(scope const(FSChar)* namez) @trusted
        {
            return GetFileAttributesW(namez);
        }
        immutable result = trustedGetFileAttributesW(namez);

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(result != INVALID_FILE_ATTRIBUTES, names, namez);

        return result;
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        stat_t statbuf = void;

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(trustedStat(namez, statbuf) == 0, names, namez);

        return statbuf.st_mode;
    }
}

/// ditto
uint getAttributes(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return getAttributes!(StringTypeOf!R)(name);
}

/// getAttributes with a file
@safe unittest
{
    import std.exception : assertThrown;

    auto f = deleteme ~ "file";
    scope(exit) f.remove;

    assert(!f.exists);
    assertThrown!FileException(f.getAttributes);

    f.write(".");
    auto attributes = f.getAttributes;
    assert(!attributes.attrIsDir);
    assert(attributes.attrIsFile);
}

/// getAttributes with a directory
@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    scope(exit) dir.rmdir;

    assert(!dir.exists);
    assertThrown!FileException(dir.getAttributes);

    dir.mkdir;
    auto attributes = dir.getAttributes;
    assert(attributes.attrIsDir);
    assert(!attributes.attrIsFile);
}

@safe unittest
{
    static assert(__traits(compiles, getAttributes(TestAliasedString(null))));
}

/++
    If the given file is a symbolic link, then this returns the attributes of the
    symbolic link itself rather than file that it points to. If the given file
    is $(I not) a symbolic link, then this function returns the same result
    as getAttributes.

    On Windows, getLinkAttributes is identical to getAttributes. It exists on
    Windows so that you don't have to special-case code for Windows when dealing
    with symbolic links.

    Params:
        name = The file to get the symbolic link attributes of.

    Returns:
        the attributes

    Throws:
        $(LREF FileException) on error.
 +/
uint getLinkAttributes(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        return getAttributes(name);
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedLstat(const(FSChar)* namez, ref stat_t buf) @trusted
        {
            return lstat(namez, &buf);
        }
        stat_t lstatbuf = void;
        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(trustedLstat(namez, lstatbuf) == 0, names, namez);
        return lstatbuf.st_mode;
    }
}

/// ditto
uint getLinkAttributes(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return getLinkAttributes!(StringTypeOf!R)(name);
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto source = deleteme ~ "source";
    auto target = deleteme ~ "target";

    assert(!source.exists);
    assertThrown!FileException(source.getLinkAttributes);

    // symlinking isn't available on Windows
    version (Posix)
    {
        scope(exit) source.remove, target.remove;

        target.write("target");
        target.symlink(source);
        assert(source.readText == "target");
        assert(source.isSymlink);
        assert(source.getLinkAttributes.attrIsSymlink);
    }
}

/// if the file is no symlink, getLinkAttributes behaves like getAttributes
@safe unittest
{
    import std.exception : assertThrown;

    auto f = deleteme ~ "file";
    scope(exit) f.remove;

    assert(!f.exists);
    assertThrown!FileException(f.getLinkAttributes);

    f.write(".");
    auto attributes = f.getLinkAttributes;
    assert(!attributes.attrIsDir);
    assert(attributes.attrIsFile);
}

/// if the file is no symlink, getLinkAttributes behaves like getAttributes
@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    scope(exit) dir.rmdir;

    assert(!dir.exists);
    assertThrown!FileException(dir.getLinkAttributes);

    dir.mkdir;
    auto attributes = dir.getLinkAttributes;
    assert(attributes.attrIsDir);
    assert(!attributes.attrIsFile);
}

@safe unittest
{
    static assert(__traits(compiles, getLinkAttributes(TestAliasedString(null))));
}

/++
    Set the _attributes of the given file.

    For example, a programmatic equivalent of Unix's `chmod +x name`
    to make a file executable is
    `name.setAttributes(name.getAttributes | octal!700)`.

    Params:
        name = the file _name
        attributes = the _attributes to set the file to

    Throws:
        $(LREF FileException) if the given file does not exist.
 +/
void setAttributes(R)(R name, uint attributes)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedSetFileAttributesW(scope const(FSChar)* namez, uint dwFileAttributes) @trusted
        {
            return SetFileAttributesW(namez, dwFileAttributes);
        }
        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(trustedSetFileAttributesW(namez, attributes), names, namez);
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedChmod(scope const(FSChar)* namez, mode_t mode) @trusted
        {
            return chmod(namez, mode);
        }
        assert(attributes <= mode_t.max);
        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias names = name;
        else
            string names = null;
        cenforce(!trustedChmod(namez, cast(mode_t) attributes), names, namez);
    }
}

/// ditto
void setAttributes(R)(auto ref R name, uint attributes)
if (isConvertibleToString!R)
{
    return setAttributes!(StringTypeOf!R)(name, attributes);
}

@safe unittest
{
    static assert(__traits(compiles, setAttributes(TestAliasedString(null), 0)));
}

/// setAttributes with a file
@safe unittest
{
    import std.exception : assertThrown;
    import std.conv : octal;

    auto f = deleteme ~ "file";
    version (Posix)
    {
        scope(exit) f.remove;

        assert(!f.exists);
        assertThrown!FileException(f.setAttributes(octal!777));

        f.write(".");
        auto attributes = f.getAttributes;
        assert(!attributes.attrIsDir);
        assert(attributes.attrIsFile);

        f.setAttributes(octal!777);
        attributes = f.getAttributes;

        assert((attributes & 1023) == octal!777);
    }
}

/// setAttributes with a directory
@safe unittest
{
    import std.exception : assertThrown;
    import std.conv : octal;

    auto dir = deleteme ~ "dir";
    version (Posix)
    {
        scope(exit) dir.rmdir;

        assert(!dir.exists);
        assertThrown!FileException(dir.setAttributes(octal!777));

        dir.mkdir;
        auto attributes = dir.getAttributes;
        assert(attributes.attrIsDir);
        assert(!attributes.attrIsFile);

        dir.setAttributes(octal!777);
        attributes = dir.getAttributes;

        assert((attributes & 1023) == octal!777);
    }
}

/++
    Returns whether the given file is a directory.

    Params:
        name = The path to the file.

    Returns:
        true if name specifies a directory

    Throws:
        $(LREF FileException) if the given file does not exist.
  +/
@property bool isDir(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
    {
        return (getAttributes(name) & FILE_ATTRIBUTE_DIRECTORY) != 0;
    }
    else version (Posix)
    {
        return (getAttributes(name) & S_IFMT) == S_IFDIR;
    }
}

/// ditto
@property bool isDir(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return name.isDir!(StringTypeOf!R);
}

///

@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    auto f = deleteme ~ "f";
    scope(exit) dir.rmdir, f.remove;

    assert(!dir.exists);
    assertThrown!FileException(dir.isDir);

    dir.mkdir;
    assert(dir.isDir);

    f.write(".");
    assert(!f.isDir);
}

@safe unittest
{
    static assert(__traits(compiles, TestAliasedString(null).isDir));
}

@safe unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
            assert("C:\\Program Files\\".isDir);

        if ("C:\\Windows\\system.ini".exists)
            assert(!"C:\\Windows\\system.ini".isDir);
    }
    else version (Posix)
    {
        if (system_directory.exists)
            assert(system_directory.isDir);

        if (system_file.exists)
            assert(!system_file.isDir);
    }
}

@safe unittest
{
    version (Windows)
        enum dir = "C:\\Program Files\\";
    else version (Posix)
        enum dir = system_directory;

    if (dir.exists)
    {
        DirEntry de = DirEntry(dir);
        assert(de.isDir);
        assert(DirEntry(dir).isDir);
    }
}

/++
    Returns whether the given file _attributes are for a directory.

    Params:
        attributes = The file _attributes.

    Returns:
        true if attributes specifies a directory
+/
bool attrIsDir(uint attributes) @safe pure nothrow @nogc
{
    version (Windows)
    {
        return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
    }
    else version (Posix)
    {
        return (attributes & S_IFMT) == S_IFDIR;
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    auto f = deleteme ~ "f";
    scope(exit) dir.rmdir, f.remove;

    assert(!dir.exists);
    assertThrown!FileException(dir.getAttributes.attrIsDir);

    dir.mkdir;
    assert(dir.isDir);
    assert(dir.getAttributes.attrIsDir);

    f.write(".");
    assert(!f.isDir);
    assert(!f.getAttributes.attrIsDir);
}

@safe unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
        {
            assert(attrIsDir(getAttributes("C:\\Program Files\\")));
            assert(attrIsDir(getLinkAttributes("C:\\Program Files\\")));
        }

        if ("C:\\Windows\\system.ini".exists)
        {
            assert(!attrIsDir(getAttributes("C:\\Windows\\system.ini")));
            assert(!attrIsDir(getLinkAttributes("C:\\Windows\\system.ini")));
        }
    }
    else version (Posix)
    {
        if (system_directory.exists)
        {
            assert(attrIsDir(getAttributes(system_directory)));
            assert(attrIsDir(getLinkAttributes(system_directory)));
        }

        if (system_file.exists)
        {
            assert(!attrIsDir(getAttributes(system_file)));
            assert(!attrIsDir(getLinkAttributes(system_file)));
        }
    }
}


/++
    Returns whether the given file (or directory) is a file.

    On Windows, if a file is not a directory, then it's a file. So,
    either `isFile` or `isDir` will return true for any given file.

    On POSIX systems, if `isFile` is `true`, that indicates that the file
    is a regular file (e.g. not a block not device). So, on POSIX systems, it's
    possible for both `isFile` and `isDir` to be `false` for a
    particular file (in which case, it's a special file). You can use
    `getAttributes` to get the attributes to figure out what type of special
    it is, or you can use `DirEntry` to get at its `statBuf`, which is the
    result from `stat`. In either case, see the man page for `stat` for
    more information.

    Params:
        name = The path to the file.

    Returns:
        true if name specifies a file

    Throws:
        $(LREF FileException) if the given file does not exist.
+/
@property bool isFile(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
        return !name.isDir;
    else version (Posix)
        return (getAttributes(name) & S_IFMT) == S_IFREG;
}

/// ditto
@property bool isFile(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return isFile!(StringTypeOf!R)(name);
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    auto f = deleteme ~ "f";
    scope(exit) dir.rmdir, f.remove;

    dir.mkdir;
    assert(!dir.isFile);

    assert(!f.exists);
    assertThrown!FileException(f.isFile);

    f.write(".");
    assert(f.isFile);
}

// https://issues.dlang.org/show_bug.cgi?id=15658
@safe unittest
{
    DirEntry e = DirEntry(".");
    static assert(is(typeof(isFile(e))));
}

@safe unittest
{
    static assert(__traits(compiles, TestAliasedString(null).isFile));
}

@safe unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
            assert(!"C:\\Program Files\\".isFile);

        if ("C:\\Windows\\system.ini".exists)
            assert("C:\\Windows\\system.ini".isFile);
    }
    else version (Posix)
    {
        if (system_directory.exists)
            assert(!system_directory.isFile);

        if (system_file.exists)
            assert(system_file.isFile);
    }
}


/++
    Returns whether the given file _attributes are for a file.

    On Windows, if a file is not a directory, it's a file. So, either
    `attrIsFile` or `attrIsDir` will return `true` for the
    _attributes of any given file.

    On POSIX systems, if `attrIsFile` is `true`, that indicates that the
    file is a regular file (e.g. not a block not device). So, on POSIX systems,
    it's possible for both `attrIsFile` and `attrIsDir` to be `false`
    for a particular file (in which case, it's a special file). If a file is a
    special file, you can use the _attributes to check what type of special file
    it is (see the man page for `stat` for more information).

    Params:
        attributes = The file _attributes.

    Returns:
        true if the given file _attributes are for a file

Example:
--------------------
assert(attrIsFile(getAttributes("/etc/fonts/fonts.conf")));
assert(attrIsFile(getLinkAttributes("/etc/fonts/fonts.conf")));
--------------------
  +/
bool attrIsFile(uint attributes) @safe pure nothrow @nogc
{
    version (Windows)
    {
        return (attributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
    }
    else version (Posix)
    {
        return (attributes & S_IFMT) == S_IFREG;
    }
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto dir = deleteme ~ "dir";
    auto f = deleteme ~ "f";
    scope(exit) dir.rmdir, f.remove;

    dir.mkdir;
    assert(!dir.isFile);
    assert(!dir.getAttributes.attrIsFile);

    assert(!f.exists);
    assertThrown!FileException(f.getAttributes.attrIsFile);

    f.write(".");
    assert(f.isFile);
    assert(f.getAttributes.attrIsFile);
}

@safe unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
        {
            assert(!attrIsFile(getAttributes("C:\\Program Files\\")));
            assert(!attrIsFile(getLinkAttributes("C:\\Program Files\\")));
        }

        if ("C:\\Windows\\system.ini".exists)
        {
            assert(attrIsFile(getAttributes("C:\\Windows\\system.ini")));
            assert(attrIsFile(getLinkAttributes("C:\\Windows\\system.ini")));
        }
    }
    else version (Posix)
    {
        if (system_directory.exists)
        {
            assert(!attrIsFile(getAttributes(system_directory)));
            assert(!attrIsFile(getLinkAttributes(system_directory)));
        }

        if (system_file.exists)
        {
            assert(attrIsFile(getAttributes(system_file)));
            assert(attrIsFile(getLinkAttributes(system_file)));
        }
    }
}


/++
    Returns whether the given file is a symbolic link.

    On Windows, returns `true` when the file is either a symbolic link or a
    junction point.

    Params:
        name = The path to the file.

    Returns:
        true if name is a symbolic link

    Throws:
        $(LREF FileException) if the given file does not exist.
  +/
@property bool isSymlink(R)(R name)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    version (Windows)
        return (getAttributes(name) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
    else version (Posix)
        return (getLinkAttributes(name) & S_IFMT) == S_IFLNK;
}

/// ditto
@property bool isSymlink(R)(auto ref R name)
if (isConvertibleToString!R)
{
    return name.isSymlink!(StringTypeOf!R);
}

@safe unittest
{
    static assert(__traits(compiles, TestAliasedString(null).isSymlink));
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto source = deleteme ~ "source";
    auto target = deleteme ~ "target";

    assert(!source.exists);
    assertThrown!FileException(source.isSymlink);

    // symlinking isn't available on Windows
    version (Posix)
    {
        scope(exit) source.remove, target.remove;

        target.write("target");
        target.symlink(source);
        assert(source.readText == "target");
        assert(source.isSymlink);
        assert(source.getLinkAttributes.attrIsSymlink);
    }
}

@system unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
            assert(!"C:\\Program Files\\".isSymlink);

        if ("C:\\Users\\".exists && "C:\\Documents and Settings\\".exists)
            assert("C:\\Documents and Settings\\".isSymlink);

        enum fakeSymFile = "C:\\Windows\\system.ini";
        if (fakeSymFile.exists)
        {
            assert(!fakeSymFile.isSymlink);

            assert(!fakeSymFile.isSymlink);
            assert(!attrIsSymlink(getAttributes(fakeSymFile)));
            assert(!attrIsSymlink(getLinkAttributes(fakeSymFile)));

            assert(attrIsFile(getAttributes(fakeSymFile)));
            assert(attrIsFile(getLinkAttributes(fakeSymFile)));
            assert(!attrIsDir(getAttributes(fakeSymFile)));
            assert(!attrIsDir(getLinkAttributes(fakeSymFile)));

            assert(getAttributes(fakeSymFile) == getLinkAttributes(fakeSymFile));
        }
    }
    else version (Posix)
    {
        if (system_directory.exists)
        {
            assert(!system_directory.isSymlink);

            immutable symfile = deleteme ~ "_slink\0";
            scope(exit) if (symfile.exists) symfile.remove();

            core.sys.posix.unistd.symlink(system_directory, symfile.ptr);

            assert(symfile.isSymlink);
            assert(!attrIsSymlink(getAttributes(symfile)));
            assert(attrIsSymlink(getLinkAttributes(symfile)));

            assert(attrIsDir(getAttributes(symfile)));
            assert(!attrIsDir(getLinkAttributes(symfile)));

            assert(!attrIsFile(getAttributes(symfile)));
            assert(!attrIsFile(getLinkAttributes(symfile)));
        }

        if (system_file.exists)
        {
            assert(!system_file.isSymlink);

            immutable symfile = deleteme ~ "_slink\0";
            scope(exit) if (symfile.exists) symfile.remove();

            core.sys.posix.unistd.symlink(system_file, symfile.ptr);

            assert(symfile.isSymlink);
            assert(!attrIsSymlink(getAttributes(symfile)));
            assert(attrIsSymlink(getLinkAttributes(symfile)));

            assert(!attrIsDir(getAttributes(symfile)));
            assert(!attrIsDir(getLinkAttributes(symfile)));

            assert(attrIsFile(getAttributes(symfile)));
            assert(!attrIsFile(getLinkAttributes(symfile)));
        }
    }

    static assert(__traits(compiles, () @safe { return "dummy".isSymlink; }));
}


/++
    Returns whether the given file attributes are for a symbolic link.

    On Windows, return `true` when the file is either a symbolic link or a
    junction point.

    Params:
        attributes = The file attributes.

    Returns:
        true if attributes are for a symbolic link

Example:
--------------------
core.sys.posix.unistd.symlink("/etc/fonts/fonts.conf", "/tmp/alink");

assert(!getAttributes("/tmp/alink").isSymlink);
assert(getLinkAttributes("/tmp/alink").isSymlink);
--------------------
  +/
bool attrIsSymlink(uint attributes) @safe pure nothrow @nogc
{
    version (Windows)
        return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
    else version (Posix)
        return (attributes & S_IFMT) == S_IFLNK;
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto source = deleteme ~ "source";
    auto target = deleteme ~ "target";

    assert(!source.exists);
    assertThrown!FileException(source.getLinkAttributes.attrIsSymlink);

    // symlinking isn't available on Windows
    version (Posix)
    {
        scope(exit) source.remove, target.remove;

        target.write("target");
        target.symlink(source);
        assert(source.readText == "target");
        assert(source.isSymlink);
        assert(source.getLinkAttributes.attrIsSymlink);
    }
}

/**
Change directory to `pathname`. Equivalent to `cd` on
Windows and POSIX.

Params:
    pathname = the directory to step into

Throws: $(LREF FileException) on error.
 */
void chdir(R)(R pathname)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    // Place outside of @trusted block
    auto pathz = pathname.tempCString!FSChar();

    version (Windows)
    {
        static auto trustedChdir(scope const(FSChar)* pathz) @trusted
        {
            return SetCurrentDirectoryW(pathz);
        }
    }
    else version (Posix)
    {
        static auto trustedChdir(scope const(FSChar)* pathz) @trusted
        {
            return core.sys.posix.unistd.chdir(pathz) == 0;
        }
    }
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        alias pathStr = pathname;
    else
        string pathStr = null;
    cenforce(trustedChdir(pathz), pathStr, pathz);
}

/// ditto
void chdir(R)(auto ref R pathname)
if (isConvertibleToString!R)
{
    return chdir!(StringTypeOf!R)(pathname);
}

///
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.sorting : sort;
    import std.array : array;
    import std.path : buildPath;

    auto cwd = getcwd;
    auto dir = deleteme ~ "dir";
    dir.mkdir;
    scope(exit) cwd.chdir, dir.rmdirRecurse;

    dir.buildPath("a").write(".");
    dir.chdir; // step into dir
    "b".write(".");
    assert(dirEntries(".", SpanMode.shallow).array.sort.equal(
        [".".buildPath("a"), ".".buildPath("b")]
    ));
}

@safe unittest
{
    static assert(__traits(compiles, chdir(TestAliasedString(null))));
}

/**
Make a new directory `pathname`.

Params:
    pathname = the path of the directory to make

Throws:
    $(LREF FileException) on POSIX or $(LREF WindowsException) on Windows
    if an error occured.
 */
void mkdir(R)(R pathname)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    // Place outside of @trusted block
    const pathz = pathname.tempCString!FSChar();

    version (Windows)
    {
        static auto trustedCreateDirectoryW(scope const(FSChar)* pathz) @trusted
        {
            return CreateDirectoryW(pathz, null);
        }
        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias pathStr = pathname;
        else
            string pathStr = null;
        wenforce(trustedCreateDirectoryW(pathz), pathStr, pathz);
    }
    else version (Posix)
    {
        import std.conv : octal;

        static auto trustedMkdir(scope const(FSChar)* pathz, mode_t mode) @trusted
        {
            return core.sys.posix.sys.stat.mkdir(pathz, mode);
        }
        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias pathStr = pathname;
        else
            string pathStr = null;
        cenforce(trustedMkdir(pathz, octal!777) == 0, pathStr, pathz);
    }
}

/// ditto
void mkdir(R)(auto ref R pathname)
if (isConvertibleToString!R)
{
    return mkdir!(StringTypeOf!R)(pathname);
}

@safe unittest
{
    import std.file : mkdir;
    static assert(__traits(compiles, mkdir(TestAliasedString(null))));
}

///
@safe unittest
{
    import std.file : mkdir;

    auto dir = deleteme ~ "dir";
    scope(exit) dir.rmdir;

    dir.mkdir;
    assert(dir.exists);
}

///
@safe unittest
{
    import std.exception : assertThrown;
    assertThrown("a/b/c/d/e".mkdir);
}

// Same as mkdir but ignores "already exists" errors.
// Returns: "true" if the directory was created,
//   "false" if it already existed.
private bool ensureDirExists()(scope const(char)[] pathname)
{
    import std.exception : enforce;
    const pathz = pathname.tempCString!FSChar();

    version (Windows)
    {
        if (() @trusted { return CreateDirectoryW(pathz, null); }())
            return true;
        cenforce(GetLastError() == ERROR_ALREADY_EXISTS, pathname.idup);
    }
    else version (Posix)
    {
        import std.conv : octal;

        if (() @trusted { return core.sys.posix.sys.stat.mkdir(pathz, octal!777); }() == 0)
            return true;
        cenforce(errno == EEXIST || errno == EISDIR, pathname);
    }
    enforce(pathname.isDir, new FileException(pathname.idup));
    return false;
}

/**
Make directory and all parent directories as needed.

Does nothing if the directory specified by
`pathname` already exists.

Params:
    pathname = the full path of the directory to create

Throws: $(LREF FileException) on error.
 */
void mkdirRecurse(scope const(char)[] pathname) @safe
{
    import std.path : dirName, baseName;

    const left = dirName(pathname);
    if (left.length != pathname.length && !exists(left))
    {
        mkdirRecurse(left);
    }
    if (!baseName(pathname).empty)
    {
        ensureDirExists(pathname);
    }
}

///
@safe unittest
{
    import std.path : buildPath;

    auto dir = deleteme ~ "dir";
    scope(exit) dir.rmdirRecurse;

    dir.mkdir;
    assert(dir.exists);
    dir.mkdirRecurse; // does nothing

    // creates all parent directories as needed
    auto nested = dir.buildPath("a", "b", "c");
    nested.mkdirRecurse;
    assert(nested.exists);
}

///
@safe unittest
{
    import std.exception : assertThrown;

    scope(exit) deleteme.remove;
    deleteme.write("a");

    // cannot make directory as it's already a file
    assertThrown!FileException(deleteme.mkdirRecurse);
}

@safe unittest
{
    import std.exception : assertThrown;
    {
        import std.path : buildPath, buildNormalizedPath;

        immutable basepath = deleteme ~ "_dir";
        scope(exit) () @trusted { rmdirRecurse(basepath); }();

        auto path = buildPath(basepath, "a", "..", "b");
        mkdirRecurse(path);
        path = path.buildNormalizedPath;
        assert(path.isDir);

        path = buildPath(basepath, "c");
        write(path, "");
        assertThrown!FileException(mkdirRecurse(path));

        path = buildPath(basepath, "d");
        mkdirRecurse(path);
        mkdirRecurse(path); // should not throw
    }

    version (Windows)
    {
        assertThrown!FileException(mkdirRecurse(`1:\foobar`));
    }

    // https://issues.dlang.org/show_bug.cgi?id=3570
    {
        immutable basepath = deleteme ~ "_dir";
        version (Windows)
        {
            immutable path = basepath ~ "\\fake\\here\\";
        }
        else version (Posix)
        {
            immutable path = basepath ~ `/fake/here/`;
        }

        mkdirRecurse(path);
        assert(basepath.exists && basepath.isDir);
        scope(exit) () @trusted { rmdirRecurse(basepath); }();
        assert(path.exists && path.isDir);
    }
}

/****************************************************
Remove directory `pathname`.

Params:
    pathname = Range or string specifying the directory name

Throws: $(LREF FileException) on error.
 */
void rmdir(R)(R pathname)
if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)
{
    // Place outside of @trusted block
    auto pathz = pathname.tempCString!FSChar();

    version (Windows)
    {
        static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
        {
            return RemoveDirectoryW(pathz);
        }
    }
    else version (Posix)
    {
        static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
        {
            return core.sys.posix.unistd.rmdir(pathz) == 0;
        }
    }
    static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
        alias pathStr = pathname;
    else
        string pathStr = null;
    cenforce(trustedRmdir(pathz), pathStr, pathz);
}

/// ditto
void rmdir(R)(auto ref R pathname)
if (isConvertibleToString!R)
{
    rmdir!(StringTypeOf!R)(pathname);
}

@safe unittest
{
    static assert(__traits(compiles, rmdir(TestAliasedString(null))));
}

///
@safe unittest
{
    auto dir = deleteme ~ "dir";

    dir.mkdir;
    assert(dir.exists);
    dir.rmdir;
    assert(!dir.exists);
}

/++
    $(BLUE This function is POSIX-Only.)

    Creates a symbolic _link (_symlink).

    Params:
        original = The file that is being linked. This is the target path that's
            stored in the _symlink. A relative path is relative to the created
            _symlink.
        link = The _symlink to create. A relative path is relative to the
            current working directory.

    Throws:
        $(LREF FileException) on error (which includes if the _symlink already
        exists).
  +/
version (StdDdoc) void symlink(RO, RL)(RO original, RL link)
if ((isSomeFiniteCharInputRange!RO || isConvertibleToString!RO) &&
    (isSomeFiniteCharInputRange!RL || isConvertibleToString!RL));
else version (Posix) void symlink(RO, RL)(RO original, RL link)
if ((isSomeFiniteCharInputRange!RO || isConvertibleToString!RO) &&
    (isSomeFiniteCharInputRange!RL || isConvertibleToString!RL))
{
    static if (isConvertibleToString!RO || isConvertibleToString!RL)
    {
        import std.meta : staticMap;
        alias Types = staticMap!(convertToString, RO, RL);
        symlink!Types(original, link);
    }
    else
    {
        import std.conv : text;
        auto oz = original.tempCString();
        auto lz = link.tempCString();
        alias posixSymlink = core.sys.posix.unistd.symlink;
        immutable int result = () @trusted { return posixSymlink(oz, lz); } ();
        cenforce(result == 0, text(link));
    }
}

version (Posix) @safe unittest
{
    if (system_directory.exists)
    {
        immutable symfile = deleteme ~ "_slink\0";
        scope(exit) if (symfile.exists) symfile.remove();

        symlink(system_directory, symfile);

        assert(symfile.exists);
        assert(symfile.isSymlink);
        assert(!attrIsSymlink(getAttributes(symfile)));
        assert(attrIsSymlink(getLinkAttributes(symfile)));

        assert(attrIsDir(getAttributes(symfile)));
        assert(!attrIsDir(getLinkAttributes(symfile)));

        assert(!attrIsFile(getAttributes(symfile)));
        assert(!attrIsFile(getLinkAttributes(symfile)));
    }

    if (system_file.exists)
    {
        assert(!system_file.isSymlink);

        immutable symfile = deleteme ~ "_slink\0";
        scope(exit) if (symfile.exists) symfile.remove();

        symlink(system_file, symfile);

        assert(symfile.exists);
        assert(symfile.isSymlink);
        assert(!attrIsSymlink(getAttributes(symfile)));
        assert(attrIsSymlink(getLinkAttributes(symfile)));

        assert(!attrIsDir(getAttributes(symfile)));
        assert(!attrIsDir(getLinkAttributes(symfile)));

        assert(attrIsFile(getAttributes(symfile)));
        assert(!attrIsFile(getLinkAttributes(symfile)));
    }
}

version (Posix) @safe unittest
{
    static assert(__traits(compiles,
        symlink(TestAliasedString(null), TestAliasedString(null))));
}


/++
    $(BLUE This function is POSIX-Only.)

    Returns the path to the file pointed to by a symlink. Note that the
    path could be either relative or absolute depending on the symlink.
    If the path is relative, it's relative to the symlink, not the current
    working directory.

    Throws:
        $(LREF FileException) on error.
  +/
version (StdDdoc) string readLink(R)(R link)
if (isSomeFiniteCharInputRange!R || isConvertibleToString!R);
else version (Posix) string readLink(R)(R link)
if (isSomeFiniteCharInputRange!R || isConvertibleToString!R)
{
    static if (isConvertibleToString!R)
    {
        return readLink!(convertToString!R)(link);
    }
    else
    {
        import std.conv : to;
        import std.exception : assumeUnique;
        alias posixReadlink = core.sys.posix.unistd.readlink;
        enum bufferLen = 2048;
        enum maxCodeUnits = 6;
        char[bufferLen] buffer;
        const linkz = link.tempCString();
        auto size = () @trusted {
            return posixReadlink(linkz, buffer.ptr, buffer.length);
        } ();
        cenforce(size != -1, to!string(link));

        if (size <= bufferLen - maxCodeUnits)
            return to!string(buffer[0 .. size]);

        auto dynamicBuffer = new char[](bufferLen * 3 / 2);

        foreach (i; 0 .. 10)
        {
            size = () @trusted {
                return posixReadlink(linkz, dynamicBuffer.ptr,
                    dynamicBuffer.length);
            } ();
            cenforce(size != -1, to!string(link));

            if (size <= dynamicBuffer.length - maxCodeUnits)
            {
                dynamicBuffer.length = size;
                return () @trusted {
                    return assumeUnique(dynamicBuffer);
                } ();
            }

            dynamicBuffer.length = dynamicBuffer.length * 3 / 2;
        }

        throw new FileException(to!string(link), "Path is too long to read.");
    }
}

version (Posix) @safe unittest
{
    import std.exception : assertThrown;
    import std.string;

    foreach (file; [system_directory, system_file])
    {
        if (file.exists)
        {
            immutable symfile = deleteme ~ "_slink\0";
            scope(exit) if (symfile.exists) symfile.remove();

            symlink(file, symfile);
            assert(readLink(symfile) == file, format("Failed file: %s", file));
        }
    }

    assertThrown!FileException(readLink("/doesnotexist"));
}

version (Posix) @safe unittest
{
    static assert(__traits(compiles, readLink(TestAliasedString("foo"))));
}

version (Posix) @system unittest // input range of dchars
{
    mkdirRecurse(deleteme);
    scope(exit) if (deleteme.exists) rmdirRecurse(deleteme);
    write(deleteme ~ "/f", "");
    import std.range.interfaces : InputRange, inputRangeObject;
    import std.utf : byChar;
    immutable string link = deleteme ~ "/l";
    symlink("f", link);
    InputRange!(ElementType!string) linkr = inputRangeObject(link);
    alias R = typeof(linkr);
    static assert(isInputRange!R);
    static assert(!isForwardRange!R);
    assert(readLink(linkr) == "f");
}


/****************************************************
 * Get the current working directory.
 * Throws: $(LREF FileException) on error.
 */
version (Windows) string getcwd() @trusted
{
    import std.conv : to;
    import std.checkedint : checked;
    /* GetCurrentDirectory's return value:
        1. function succeeds: the number of characters that are written to
    the buffer, not including the terminating null character.
        2. function fails: zero
        3. the buffer (lpBuffer) is not large enough: the required size of
    the buffer, in characters, including the null-terminating character.
    */
    version (StdUnittest)
        enum BUF_SIZE = 10;     // trigger reallocation code
    else
        enum BUF_SIZE = 4096;   // enough for most common case
    wchar[BUF_SIZE] buffW = void;
    immutable n = cenforce(GetCurrentDirectoryW(to!DWORD(buffW.length), buffW.ptr),
            "getcwd");
    // we can do it because toUTFX always produces a fresh string
    if (n < buffW.length)
    {
        return buffW[0 .. n].to!string;
    }
    else //staticBuff isn't enough
    {
        auto cn = checked(n);
        auto ptr = cast(wchar*) malloc((cn * wchar.sizeof).get);
        scope(exit) free(ptr);
        immutable n2 = GetCurrentDirectoryW(cn.get, ptr);
        cenforce(n2 && n2 < cn, "getcwd");
        return ptr[0 .. n2].to!string;
    }
}
else version (Solaris) string getcwd() @trusted
{
    /* BUF_SIZE >= PATH_MAX */
    enum BUF_SIZE = 4096;
    /* The user should be able to specify any size buffer > 0 */
    auto p = cenforce(core.sys.posix.unistd.getcwd(null, BUF_SIZE),
            "cannot get cwd");
    scope(exit) core.stdc.stdlib.free(p);
    return p[0 .. core.stdc.string.strlen(p)].idup;
}
else version (Posix) string getcwd() @trusted
{
    auto p = cenforce(core.sys.posix.unistd.getcwd(null, 0),
            "cannot get cwd");
    scope(exit) core.stdc.stdlib.free(p);
    return p[0 .. core.stdc.string.strlen(p)].idup;
}

///
@safe unittest
{
    auto s = getcwd();
    assert(s.length);
}

/**
 * Returns the full path of the current executable.
 *
 * Returns:
 *     The path of the executable as a `string`.
 *
 * Throws:
 * $(REF1 Exception, object)
 */
@trusted string thisExePath()
{
    version (Darwin)
    {
        import core.sys.darwin.mach.dyld : _NSGetExecutablePath;
        import core.sys.posix.stdlib : realpath;
        import std.conv : to;
        import std.exception : errnoEnforce;

        uint size;

        _NSGetExecutablePath(null, &size); // get the length of the path
        auto buffer = new char[size];
        _NSGetExecutablePath(buffer.ptr, &size);

        auto absolutePath = realpath(buffer.ptr, null); // let the function allocate

        scope (exit)
        {
            if (absolutePath)
                free(absolutePath);
        }

        errnoEnforce(absolutePath);
        return to!(string)(absolutePath);
    }
    else version (linux)
    {
        return readLink("/proc/self/exe");
    }
    else version (Windows)
    {
        import std.conv : to;
        import std.exception : enforce;

        wchar[MAX_PATH] buf;
        wchar[] buffer = buf[];

        while (true)
        {
            auto len = GetModuleFileNameW(null, buffer.ptr, cast(DWORD) buffer.length);
            wenforce(len);
            if (len != buffer.length)
                return to!(string)(buffer[0 .. len]);
            buffer.length *= 2;
        }
    }
    else version (DragonFlyBSD)
    {
        import core.sys.dragonflybsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME;
        import std.exception : errnoEnforce, assumeUnique;

        int[4] mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1];
        size_t len;

        auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path
        errnoEnforce(result == 0);

        auto buffer = new char[len - 1];
        result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);
        errnoEnforce(result == 0);

        return buffer.assumeUnique;
    }
    else version (FreeBSD)
    {
        import core.sys.freebsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME;
        import std.exception : errnoEnforce, assumeUnique;

        int[4] mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1];
        size_t len;

        auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path
        errnoEnforce(result == 0);

        auto buffer = new char[len - 1];
        result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);
        errnoEnforce(result == 0);

        return buffer.assumeUnique;
    }
    else version (NetBSD)
    {
        import core.sys.netbsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC_ARGS, KERN_PROC_PATHNAME;
        import std.exception : errnoEnforce, assumeUnique;

        int[4] mib = [CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME];
        size_t len;

        auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0); // get the length of the path
        errnoEnforce(result == 0);

        auto buffer = new char[len - 1];
        result = sysctl(mib.ptr, mib.length, buffer.ptr, &len, null, 0);
        errnoEnforce(result == 0);

        return buffer.assumeUnique;
    }
    else version (OpenBSD)
    {
        import core.sys.openbsd.sys.sysctl : sysctl, CTL_KERN, KERN_PROC_ARGS, KERN_PROC_ARGV;
        import core.sys.posix.unistd : getpid;
        import std.conv : to;
        import std.exception : enforce, errnoEnforce;
        import std.process : searchPathFor;

        int[4] mib = [CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV];
        size_t len;

        auto result = sysctl(mib.ptr, mib.length, null, &len, null, 0);
        errnoEnforce(result == 0);

        auto argv = new char*[len - 1];
        result = sysctl(mib.ptr, mib.length, argv.ptr, &len, null, 0);
        errnoEnforce(result == 0);

        auto argv0 = argv[0];
        if (*argv0 == '/' || *argv0 == '.')
        {
            import core.sys.posix.stdlib : realpath;
            auto absolutePath = realpath(argv0, null);
            scope (exit)
            {
                if (absolutePath)
                    free(absolutePath);
            }
            errnoEnforce(absolutePath);
            return to!(string)(absolutePath);
        }
        else
        {
            auto absolutePath = searchPathFor(to!string(argv0));
            errnoEnforce(absolutePath);
            return absolutePath;
        }
    }
    else version (Solaris)
    {
        import core.sys.posix.unistd : getpid;
        import std.string : format;

        // Only Solaris 10 and later
        return readLink(format("/proc/%d/path/a.out", getpid()));
    }
    else version (Hurd)
    {
        return readLink("/proc/self/exe");
    }
    else
        static assert(0, "thisExePath is not supported on this platform");
}

///
@safe unittest
{
    import std.path : isAbsolute;
    auto path = thisExePath();

    assert(path.exists);
    assert(path.isAbsolute);
    assert(path.isFile);
}

version (StdDdoc)
{
    /++
        Info on a file, similar to what you'd get from stat on a POSIX system.
      +/
    struct DirEntry
    {
        @safe:
        /++
            Constructs a `DirEntry` for the given file (or directory).

            Params:
                path = The file (or directory) to get a DirEntry for.

            Throws:
                $(LREF FileException) if the file does not exist.
        +/
        this(return scope string path);

        version (Windows)
        {
            private this(string path, in WIN32_FIND_DATAW *fd);
        }
        else version (Posix)
        {
            private this(string path, core.sys.posix.dirent.dirent* fd);
        }

        /++
            Returns the path to the file represented by this `DirEntry`.

Example:
--------------------
auto de1 = DirEntry("/etc/fonts/fonts.conf");
assert(de1.name == "/etc/fonts/fonts.conf");

auto de2 = DirEntry("/usr/share/include");
assert(de2.name == "/usr/share/include");
--------------------
          +/
        @property string name() const return scope;


        /++
            Returns whether the file represented by this `DirEntry` is a
            directory.

Example:
--------------------
auto de1 = DirEntry("/etc/fonts/fonts.conf");
assert(!de1.isDir);

auto de2 = DirEntry("/usr/share/include");
assert(de2.isDir);
--------------------
          +/
        @property bool isDir() scope;


        /++
            Returns whether the file represented by this `DirEntry` is a file.

            On Windows, if a file is not a directory, then it's a file. So,
            either `isFile` or `isDir` will return `true`.

            On POSIX systems, if `isFile` is `true`, that indicates that
            the file is a regular file (e.g. not a block not device). So, on
            POSIX systems, it's possible for both `isFile` and `isDir` to
            be `false` for a particular file (in which case, it's a special
            file). You can use `attributes` or `statBuf` to get more
            information about a special file (see the stat man page for more
            details).

Example:
--------------------
auto de1 = DirEntry("/etc/fonts/fonts.conf");
assert(de1.isFile);

auto de2 = DirEntry("/usr/share/include");
assert(!de2.isFile);
--------------------
          +/
        @property bool isFile() scope;

        /++
            Returns whether the file represented by this `DirEntry` is a
            symbolic link.

            On Windows, return `true` when the file is either a symbolic
            link or a junction point.
          +/
        @property bool isSymlink() scope;

        /++
            Returns the size of the file represented by this `DirEntry`
            in bytes.
          +/
        @property ulong size() scope;

        /++
            $(BLUE This function is Windows-Only.)

            Returns the creation time of the file represented by this
            `DirEntry`.
          +/
        @property SysTime timeCreated() const scope;

        /++
            Returns the time that the file represented by this `DirEntry` was
            last accessed.

            Note that many file systems do not update the access time for files
            (generally for performance reasons), so there's a good chance that
            `timeLastAccessed` will return the same value as
            `timeLastModified`.
          +/
        @property SysTime timeLastAccessed() scope;

        /++
            Returns the time that the file represented by this `DirEntry` was
            last modified.
          +/
        @property SysTime timeLastModified() scope;

        /++
            $(BLUE This function is POSIX-Only.)

            Returns the time that the file represented by this `DirEntry` was
            last changed (not only in contents, but also in permissions or ownership).
          +/
        @property SysTime timeStatusChanged() const scope;

        /++
            Returns the _attributes of the file represented by this `DirEntry`.

            Note that the file _attributes on Windows and POSIX systems are
            completely different. On, Windows, they're what is returned by
            `GetFileAttributes`
            $(HTTP msdn.microsoft.com/en-us/library/aa364944(v=vs.85).aspx, GetFileAttributes)
            Whereas, an POSIX systems, they're the `st_mode` value which is
            part of the `stat` struct gotten by calling `stat`.

            On POSIX systems, if the file represented by this `DirEntry` is a
            symbolic link, then _attributes are the _attributes of the file
            pointed to by the symbolic link.
          +/
        @property uint attributes() scope;

        /++
            On POSIX systems, if the file represented by this `DirEntry` is a
            symbolic link, then `linkAttributes` are the attributes of the
            symbolic link itself. Otherwise, `linkAttributes` is identical to
            `attributes`.

            On Windows, `linkAttributes` is identical to `attributes`. It
            exists on Windows so that you don't have to special-case code for
            Windows when dealing with symbolic links.
          +/
        @property uint linkAttributes() scope;

        version (Windows)
            alias stat_t = void*;

        /++
            $(BLUE This function is POSIX-Only.)

            The `stat` struct gotten from calling `stat`.
          +/
        @property stat_t statBuf() scope;
    }
}
else version (Windows)
{
    struct DirEntry
    {
    @safe:
    public:
        alias name this;

        this(return scope string path)
        {
            import std.datetime.systime : FILETIMEToSysTime;

            if (!path.exists())
                throw new FileException(path, "File does not exist");

            _name = path;

            with (getFileAttributesWin(path))
            {
                _size = makeUlong(nFileSizeLow, nFileSizeHigh);
                _timeCreated = FILETIMEToSysTime(&ftCreationTime);
                _timeLastAccessed = FILETIMEToSysTime(&ftLastAccessTime);
                _timeLastModified = FILETIMEToSysTime(&ftLastWriteTime);
                _attributes = dwFileAttributes;
            }
        }

        private this(string path, WIN32_FIND_DATAW *fd) @trusted
        {
            import core.stdc.wchar_ : wcslen;
            import std.conv : to;
            import std.datetime.systime : FILETIMEToSysTime;
            import std.path : buildPath;

            fd.cFileName[$ - 1] = 0;

            size_t clength = wcslen(&fd.cFileName[0]);
            _name = buildPath(path, fd.cFileName[0 .. clength].to!string);
            _size = (cast(ulong) fd.nFileSizeHigh << 32) | fd.nFileSizeLow;
            _timeCreated = FILETIMEToSysTime(&fd.ftCreationTime);
            _timeLastAccessed = FILETIMEToSysTime(&fd.ftLastAccessTime);
            _timeLastModified = FILETIMEToSysTime(&fd.ftLastWriteTime);
            _attributes = fd.dwFileAttributes;
        }

        @property string name() const pure nothrow return scope
        {
            return _name;
        }

        @property bool isDir() const pure nothrow scope
        {
            return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
        }

        @property bool isFile() const pure nothrow scope
        {
            //Are there no options in Windows other than directory and file?
            //If there are, then this probably isn't the best way to determine
            //whether this DirEntry is a file or not.
            return !isDir;
        }

        @property bool isSymlink() const pure nothrow scope
        {
            return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
        }

        @property ulong size() const pure nothrow scope
        {
            return _size;
        }

        @property SysTime timeCreated() const pure nothrow return scope
        {
            return cast(SysTime)_timeCreated;
        }

        @property SysTime timeLastAccessed() const pure nothrow return scope
        {
            return cast(SysTime)_timeLastAccessed;
        }

        @property SysTime timeLastModified() const pure nothrow return scope
        {
            return cast(SysTime)_timeLastModified;
        }

        @property uint attributes() const pure nothrow scope
        {
            return _attributes;
        }

        @property uint linkAttributes() const pure nothrow scope
        {
            return _attributes;
        }

    private:
        string _name; /// The file or directory represented by this DirEntry.

        SysTime _timeCreated;      /// The time when the file was created.
        SysTime _timeLastAccessed; /// The time when the file was last accessed.
        SysTime _timeLastModified; /// The time when the file was last modified.

        ulong _size;       /// The size of the file in bytes.
        uint  _attributes; /// The file attributes from WIN32_FIND_DATAW.
    }
}
else version (Posix)
{
    struct DirEntry
    {
    @safe:
    public:
        alias name this;

        this(return scope string path)
        {
            if (!path.exists)
                throw new FileException(path, "File does not exist");

            _name = path;

            _didLStat = false;
            _didStat = false;
            _dTypeSet = false;
        }

        private this(string path, core.sys.posix.dirent.dirent* fd) @safe
        {
            import std.path : buildPath;

            static if (is(typeof(fd.d_namlen)))
                immutable len = fd.d_namlen;
            else
                immutable len = (() @trusted => core.stdc.string.strlen(fd.d_name.ptr))();

            _name = buildPath(path, (() @trusted => fd.d_name.ptr[0 .. len])());

            _didLStat = false;
            _didStat = false;

            //fd_d_type doesn't work for all file systems,
            //in which case the result is DT_UNKOWN. But we
            //can determine the correct type from lstat, so
            //we'll only set the dtype here if we could
            //correctly determine it (not lstat in the case
            //of DT_UNKNOWN in case we don't ever actually
            //need the dtype, thus potentially avoiding the
            //cost of calling lstat).
            static if (__traits(compiles, fd.d_type != DT_UNKNOWN))
            {
                if (fd.d_type != DT_UNKNOWN)
                {
                    _dType = fd.d_type;
                    _dTypeSet = true;
                }
                else
                    _dTypeSet = false;
            }
            else
            {
                // e.g. Solaris does not have the d_type member
                _dTypeSet = false;
            }
        }

        @property string name() const pure nothrow return scope
        {
            return _name;
        }

        @property bool isDir() scope
        {
            _ensureStatOrLStatDone();

            return (_statBuf.st_mode & S_IFMT) == S_IFDIR;
        }

        @property bool isFile() scope
        {
            _ensureStatOrLStatDone();

            return (_statBuf.st_mode & S_IFMT) == S_IFREG;
        }

        @property bool isSymlink() scope
        {
            _ensureLStatDone();

            return (_lstatMode & S_IFMT) == S_IFLNK;
        }

        @property ulong size() scope
        {
            _ensureStatDone();
            return _statBuf.st_size;
        }

        @property SysTime timeStatusChanged() scope
        {
            _ensureStatDone();

            return statTimeToStdTime!'c'(_statBuf);
        }

        @property SysTime timeLastAccessed() scope
        {
            _ensureStatDone();

            return statTimeToStdTime!'a'(_statBuf);
        }

        @property SysTime timeLastModified() scope
        {
            _ensureStatDone();

            return statTimeToStdTime!'m'(_statBuf);
        }

        @property uint attributes() scope
        {
            _ensureStatDone();

            return _statBuf.st_mode;
        }

        @property uint linkAttributes() scope
        {
            _ensureLStatDone();

            return _lstatMode;
        }

        @property stat_t statBuf() scope
        {
            _ensureStatDone();

            return _statBuf;
        }

    private:
        /++
            This is to support lazy evaluation, because doing stat's is
            expensive and not always needed.
         +/
        void _ensureStatDone() @trusted scope
        {
            if (_didStat)
                return;

            cenforce(stat(_name.tempCString(), &_statBuf) == 0,
                    "Failed to stat file `" ~ _name ~ "'");

            _didStat = true;
        }

        /++
            This is to support lazy evaluation, because doing stat's is
            expensive and not always needed.

            Try both stat and lstat for isFile and isDir
            to detect broken symlinks.
         +/
        void _ensureStatOrLStatDone() @trusted scope
        {
            if (_didStat)
                return;

            if (stat(_name.tempCString(), &_statBuf) != 0)
            {
                _ensureLStatDone();

                _statBuf = stat_t.init;
                _statBuf.st_mode = S_IFLNK;
            }
            else
            {
                _didStat = true;
            }
        }

        /++
            This is to support lazy evaluation, because doing stat's is
            expensive and not always needed.
         +/
        void _ensureLStatDone() @trusted scope
        {
            if (_didLStat)
                return;

            stat_t statbuf = void;
            cenforce(lstat(_name.tempCString(), &statbuf) == 0,
                "Failed to stat file `" ~ _name ~ "'");

            _lstatMode = statbuf.st_mode;

            _dTypeSet = true;
            _didLStat = true;
        }

        string _name; /// The file or directory represented by this DirEntry.

        stat_t _statBuf = void;   /// The result of stat().
        uint  _lstatMode;         /// The stat mode from lstat().
        ubyte _dType;             /// The type of the file.

        bool _didLStat = false;   /// Whether lstat() has been called for this DirEntry.
        bool _didStat = false;    /// Whether stat() has been called for this DirEntry.
        bool _dTypeSet = false;   /// Whether the dType of the file has been set.
    }
}

@system unittest
{
    version (Windows)
    {
        if ("C:\\Program Files\\".exists)
        {
            auto de = DirEntry("C:\\Program Files\\");
            assert(!de.isFile);
            assert(de.isDir);
            assert(!de.isSymlink);
        }

        if ("C:\\Users\\".exists && "C:\\Documents and Settings\\".exists)
        {
            auto de = DirEntry("C:\\Documents and Settings\\");
            assert(de.isSymlink);
        }

        if ("C:\\Windows\\system.ini".exists)
        {
            auto de = DirEntry("C:\\Windows\\system.ini");
            assert(de.isFile);
            assert(!de.isDir);
            assert(!de.isSymlink);
        }
    }
    else version (Posix)
    {
        import std.exception : assertThrown;

        if (system_directory.exists)
        {
            {
                auto de = DirEntry(system_directory);
                assert(!de.isFile);
                assert(de.isDir);
                assert(!de.isSymlink);
            }

            immutable symfile = deleteme ~ "_slink\0";
            scope(exit) if (symfile.exists) symfile.remove();

            core.sys.posix.unistd.symlink(system_directory, symfile.ptr);

            {
                auto de = DirEntry(symfile);
                assert(!de.isFile);
                assert(de.isDir);
                assert(de.isSymlink);
            }

            symfile.remove();
            core.sys.posix.unistd.symlink((deleteme ~ "_broken_symlink\0").ptr, symfile.ptr);

            {
                // https://issues.dlang.org/show_bug.cgi?id=8298
                DirEntry de = DirEntry(symfile);

                assert(!de.isFile);
                assert(!de.isDir);
                assert(de.isSymlink);
                assertThrown!FileException(de.size);
                assertThrown!FileException(de.timeStatusChanged);
                assertThrown!FileException(de.timeLastAccessed);
                assertThrown!FileException(de.timeLastModified);
                assertThrown!FileException(de.attributes);
                assertThrown!FileException(de.statBuf);
                assert(symfile.exists);
                symfile.remove();
            }
        }

        if (system_file.exists)
        {
            auto de = DirEntry(system_file);
            assert(de.isFile);
            assert(!de.isDir);
            assert(!de.isSymlink);
        }
    }
}

alias PreserveAttributes = Flag!"preserveAttributes";

version (StdDdoc)
{
    /// Defaults to `Yes.preserveAttributes` on Windows, and the opposite on all other platforms.
    PreserveAttributes preserveAttributesDefault;
}
else version (Windows)
{
    enum preserveAttributesDefault = Yes.preserveAttributes;
}
else
{
    enum preserveAttributesDefault = No.preserveAttributes;
}

/***************************************************
Copy file `from` _to file `to`. File timestamps are preserved.
File attributes are preserved, if `preserve` equals `Yes.preserveAttributes`.
On Windows only `Yes.preserveAttributes` (the default on Windows) is supported.
If the target file exists, it is overwritten.

Params:
    from = string or range of characters representing the existing file name
    to = string or range of characters representing the target file name
    preserve = whether to _preserve the file attributes

Throws: $(LREF FileException) on error.
 */
void copy(RF, RT)(RF from, RT to, PreserveAttributes preserve = preserveAttributesDefault)
if (isSomeFiniteCharInputRange!RF && !isConvertibleToString!RF &&
    isSomeFiniteCharInputRange!RT && !isConvertibleToString!RT)
{
    // Place outside of @trusted block
    auto fromz = from.tempCString!FSChar();
    auto toz = to.tempCString!FSChar();

    static if (isNarrowString!RF && is(immutable ElementEncodingType!RF == immutable char))
        alias f = from;
    else
        enum string f = null;

    static if (isNarrowString!RT && is(immutable ElementEncodingType!RT == immutable char))
        alias t = to;
    else
        enum string t = null;

    copyImpl(f, t, fromz, toz, preserve);
}

/// ditto
void copy(RF, RT)(auto ref RF from, auto ref RT to, PreserveAttributes preserve = preserveAttributesDefault)
if (isConvertibleToString!RF || isConvertibleToString!RT)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, RF, RT);
    copy!Types(from, to, preserve);
}

///
@safe unittest
{
    auto source = deleteme ~ "source";
    auto target = deleteme ~ "target";
    auto targetNonExistent = deleteme ~ "target2";

    scope(exit) source.remove, target.remove, targetNonExistent.remove;

    source.write("source");
    target.write("target");

    assert(target.readText == "target");

    source.copy(target);
    assert(target.readText == "source");

    source.copy(targetNonExistent);
    assert(targetNonExistent.readText == "source");
}

// https://issues.dlang.org/show_bug.cgi?id=15319
@safe unittest
{
    assert(__traits(compiles, copy("from.txt", "to.txt")));
}

private void copyImpl(scope const(char)[] f, scope const(char)[] t,
                      scope const(FSChar)* fromz, scope const(FSChar)* toz,
                      PreserveAttributes preserve) @trusted
{
    version (Windows)
    {
        assert(preserve == Yes.preserveAttributes);
        immutable result = CopyFileW(fromz, toz, false);
        if (!result)
        {
            import core.stdc.wchar_ : wcslen;
            import std.conv : to;
            import std.format : format;

            /++
            Reference resources: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfilew
            Because OS copyfilew handles both source and destination paths,
            the GetLastError does not accurately locate whether the error is for the source or destination.
            +/
            if (!f)
                f = to!(typeof(f))(fromz[0 .. wcslen(fromz)]);
            if (!t)
                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);

            throw new FileException(format!"Copy from %s to %s"(f, t));
        }
    }
    else version (Posix)
    {
        static import core.stdc.stdio;
        import std.conv : to, octal;

        immutable fdr = core.sys.posix.fcntl.open(fromz, O_RDONLY);
        cenforce(fdr != -1, f, fromz);
        scope(exit) core.sys.posix.unistd.close(fdr);

        stat_t statbufr = void;
        cenforce(fstat(fdr, &statbufr) == 0, f, fromz);
        //cenforce(core.sys.posix.sys.stat.fstat(fdr, &statbufr) == 0, f, fromz);

        immutable fdw = core.sys.posix.fcntl.open(toz,
                O_CREAT | O_WRONLY, octal!666);
        cenforce(fdw != -1, t, toz);
        {
            scope(failure) core.sys.posix.unistd.close(fdw);

            stat_t statbufw = void;
            cenforce(fstat(fdw, &statbufw) == 0, t, toz);
            if (statbufr.st_dev == statbufw.st_dev && statbufr.st_ino == statbufw.st_ino)
                throw new FileException(t, "Source and destination are the same file");
        }

        scope(failure) core.stdc.stdio.remove(toz);
        {
            scope(failure) core.sys.posix.unistd.close(fdw);
            cenforce(ftruncate(fdw, 0) == 0, t, toz);

            auto BUFSIZ = 4096u * 16;
            auto buf = core.stdc.stdlib.malloc(BUFSIZ);
            if (!buf)
            {
                BUFSIZ = 4096;
                buf = core.stdc.stdlib.malloc(BUFSIZ);
                if (!buf)
                {
                    import core.exception : onOutOfMemoryError;
                    onOutOfMemoryError();
                }
            }
            scope(exit) core.stdc.stdlib.free(buf);

            for (auto size = statbufr.st_size; size; )
            {
                immutable toxfer = (size > BUFSIZ) ? BUFSIZ : cast(size_t) size;
                cenforce(
                    core.sys.posix.unistd.read(fdr, buf, toxfer) == toxfer
                    && core.sys.posix.unistd.write(fdw, buf, toxfer) == toxfer,
                    f, fromz);
                assert(size >= toxfer);
                size -= toxfer;
            }
            if (preserve)
                cenforce(fchmod(fdw, to!mode_t(statbufr.st_mode)) == 0, f, fromz);
        }

        cenforce(core.sys.posix.unistd.close(fdw) != -1, f, fromz);

        setTimesImpl(t, toz, statbufr.statTimeToStdTime!'a', statbufr.statTimeToStdTime!'m');
    }
}

// https://issues.dlang.org/show_bug.cgi?id=14817
@safe unittest
{
    import std.algorithm, std.file;
    auto t1 = deleteme, t2 = deleteme~"2";
    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();
    write(t1, "11");
    copy(t1, t2);
    assert(readText(t2) == "11");
    write(t1, "2");
    copy(t1, t2);
    assert(readText(t2) == "2");

    import std.utf : byChar;
    copy(t1.byChar, t2.byChar);
    assert(readText(t2.byChar) == "2");

// https://issues.dlang.org/show_bug.cgi?id=20370
    version (Windows)
        assert(t1.timeLastModified == t2.timeLastModified);
    else static if (is(typeof(&utimensat)) || is(typeof(&setattrlist)))
        assert(t1.timeLastModified == t2.timeLastModified);
    else
        assert(abs(t1.timeLastModified - t2.timeLastModified) < dur!"usecs"(1));
}

// https://issues.dlang.org/show_bug.cgi?id=11434
@safe version (Posix) @safe unittest
{
    import std.conv : octal;
    auto t1 = deleteme, t2 = deleteme~"2";
    scope(exit) foreach (t; [t1, t2]) if (t.exists) t.remove();
    write(t1, "1");
    setAttributes(t1, octal!767);
    copy(t1, t2, Yes.preserveAttributes);
    assert(readText(t2) == "1");
    assert(getAttributes(t2) == octal!100767);
}

// https://issues.dlang.org/show_bug.cgi?id=15865
@safe unittest
{
    import std.exception : assertThrown;
    auto t = deleteme;
    write(t, "a");
    scope(exit) t.remove();
    assertThrown!FileException(copy(t, t));
    assert(readText(t) == "a");
}

// https://issues.dlang.org/show_bug.cgi?id=19834
version (Windows) @safe unittest
{
    import std.exception : collectException;
    import std.algorithm.searching : startsWith;
    import std.format : format;

    auto f = deleteme;
    auto t = f ~ "2";
    auto ex = collectException(copy(f, t));
    assert(ex.msg.startsWith(format!"Copy from %s to %s"(f, t)));
}

/++
    Remove directory and all of its content and subdirectories,
    recursively.

    Params:
        pathname = the path of the directory to completely remove
        de = The $(LREF DirEntry) to remove

    Throws:
        $(LREF FileException) if there is an error (including if the given
        file is not a directory).
 +/
void rmdirRecurse(scope const(char)[] pathname) @safe
{
    //No references to pathname will be kept after rmdirRecurse,
    //so the cast is safe
    rmdirRecurse(DirEntry((() @trusted => cast(string) pathname)()));
}

/// ditto
void rmdirRecurse(ref scope DirEntry de) @safe
{
    if (!de.isDir)
        throw new FileException(de.name, "Not a directory");

    if (de.isSymlink)
    {
        version (Windows)
            rmdir(de.name);
        else
            remove(de.name);
    }
    else
    {
        // dirEntries is @system without DIP1000 because it uses
        // a DirIterator with a SafeRefCounted variable, but here, no
        // references to the payload are escaped to the outside, so this should
        // be @trusted
        () @trusted {
            // all children, recursively depth-first
            foreach (DirEntry e; dirEntries(de.name, SpanMode.depth, false))
            {
                attrIsDir(e.linkAttributes) ? rmdir(e.name) : remove(e.name);
            }
        }();

        // the dir itself
        rmdir(de.name);
    }
}
///ditto
//Note, without this overload, passing an RValue DirEntry still works, but
//actually fully reconstructs a DirEntry inside the
//"rmdirRecurse(in char[] pathname)" implementation. That is needlessly
//expensive.
//A DirEntry is a bit big (72B), so keeping the "by ref" signature is desirable.
void rmdirRecurse(scope DirEntry de) @safe
{
    rmdirRecurse(de);
}

///
@system unittest
{
    import std.path : buildPath;

    auto dir = deleteme.buildPath("a", "b", "c");

    dir.mkdirRecurse;
    assert(dir.exists);

    deleteme.rmdirRecurse;
    assert(!dir.exists);
    assert(!deleteme.exists);
}

version (Windows) @system unittest
{
    import std.exception : enforce;
    auto d = deleteme ~ r".dir\a\b\c\d\e\f\g";
    mkdirRecurse(d);
    rmdirRecurse(deleteme ~ ".dir");
    enforce(!exists(deleteme ~ ".dir"));
}

version (Posix) @system unittest
{
    import std.exception : enforce, collectException;

    collectException(rmdirRecurse(deleteme));
    auto d = deleteme~"/a/b/c/d/e/f/g";
    enforce(collectException(mkdir(d)));
    mkdirRecurse(d);
    core.sys.posix.unistd.symlink((deleteme~"/a/b/c\0").ptr,
            (deleteme~"/link\0").ptr);
    rmdirRecurse(deleteme~"/link");
    enforce(exists(d));
    rmdirRecurse(deleteme);
    enforce(!exists(deleteme));

    d = deleteme~"/a/b/c/d/e/f/g";
    mkdirRecurse(d);
    const linkTarget = deleteme ~ "/link";
    symlink(deleteme ~ "/a/b/c", linkTarget);
    rmdirRecurse(deleteme);
    enforce(!exists(deleteme));
}

@safe unittest
{
    ubyte[] buf = new ubyte[10];
    buf[] = 3;
    string unit_file = deleteme ~ "-unittest_write.tmp";
    if (exists(unit_file)) remove(unit_file);
    write(unit_file, cast(void[]) buf);
    void[] buf2 = read(unit_file);
    assert(cast(void[]) buf == buf2);

    string unit2_file = deleteme ~ "-unittest_write2.tmp";
    copy(unit_file, unit2_file);
    buf2 = read(unit2_file);
    assert(cast(void[]) buf == buf2);

    remove(unit_file);
    assert(!exists(unit_file));
    remove(unit2_file);
    assert(!exists(unit2_file));
}

/**
 * Dictates directory spanning policy for $(D_PARAM dirEntries) (see below).
 */
enum SpanMode
{
    /** Only spans one directory. */
    shallow,
    /** Spans the directory in
     $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Post-order,
     _depth-first $(B post)-order), i.e. the content of any
     subdirectory is spanned before that subdirectory itself. Useful
     e.g. when recursively deleting files.  */
    depth,
    /** Spans the directory in
    $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Pre-order, depth-first
    $(B pre)-order), i.e. the content of any subdirectory is spanned
    right after that subdirectory itself.

    Note that `SpanMode.breadth` will not result in all directory
    members occurring before any subdirectory members, i.e. it is not
    _true
    $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search,
    _breadth-first traversal).
    */
    breadth,
}

///
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    import std.algorithm.sorting : sort;
    import std.array : array;
    import std.path : buildPath, relativePath;

    auto root = deleteme ~ "root";
    scope(exit) root.rmdirRecurse;
    root.mkdir;

    root.buildPath("animals").mkdir;
    root.buildPath("animals", "cat").mkdir;

    alias removeRoot = (return scope e) => e.relativePath(root);

    assert(root.dirEntries(SpanMode.depth).map!removeRoot.equal(
        [buildPath("animals", "cat"), "animals"]));

    assert(root.dirEntries(SpanMode.breadth).map!removeRoot.equal(
        ["animals", buildPath("animals", "cat")]));

    root.buildPath("plants").mkdir;

    assert(root.dirEntries(SpanMode.shallow).array.sort.map!removeRoot.equal(
        ["animals", "plants"]));
}

private struct DirIteratorImpl
{
  @safe:
    SpanMode _mode;
    // Whether we should follow symlinked directories while iterating.
    // It also indicates whether we should avoid functions which call
    // stat (since we should only need lstat in this case and it would
    // be more efficient to not call stat in addition to lstat).
    bool _followSymlink;
    DirEntry _cur;
    DirHandle[] _stack;
    DirEntry[] _stashed; //used in depth first mode

    //stack helpers
    void pushExtra(DirEntry de)
    {
        _stashed ~= de;
    }

    //ditto
    bool hasExtra()
    {
        return _stashed.length != 0;
    }

    //ditto
    DirEntry popExtra()
    {
        DirEntry de;
        de = _stashed[$-1];
        _stashed.popBack();
        return de;
    }

    version (Windows)
    {
        WIN32_FIND_DATAW _findinfo;
        struct DirHandle
        {
            string dirpath;
            HANDLE h;
        }

        bool stepIn(string directory) @safe
        {
            import std.path : chainPath;
            auto searchPattern = chainPath(directory, "*.*");

            static auto trustedFindFirstFileW(typeof(searchPattern) pattern, scope WIN32_FIND_DATAW* findinfo) @trusted
            {
                return FindFirstFileW(pattern.tempCString!FSChar(), findinfo);
            }

            HANDLE h = trustedFindFirstFileW(searchPattern, &_findinfo);
            cenforce(h != INVALID_HANDLE_VALUE, directory);
            _stack ~= DirHandle(directory, h);
            return toNext(false, &_findinfo);
        }

        bool next()
        {
            if (_stack.length == 0)
                return false;
            return toNext(true, &_findinfo);
        }

        bool toNext(bool fetch, scope WIN32_FIND_DATAW* findinfo) @trusted
        {
            import core.stdc.wchar_ : wcscmp;

            if (fetch)
            {
                if (FindNextFileW(_stack[$-1].h, findinfo) == FALSE)
                {
                    popDirStack();
                    return false;
                }
            }
            while (wcscmp(&findinfo.cFileName[0], ".") == 0 ||
                   wcscmp(&findinfo.cFileName[0], "..") == 0)
                if (FindNextFileW(_stack[$-1].h, findinfo) == FALSE)
                {
                    popDirStack();
                    return false;
                }
            _cur = DirEntry(_stack[$-1].dirpath, findinfo);
            return true;
        }

        void popDirStack() @trusted
        {
            assert(_stack.length != 0);
            FindClose(_stack[$-1].h);
            _stack.popBack();
        }

        void releaseDirStack() @trusted
        {
            foreach (d; _stack)
                FindClose(d.h);
        }

        bool mayStepIn()
        {
            return _followSymlink ? _cur.isDir : _cur.isDir && !_cur.isSymlink;
        }
    }
    else version (Posix)
    {
        struct DirHandle
        {
            string dirpath;
            DIR*   h;
        }

        bool stepIn(string directory)
        {
            static auto trustedOpendir(string dir) @trusted
            {
                return opendir(dir.tempCString());
            }

            auto h = directory.length ? trustedOpendir(directory) : trustedOpendir(".");
            cenforce(h, directory);
            _stack ~= (DirHandle(directory, h));
            return next();
        }

        bool next() @trusted
        {
            if (_stack.length == 0)
                return false;

            for (dirent* fdata; (fdata = readdir(_stack[$-1].h)) != null; )
            {
                // Skip "." and ".."
                if (core.stdc.string.strcmp(&fdata.d_name[0], ".") &&
                    core.stdc.string.strcmp(&fdata.d_name[0], ".."))
                {
                    _cur = DirEntry(_stack[$-1].dirpath, fdata);
                    return true;
                }
            }

            popDirStack();
            return false;
        }

        void popDirStack() @trusted
        {
            assert(_stack.length != 0);
            closedir(_stack[$-1].h);
            _stack.popBack();
        }

        void releaseDirStack() @trusted
        {
            foreach (d; _stack)
                closedir(d.h);
        }

        bool mayStepIn()
        {
            return _followSymlink ? _cur.isDir : attrIsDir(_cur.linkAttributes);
        }
    }

    this(R)(R pathname, SpanMode mode, bool followSymlink)
    if (isSomeFiniteCharInputRange!R)
    {
        _mode = mode;
        _followSymlink = followSymlink;

        static if (isNarrowString!R && is(immutable ElementEncodingType!R == immutable char))
            alias pathnameStr = pathname;
        else
        {
            import std.array : array;
            string pathnameStr = pathname.array;
        }
        if (stepIn(pathnameStr))
        {
            if (_mode == SpanMode.depth)
                while (mayStepIn())
                {
                    auto thisDir = _cur;
                    if (stepIn(_cur.name))
                    {
                        pushExtra(thisDir);
                    }
                    else
                        break;
                }
        }
    }

    @property bool empty()
    {
        return _stashed.length == 0 && _stack.length == 0;
    }

    @property DirEntry front()
    {
        return _cur;
    }

    void popFront()
    {
        switch (_mode)
        {
        case SpanMode.depth:
            if (next())
            {
                while (mayStepIn())
                {
                    auto thisDir = _cur;
                    if (stepIn(_cur.name))
                    {
                        pushExtra(thisDir);
                    }
                    else
                        break;
                }
            }
            else if (hasExtra())
                _cur = popExtra();
            break;
        case SpanMode.breadth:
            if (mayStepIn())
            {
                if (!stepIn(_cur.name))
                    while (!empty && !next()){}
            }
            else
                while (!empty && !next()){}
            break;
        default:
            next();
        }
    }

    ~this()
    {
        releaseDirStack();
    }
}

// Must be a template, because the destructor is unsafe or safe depending on
// whether `-preview=dip1000` is in use. Otherwise, linking errors would
// result.
struct _DirIterator(bool useDIP1000)
{
    static assert(useDIP1000 == dip1000Enabled,
        "Please don't override useDIP1000 to disagree with compiler switch.");

private:
    SafeRefCounted!(DirIteratorImpl, RefCountedAutoInitialize.no) impl;

    this(string pathname, SpanMode mode, bool followSymlink) @trusted
    {
        impl = typeof(impl)(pathname, mode, followSymlink);
    }
public:
    @property bool empty() @trusted { return impl.empty; }
    @property DirEntry front() @trusted { return impl.front; }
    void popFront() @trusted { impl.popFront(); }
}

// This has the client code to automatically use and link to the correct
// template instance
alias DirIterator = _DirIterator!dip1000Enabled;

/++
    Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    of `DirEntry` that lazily iterates a given directory,
    also provides two ways of foreach iteration. The iteration variable can be of
    type `string` if only the name is needed, or `DirEntry`
    if additional details are needed. The span _mode dictates how the
    directory is traversed. The name of each iterated directory entry
    contains the absolute or relative _path (depending on _pathname).

    Note: The order of returned directory entries is as it is provided by the
    operating system / filesystem, and may not follow any particular sorting.

    Params:
        useDIP1000 = used to instantiate this function separately for code with
                     and without -preview=dip1000 compiler switch, because it
                     affects the ABI of this function. Set automatically -
                     don't touch.

        path = The directory to iterate over.
               If empty, the current directory will be iterated.

        pattern = Optional string with wildcards, such as $(RED
                  "*.d"). When present, it is used to filter the
                  results by their file name. The supported wildcard
                  strings are described under $(REF globMatch,
                  std,_path).

        mode = Whether the directory's sub-directories should be
               iterated in depth-first post-order ($(LREF depth)),
               depth-first pre-order ($(LREF breadth)), or not at all
               ($(LREF shallow)).

        followSymlink = Whether symbolic links which point to directories
                         should be treated as directories and their contents
                         iterated over.

    Returns:
        An $(REF_ALTTEXT input range, isInputRange,std,range,primitives) of
        $(LREF DirEntry).

    Throws:
        $(UL
        $(LI $(LREF FileException) if the $(B path) directory does not exist or read permission is denied.)
        $(LI $(LREF FileException) if $(B mode) is not `shallow` and a subdirectory cannot be read.)
        )

Example:
--------------------
// Iterate a directory in depth
foreach (string name; dirEntries("destroy/me", SpanMode.depth))
{
    remove(name);
}

// Iterate the current directory in breadth
foreach (string name; dirEntries("", SpanMode.breadth))
{
    writeln(name);
}

// Iterate a directory and get detailed info about it
foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth))
{
    writeln(e.name, "\t", e.size);
}

// Iterate over all *.d files in current directory and all its subdirectories
auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d"));
foreach (d; dFiles)
    writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel:
foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread
{
    string cmd = "dmd -c "  ~ d.name;
    writeln(cmd);
    std.process.executeShell(cmd);
}

// Iterate over all D source files in current directory and all its
// subdirectories
auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth);
foreach (d; dFiles)
    writeln(d.name);
--------------------
To handle subdirectories with denied read permission, use `SpanMode.shallow`:
---
void scan(string path)
{
    foreach (DirEntry entry; dirEntries(path, SpanMode.shallow))
    {
        try
        {
            writeln(entry.name);
            if (entry.isDir)
                scan(entry.name);
        }
        catch (FileException fe) { continue; } // ignore
    }
}

scan("");
---
+/

// For some reason, doing the same alias-to-a-template trick as with DirIterator
// does not work here.
auto dirEntries(bool useDIP1000 = dip1000Enabled)
    (string path, SpanMode mode, bool followSymlink = true)
{
    return _DirIterator!useDIP1000(path, mode, followSymlink);
}

/// Duplicate functionality of D1's `std.file.listdir()`:
@safe unittest
{
    string[] listdir(string pathname)
    {
        import std.algorithm.iteration : map, filter;
        import std.array : array;
        import std.path : baseName;

        return dirEntries(pathname, SpanMode.shallow)
            .filter!(a => a.isFile)
            .map!((return a) => baseName(a.name))
            .array;
    }

    // Can be safe only with -preview=dip1000
    @safe void main(string[] args)
    {
        import std.stdio : writefln;

        string[] files = listdir(args[1]);
        writefln("%s", files);
    }
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    import std.algorithm.searching : startsWith;
    import std.array : array;
    import std.conv : to;
    import std.path : buildPath, absolutePath;
    import std.file : dirEntries;
    import std.process : thisProcessID;
    import std.range.primitives : walkLength;

    version (Android)
        string testdir = deleteme; // This has to be an absolute path when
                                   // called from a shared library on Android,
                                   // ie an apk
    else
        string testdir = tempDir.buildPath("deleteme.dmd.unittest.std.file" ~ to!string(thisProcessID));
    mkdirRecurse(buildPath(testdir, "somedir"));
    scope(exit) rmdirRecurse(testdir);
    write(buildPath(testdir, "somefile"), null);
    write(buildPath(testdir, "somedir", "somedeepfile"), null);

    // testing range interface
    size_t equalEntries(string relpath, SpanMode mode)
    {
        import std.exception : enforce;
        auto len = enforce(walkLength(dirEntries(absolutePath(relpath), mode)));
        assert(walkLength(dirEntries(relpath, mode)) == len);
        assert(equal(
                   map!((return a) => absolutePath(a.name))(dirEntries(relpath, mode)),
                   map!(a => a.name)(dirEntries(absolutePath(relpath), mode))));
        return len;
    }

    assert(equalEntries(testdir, SpanMode.shallow) == 2);
    assert(equalEntries(testdir, SpanMode.depth) == 3);
    assert(equalEntries(testdir, SpanMode.breadth) == 3);

    // testing opApply
    foreach (string name; dirEntries(testdir, SpanMode.breadth))
    {
        //writeln(name);
        assert(name.startsWith(testdir));
    }
    foreach (DirEntry e; dirEntries(absolutePath(testdir), SpanMode.breadth))
    {
        //writeln(name);
        assert(e.isFile || e.isDir, e.name);
    }

    // https://issues.dlang.org/show_bug.cgi?id=7264
    foreach (string name; dirEntries(testdir, "*.d", SpanMode.breadth))
    {

    }
    foreach (entry; dirEntries(testdir, SpanMode.breadth))
    {
        static assert(is(typeof(entry) == DirEntry));
    }
    // https://issues.dlang.org/show_bug.cgi?id=7138
    auto a = array(dirEntries(testdir, SpanMode.shallow));

    // https://issues.dlang.org/show_bug.cgi?id=11392
    auto dFiles = dirEntries(testdir, SpanMode.shallow);
    foreach (d; dFiles){}

    // https://issues.dlang.org/show_bug.cgi?id=15146
    dirEntries("", SpanMode.shallow).walkLength();
}

/// Ditto
auto dirEntries(bool useDIP1000 = dip1000Enabled)
    (string path, string pattern, SpanMode mode,
    bool followSymlink = true)
{
    import std.algorithm.iteration : filter;
    import std.path : globMatch, baseName;

    bool f(DirEntry de) { return globMatch(baseName(de.name), pattern); }
    return filter!f(_DirIterator!useDIP1000(path, mode, followSymlink));
}

@safe unittest
{
    import std.stdio : writefln;
    immutable dpath = deleteme ~ "_dir";
    immutable fpath = deleteme ~ "_file";
    immutable sdpath = deleteme ~ "_sdir";
    immutable sfpath = deleteme ~ "_sfile";
    scope(exit)
    {
        if (dpath.exists) rmdirRecurse(dpath);
        if (fpath.exists) remove(fpath);
        if (sdpath.exists) remove(sdpath);
        if (sfpath.exists) remove(sfpath);
    }

    mkdir(dpath);
    write(fpath, "hello world");
    version (Posix) () @trusted
    {
        core.sys.posix.unistd.symlink((dpath ~ '\0').ptr, (sdpath ~ '\0').ptr);
        core.sys.posix.unistd.symlink((fpath ~ '\0').ptr, (sfpath ~ '\0').ptr);
    } ();

    static struct Flags { bool dir, file, link; }
    auto tests = [dpath : Flags(true), fpath : Flags(false, true)];
    version (Posix)
    {
        tests[sdpath] = Flags(true, false, true);
        tests[sfpath] = Flags(false, true, true);
    }

    auto past = Clock.currTime() - 2.seconds;
    auto future = past + 4.seconds;

    foreach (path, flags; tests)
    {
        auto de = DirEntry(path);
        assert(de.name == path);
        assert(de.isDir == flags.dir);
        assert(de.isFile == flags.file);
        assert(de.isSymlink == flags.link);

        assert(de.isDir == path.isDir);
        assert(de.isFile == path.isFile);
        assert(de.isSymlink == path.isSymlink);
        assert(de.size == path.getSize());
        assert(de.attributes == getAttributes(path));
        assert(de.linkAttributes == getLinkAttributes(path));

        scope(failure) writefln("[%s] [%s] [%s] [%s]", past, de.timeLastAccessed, de.timeLastModified, future);
        assert(de.timeLastAccessed > past);
        assert(de.timeLastAccessed < future);
        assert(de.timeLastModified > past);
        assert(de.timeLastModified < future);

        assert(attrIsDir(de.attributes) == flags.dir);
        assert(attrIsDir(de.linkAttributes) == (flags.dir && !flags.link));
        assert(attrIsFile(de.attributes) == flags.file);
        assert(attrIsFile(de.linkAttributes) == (flags.file && !flags.link));
        assert(!attrIsSymlink(de.attributes));
        assert(attrIsSymlink(de.linkAttributes) == flags.link);

        version (Windows)
        {
            assert(de.timeCreated > past);
            assert(de.timeCreated < future);
        }
        else version (Posix)
        {
            assert(de.timeStatusChanged > past);
            assert(de.timeStatusChanged < future);
            assert(de.attributes == de.statBuf.st_mode);
        }
    }
}

// Make sure that dirEntries does not butcher Unicode file names
// https://issues.dlang.org/show_bug.cgi?id=17962
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    import std.algorithm.sorting : sort;
    import std.array : array;
    import std.path : buildPath;
    import std.uni : normalize;

    // The Unicode normalization is required to make the tests pass on Mac OS X.
    auto dir = deleteme ~ normalize("𐐷");
    scope(exit) if (dir.exists) rmdirRecurse(dir);
    mkdir(dir);
    auto files = ["Hello World",
                  "Ma Chérie.jpeg",
                  "さいごの果実.txt"].map!(a => buildPath(dir, normalize(a)))().array();
    sort(files);
    foreach (file; files)
        write(file, "nothing");

    auto result = dirEntries(dir, SpanMode.shallow).map!((return a) => a.name.normalize()).array();
    sort(result);

    assert(equal(files, result));
}

// https://issues.dlang.org/show_bug.cgi?id=21250
@system unittest
{
    import std.exception : assertThrown;
    assertThrown!Exception(dirEntries("237f5babd6de21f40915826699582e36", "*.bin", SpanMode.depth));
}

/**
 * Reads a file line by line and parses the line into a single value or a
 * $(REF Tuple, std,typecons) of values depending on the length of `Types`.
 * The lines are parsed using the specified format string. The format string is
 * passed to $(REF formattedRead, std,_format), and therefore must conform to the
 * _format string specification outlined in $(MREF std, _format).
 *
 * Params:
 *     Types = the types that each of the elements in the line should be returned as
 *     filename = the name of the file to read
 *     format = the _format string to use when reading
 *
 * Returns:
 *     If only one type is passed, then an array of that type. Otherwise, an
 *     array of $(REF Tuple, std,typecons)s.
 *
 * Throws:
 *     `Exception` if the format string is malformed. Also, throws `Exception`
 *     if any of the lines in the file are not fully consumed by the call
 *     to $(REF formattedRead, std,_format). Meaning that no empty lines or lines
 *     with extra characters are allowed.
 */
Select!(Types.length == 1, Types[0][], Tuple!(Types)[])
slurp(Types...)(string filename, scope const(char)[] format)
{
    import std.array : appender;
    import std.conv : text;
    import std.exception : enforce;
    import std.format.read : formattedRead;
    import std.stdio : File;
    import std.string : stripRight;

    auto app = appender!(typeof(return))();
    ElementType!(typeof(return)) toAdd;
    auto f = File(filename);
    scope(exit) f.close();
    foreach (line; f.byLine())
    {
        formattedRead(line, format, &toAdd);
        enforce(line.stripRight("\r").empty,
                text("Trailing characters at the end of line: `", line,
                        "'"));
        app.put(toAdd);
    }
    return app.data;
}

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

    scope(exit)
    {
        assert(exists(deleteme));
        remove(deleteme);
    }

    write(deleteme, "12 12.25\n345 1.125"); // deleteme is the name of a temporary file

    // Load file; each line is an int followed by comma, whitespace and a
    // double.
    auto a = slurp!(int, double)(deleteme, "%s %s");
    assert(a.length == 2);
    assert(a[0] == tuple(12, 12.25));
    assert(a[1] == tuple(345, 1.125));
}

@system unittest
{
    import std.typecons : tuple;

    scope(exit)
    {
        assert(exists(deleteme));
        remove(deleteme);
    }
    write(deleteme, "10\r\n20");
    assert(slurp!(int)(deleteme, "%d") == [10, 20]);
}

/**
Returns the path to a directory for temporary files.
On POSIX platforms, it searches through the following list of directories
and returns the first one which is found to exist:
$(OL
    $(LI The directory given by the `TMPDIR` environment variable.)
    $(LI The directory given by the `TEMP` environment variable.)
    $(LI The directory given by the `TMP` environment variable.)
    $(LI `/tmp/`)
    $(LI `/var/tmp/`)
    $(LI `/usr/tmp/`)
)

On all platforms, `tempDir` returns the current working directory on failure.

The return value of the function is cached, so the procedures described
below will only be performed the first time the function is called.  All
subsequent runs will return the same string, regardless of whether
environment variables and directory structures have changed in the
meantime.

The POSIX `tempDir` algorithm is inspired by Python's
$(LINK2 http://docs.python.org/library/tempfile.html#tempfile.tempdir, `tempfile.tempdir`).

Returns:
    On Windows, this function returns the result of calling the Windows API function
    $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992.aspx, `GetTempPath`).

    On POSIX platforms, it searches through the following list of directories
    and returns the first one which is found to exist:
    $(OL
        $(LI The directory given by the `TMPDIR` environment variable.)
        $(LI The directory given by the `TEMP` environment variable.)
        $(LI The directory given by the `TMP` environment variable.)
        $(LI `/tmp`)
        $(LI `/var/tmp`)
        $(LI `/usr/tmp`)
    )

    On all platforms, `tempDir` returns `"."` on failure, representing
    the current working directory.
*/
string tempDir() @trusted
{
    // We must check that the end of a path is not a separator, before adding another
    // If we don't we end up with https://issues.dlang.org/show_bug.cgi?id=22738
    static string addSeparator(string input)
    {
        import std.path : dirSeparator;
        import std.algorithm.searching : endsWith;

        // It is very rare a directory path will reach this point with a directory separator at the end
        // However on OSX this can happen, so we must verify lest we break user code i.e. https://github.com/dlang/dub/pull/2208
        if (!input.endsWith(dirSeparator))
            return input ~ dirSeparator;
        else
            return input;
    }

    static string cache;
    if (cache is null)
    {
        version (Windows)
        {
            import std.conv : to;
            // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
            wchar[MAX_PATH + 2] buf;
            DWORD len = GetTempPathW(buf.length, buf.ptr);
            if (len) cache = buf[0 .. len].to!string;
        }
        else version (Posix)
        {
            import std.process : environment;
            // This function looks through the list of alternative directories
            // and returns the first one which exists and is a directory.
            static string findExistingDir(T...)(lazy T alternatives)
            {
                foreach (dir; alternatives)
                    if (!dir.empty && exists(dir)) return addSeparator(dir);
                return null;
            }

            cache = findExistingDir(environment.get("TMPDIR"),
                                    environment.get("TEMP"),
                                    environment.get("TMP"),
                                    "/tmp",
                                    "/var/tmp",
                                    "/usr/tmp");
        }
        else static assert(false, "Unsupported platform");

        if (cache is null)
        {
            cache = addSeparator(getcwd());
        }
    }
    return cache;
}

///
@safe unittest
{
    import std.ascii : letters;
    import std.conv : to;
    import std.path : buildPath;
    import std.random : randomSample;
    import std.utf : byCodeUnit;

    // random id with 20 letters
    auto id = letters.byCodeUnit.randomSample(20).to!string;
    auto myFile = tempDir.buildPath(id ~ "my_tmp_file");
    scope(exit) myFile.remove;

    myFile.write("hello");
    assert(myFile.readText == "hello");
}

@safe unittest
{
    import std.algorithm.searching : endsWith;
    import std.path : dirSeparator;
    assert(tempDir.endsWith(dirSeparator));

    // https://issues.dlang.org/show_bug.cgi?id=22738
    assert(!tempDir.endsWith(dirSeparator ~ dirSeparator));
}

/**
Returns the available disk space based on a given path.
On Windows, `path` must be a directory; on POSIX systems, it can be a file or directory.

Params:
    path = on Windows, it must be a directory; on POSIX it can be a file or directory
Returns:
    Available space in bytes

Throws:
    $(LREF FileException) in case of failure
*/
ulong getAvailableDiskSpace(scope const(char)[] path) @safe
{
    version (Windows)
    {
        import core.sys.windows.winbase : GetDiskFreeSpaceExW;
        import core.sys.windows.winnt : ULARGE_INTEGER;
        import std.internal.cstring : tempCStringW;

        ULARGE_INTEGER freeBytesAvailable;
        auto err = () @trusted {
            return GetDiskFreeSpaceExW(path.tempCStringW(), &freeBytesAvailable, null, null);
        } ();
        cenforce(err != 0, "Cannot get available disk space");

        return freeBytesAvailable.QuadPart;
    }
    else version (Posix)
    {
        import std.internal.cstring : tempCString;

        version (FreeBSD)
        {
            import core.sys.freebsd.sys.mount : statfs, statfs_t;

            statfs_t stats;
            auto err = () @trusted {
                return statfs(path.tempCString(), &stats);
            } ();
            cenforce(err == 0, "Cannot get available disk space");

            return stats.f_bavail * stats.f_bsize;
        }
        else
        {
            import core.sys.posix.sys.statvfs : statvfs, statvfs_t;

            statvfs_t stats;
            auto err = () @trusted {
                return statvfs(path.tempCString(), &stats);
            } ();
            cenforce(err == 0, "Cannot get available disk space");

            return stats.f_bavail * stats.f_frsize;
        }
    }
    else static assert(0, "Unsupported platform");
}

///
@safe unittest
{
    import std.exception : assertThrown;

    auto space = getAvailableDiskSpace(".");
    assert(space > 0);

    assertThrown!FileException(getAvailableDiskSpace("ThisFileDoesNotExist123123"));
}
