// 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;)
$(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)
))
$(TR $(TD Other) $(TD
          $(LREF DirEntry)
          $(LREF FileException)
          $(LREF PreserveAttributes)
          $(LREF SpanMode)
))
)


Copyright: Copyright Digital Mars 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),
           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.primitives;
import std.traits;
import std.typecons;

version (Windows)
{
    import core.sys.windows.windows, 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;
}
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 : to;
    import std.path : buildPath;
    import std.process : thisProcessID;

    static _deleteme = "deleteme.dmd.unittest.pid";
    static _first = true;

    if (_first)
    {
        _deleteme = buildPath(tempDir(), _deleteme) ~ to!string(thisProcessID);
        _first = false;
    }

    return _deleteme;
}

version (unittest) private struct TestAliasedString
{
    string get() @safe @nogc pure nothrow { 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;

    /++
        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(in char[] name, in char[] msg, string file = __FILE__, size_t line = __LINE__) @safe pure
    {
        if (msg.empty)
            super(name.idup, file, line);
        else
            super(text(name, ": ", msg), file, line);

        errno = 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 $(D __FILE__).
            line  = The _line where the error occurred.
                    Defaults to $(D __LINE__).
     +/
    version (Windows) this(in char[] name,
                          uint errno = .GetLastError(),
                          string file = __FILE__,
                          size_t line = __LINE__) @safe
    {
        this(name, sysErrorString(errno), file, line);
        this.errno = errno;
    }
    else version (Posix) this(in char[] name,
                             uint errno = .errno,
                             string file = __FILE__,
                             size_t line = __LINE__) @trusted
    {
        import std.exception : errnoString;
        this(name, errnoString(errno), file, line);
        this.errno = errno;
    }
}

private T cenforce(T)(T condition, lazy 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, const(char)[] name, 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, const(char)[] name, 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);
}

@safe unittest
{
    // issue 17102
    try
    {
        cenforce(false, null, null,
                __FILE__, __LINE__);
    }
    catch (FileException) {}
}

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

/********************************************
Read entire contents of file $(D name) and returns it as an untyped
array. If the file size is larger than $(D upTo), only $(D 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.
 */

void[] read(R)(R name, size_t upTo = size_t.max)
if (isInputRange!R && isSomeChar!(ElementEncodingType!R) && !isInfinite!R &&
    !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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);
    }

    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(const(char)[] name, const(FSChar)* namez, size_t upTo = size_t.max) @trusted
{
    import core.memory : GC;
    import std.algorithm.comparison : min;
    import std.array : uninitializedArray;
    import std.conv : to;

    // 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 = uninitializedArray!(ubyte[])(initialAlloc);
    scope(failure) GC.free(result.ptr);
    size_t size = 0;

    for (;;)
    {
        immutable actual = core.sys.posix.unistd.read(fd, result.ptr + size,
                min(result.length, upTo) - size);
        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, GC.BlkAttr.NO_SCAN)[0 .. newAlloc];
    }

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


version (Windows) private void[] readImpl(const(char)[] name, const(FSChar)* namez, size_t upTo = size_t.max) @safe
{
    import core.memory : GC;
    import std.algorithm.comparison : min;
    import std.array : uninitializedArray;
    static trustedCreateFileW(const(wchar)* namez, DWORD dwDesiredAccess, DWORD dwShareMode,
                              SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition,
                              DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) @trusted
    {
        return CreateFileW(namez, dwDesiredAccess, dwShareMode,
                           lpSecurityAttributes, dwCreationDisposition,
                           dwFlagsAndAttributes, hTemplateFile);

    }
    static trustedCloseHandle(HANDLE hObject) @trusted
    {
        return CloseHandle(hObject);
    }
    static trustedGetFileSize(HANDLE hFile, out ulong fileSize) @trusted
    {
        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, ulong nNumberOfBytesToRead) @trusted
    {
        // Read by chunks of size < 4GB (Windows API limit)
        ulong 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 = uninitializedArray!(ubyte[])(size);

    scope(failure)
    {
        () @trusted { 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/sys/kernel/osrelease");
    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");
}

/********************************************
Read and validates (using $(REF validate, std,utf)) a text file. $(D S)
can be a type of array of characters of any width and constancy. No
width conversion is performed; if the width of the characters in file
$(D name) is different from the width of elements of $(D S),
validation will fail.

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

Returns: Array of characters read.

Throws: $(D FileException) on file error, $(D UTFException) on UTF
decoding error.
 */

S readText(S = string, R)(R name)
if (isSomeString!S &&
    (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
    !isConvertibleToString!R)
{
    import std.utf : validate;
    static auto trustedCast(void[] buf) @trusted { return cast(S) buf; }
    auto result = trustedCast(read(name));
    validate(result);
    return result;
}

///
@safe unittest
{
    import std.exception : enforce;
    write(deleteme, "abc"); // deleteme is the name of a temporary file
    scope(exit) remove(deleteme);
    string content = readText(deleteme);
    enforce(content == "abc");
}

/// ditto
S readText(S = string, R)(auto ref R name)
if (isConvertibleToString!R)
{
    return readText!(S, StringTypeOf!R)(name);
}

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

/*********************************************
Write $(D buffer) to file $(D 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: $(D FileException) on error.

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

///
@system 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
   assert(cast(int[]) read(deleteme) == 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 $(D buffer) to file $(D 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: $(D FileException) on error.
 */
void append(R)(R name, const void[] buffer)
if ((isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isSomeString!R) &&
    !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))
        writeImpl(name, name.tempCString!FSChar(), buffer, true);
    else
        writeImpl(null, name.tempCString!FSChar(), buffer, true);
}

///
@system 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);
   assert(cast(int[]) read(deleteme) == 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(const(char)[] name, const(FSChar)* namez,
        in 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(const(char)[] name, const(FSChar)* namez,
        in 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 $(D from) _to $(D to).
 * 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
 * Throws: $(D FileException) on error.
 */
void rename(RF, RT)(RF from, RT to)
if ((isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) || isSomeString!RF)
    && !isConvertibleToString!RF &&
    (isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!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(Unqual!(ElementEncodingType!RF) == char))
        alias f = from;
    else
        enum string f = null;

    static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == 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)));
}

private void renameImpl(const(char)[] f, const(char)[] t, const(FSChar)* fromz, 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 = to!(typeof(f))(fromz[0 .. wcslen(fromz)]);

            if (!t)
                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);

            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 $(D name).

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

Throws: $(D FileException) on error.
 */
void remove(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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
{
    static assert(__traits(compiles, remove(TestAliasedString("foo"))));
}

private void removeImpl(const(char)[] name, 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 = strlen(namez);
            name = namez[0 .. len];
        }
        cenforce(core.stdc.stdio.remove(namez) == 0,
            "Failed to remove file " ~ name);
    }
}

version (Windows) private WIN32_FILE_ATTRIBUTE_DATA getFileAttributesWin(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R))
{
    auto namez = name.tempCString!FSChar();

    WIN32_FILE_ATTRIBUTE_DATA fad = void;

    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))
    {
        static void getFA(const(char)[] name, 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(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;
}

/***************************************************
Get size of file $(D name) in bytes.

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

Throws: $(D FileException) on error (e.g., file not found).
 */
ulong getSize(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    version (Windows)
    {
        with (getFileAttributesWin(name))
            return makeUlong(nFileSizeLow, nFileSizeHigh);
    }
    else version (Posix)
    {
        auto namez = name.tempCString();

        static trustedStat(const(FSChar)* namez, out stat_t buf) @trusted
        {
            return stat(namez, &buf);
        }
        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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
{
    // create a file of size 1
    write(deleteme, "a");
    scope(exit) { assert(exists(deleteme)); remove(deleteme); }
    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 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 $(D 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:
        $(D FileException) on error.
 +/
void getTimes(R)(R name,
              out SysTime accessTime,
              out SysTime modificationTime)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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();

        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted
        {
            return stat(namez, &buf);
        }
        stat_t statbuf = void;

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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
{
    SysTime atime, mtime;
    static assert(__traits(compiles, getTimes(TestAliasedString("foo"), atime, mtime)));
}

@system unittest
{
    import std.stdio : writefln;

    auto currTime = Clock.currTime();

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

    SysTime accessTime1 = void;
    SysTime modificationTime1 = void;

    getTimes(deleteme, accessTime1, modificationTime1);

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

    {
        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 $(D name).

     This is the same as $(D 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:
     $(D FileException) on error.
     +/
    void getTimesWin(R)(R name,
                        out SysTime fileCreationTime,
                        out SysTime fileAccessTime,
                        out SysTime fileModificationTime)
    if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
        !isConvertibleToString!R);
}
else version (Windows)
{
    void getTimesWin(R)(R name,
                        out SysTime fileCreationTime,
                        out SysTime fileAccessTime,
                        out SysTime fileModificationTime)
    if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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)));
    }
}


/++
    Set access/modified times of file or folder $(D 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:
        $(D FileException) on error.
 +/
void setTimes(R)(R name,
              SysTime accessTime,
              SysTime modificationTime)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    version (Windows)
    {
        import std.datetime.systime : SysTimeToFILETIME;

        auto namez = name.tempCString!FSChar();
        static auto trustedCreateFileW(const(FSChar)* namez, DWORD dwDesiredAccess, DWORD dwShareMode,
                                       SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition,
                                       DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) @trusted
        {
            return CreateFileW(namez, dwDesiredAccess, dwShareMode,
                               lpSecurityAttributes, dwCreationDisposition,
                               dwFlagsAndAttributes, hTemplateFile);

        }
        static auto trustedCloseHandle(HANDLE hObject) @trusted
        {
            return CloseHandle(hObject);
        }
        static auto trustedSetFileTime(HANDLE hFile, in FILETIME *lpCreationTime,
                                       in ref FILETIME lpLastAccessTime, in ref FILETIME lpLastWriteTime) @trusted
        {
            return SetFileTime(hFile, lpCreationTime, &lpLastAccessTime, &lpLastWriteTime);
        }

        const ta = SysTimeToFILETIME(accessTime);
        const tm = SysTimeToFILETIME(modificationTime);
        alias defaults =
            AliasSeq!(GENERIC_WRITE,
                      0,
                      null,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL |
                      FILE_ATTRIBUTE_DIRECTORY |
                      FILE_FLAG_BACKUP_SEMANTICS,
                      HANDLE.init);
        auto h = trustedCreateFileW(namez, defaults);

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))
            alias names = name;
        else
            string names = null;
        cenforce(h != INVALID_HANDLE_VALUE, names, namez);

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

        cenforce(trustedSetFileTime(h, null, ta, tm), names, namez);
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        static if (is(typeof(&utimensat)))
        {
            static auto trustedUtimensat(int fd, const(FSChar)* namez, const ref timespec[2] times, int flags) @trusted
            {
                return utimensat(fd, namez, times, flags);
            }
            timespec[2] t = void;

            t[0] = accessTime.toTimeSpec();
            t[1] = modificationTime.toTimeSpec();

            static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))
                alias names = name;
            else
                string names = null;
            cenforce(trustedUtimensat(AT_FDCWD, namez, t, 0) == 0, names, namez);
        }
        else
        {
            static auto trustedUtimes(const(FSChar)* namez, const ref timeval[2] times) @trusted
            {
                return utimes(namez, times);
            }
            timeval[2] t = void;

            t[0] = accessTime.toTimeVal();
            t[1] = modificationTime.toTimeVal();

            static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == char))
                alias names = name;
            else
                string names = null;
            cenforce(trustedUtimes(namez, t) == 0, names, namez);
        }
    }
}

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

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

@system 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);
}

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

    Throws:
        $(D FileException) if the given file does not exist.
+/
SysTime timeLastModified(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    version (Windows)
    {
        SysTime dummy;
        SysTime ftm;

        getTimesWin(name, dummy, dummy, ftm);

        return ftm;
    }
    else version (Posix)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted
        {
            return stat(namez, &buf);
        }
        stat_t statbuf = void;

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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
{
    static assert(__traits(compiles, timeLastModified(TestAliasedString("foo"))));
}

/++
    Returns the time that the given file was last modified. If the
    file does not exist, returns $(D 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 $(D source) (i.e., $(D target) is
    older than $(D source) or does not exist), use the comparison
    below. The code throws a $(D FileException) if $(D source) does not
    exist (as it should). On the other hand, the $(D SysTime.min) default
    makes a non-existing $(D 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.

Example:
--------------------
if (timeLastModified(source) >= timeLastModified(target, SysTime.min))
{
    // must (re)build
}
else
{
    // target is up-to-date
}
--------------------
+/
SysTime timeLastModified(R)(R name, SysTime returnIfMissing)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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();
        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted
        {
            return stat(namez, &buf);
        }
        stat_t statbuf = void;

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

@safe unittest
{
    //std.process.system("echo a > deleteme") == 0 || assert(false);
    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.
version (FreeBSD) {} else
version (DragonFlyBSD) {} else
version (OSX) {} else
@system 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;
        Thread.sleep(10.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 (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    return existsImpl(name.tempCString!FSChar());
}

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

private bool existsImpl(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(!exists("this file does not exist"));
    write(deleteme, "a\n");
    scope(exit) { assert(exists(deleteme)); remove(deleteme); }
    assert(exists(deleteme));
}

@safe unittest // Bugzilla 16573
{
    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 $(LUCKY
 st_mode) value which is part of the $(D stat struct) gotten by
 calling the $(HTTP en.wikipedia.org/wiki/Stat_%28Unix%29, $(D 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.

 Throws: $(D FileException) on error.
  +/
uint getAttributes(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    version (Windows)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted
        {
            return GetFileAttributesW(namez);
        }
        immutable result = trustedGetFileAttributesW(namez);

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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();
        static auto trustedStat(const(FSChar)* namez, ref stat_t buf) @trusted
        {
            return stat(namez, &buf);
        }
        stat_t statbuf = void;

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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);
}

@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:
        $(D FileException) on error.
 +/
uint getLinkAttributes(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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(Unqual!(ElementEncodingType!R) == 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
{
    static assert(__traits(compiles, getLinkAttributes(TestAliasedString(null))));
}

/++
    Set the _attributes of the given file.

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

    Throws:
        $(D FileException) if the given file does not exist.
 +/
void setAttributes(R)(R name, uint attributes)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    version (Windows)
    {
        auto namez = name.tempCString!FSChar();
        static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted
        {
            return SetFileAttributesW(namez, dwFileAttributes);
        }
        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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(const(FSChar)* namez, mode_t mode) @trusted
        {
            return chmod(namez, mode);
        }
        assert(attributes <= mode_t.max);
        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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)));
}

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

    Params:
        name = The path to the file.

    Returns:
        true if name specifies a directory

    Throws:
        $(D FileException) if the given file does not exist.

Example:
--------------------
assert(!"/etc/fonts/fonts.conf".isDir);
assert("/usr/share/include".isDir);
--------------------
  +/
@property bool isDir(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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
{
    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);
    }
}

@system 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

Example:
--------------------
assert(!attrIsDir(getAttributes("/etc/fonts/fonts.conf")));
assert(!attrIsDir(getLinkAttributes("/etc/fonts/fonts.conf")));
--------------------
  +/
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
{
    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 $(D isFile) or $(D isDir) will return true for any given file.

    On Posix systems, if $(D isFile) is $(D 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 $(D isFile) and $(D isDir) to be $(D false) for a
    particular file (in which case, it's a special file). You can use
    $(D getAttributes) to get the attributes to figure out what type of special
    it is, or you can use $(D DirEntry) to get at its $(D statBuf), which is the
    result from $(D stat). In either case, see the man page for $(D stat) for
    more information.

    Params:
        name = The path to the file.

    Returns:
        true if name specifies a file

    Throws:
        $(D FileException) if the given file does not exist.

Example:
--------------------
assert("/etc/fonts/fonts.conf".isFile);
assert(!"/usr/share/include".isFile);
--------------------
  +/
@property bool isFile(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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);
}

@system unittest // bugzilla 15658
{
    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
    $(D attrIsFile) or $(D attrIsDir) will return $(D true) for the
    _attributes of any given file.

    On Posix systems, if $(D attrIsFile) is $(D 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 $(D attrIsFile) and $(D attrIsDir) to be $(D 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 $(D 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
{
    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 $(D 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:
        $(D FileException) if the given file does not exist.
  +/
@property bool isSymlink(R)(R name)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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));
}

@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 $(D 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;
}


/****************************************************
 * Change directory to $(D pathname).
 * Throws: $(D FileException) on error.
 */
void chdir(R)(R pathname)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
    !isConvertibleToString!R)
{
    // Place outside of @trusted block
    auto pathz = pathname.tempCString!FSChar();

    version (Windows)
    {
        static auto trustedChdir(const(FSChar)* pathz) @trusted
        {
            return SetCurrentDirectoryW(pathz);
        }
    }
    else version (Posix)
    {
        static auto trustedChdir(const(FSChar)* pathz) @trusted
        {
            return core.sys.posix.unistd.chdir(pathz) == 0;
        }
    }
    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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);
}

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

/****************************************************
Make directory $(D pathname).

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

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

        static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted
        {
            return core.sys.posix.sys.stat.mkdir(pathz, mode);
        }
        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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.path : mkdir;
    static assert(__traits(compiles, mkdir(TestAliasedString(null))));
}

// Same as mkdir but ignores "already exists" errors.
// Returns: "true" if the directory was created,
//   "false" if it already existed.
private bool ensureDirExists()(in 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
 * $(D pathname) already exists.
 *
 * Throws: $(D FileException) on error.
 */

void mkdirRecurse(in 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.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`));
    }

    // bug3570
    {
        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 $(D pathname).

Params:
    pathname = Range or string specifying the directory name

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

    version (Windows)
    {
        static auto trustedRmdir(const(FSChar)* pathz) @trusted
        {
            return RemoveDirectoryW(pathz);
        }
    }
    else version (Posix)
    {
        static auto trustedRmdir(const(FSChar)* pathz) @trusted
        {
            return core.sys.posix.unistd.rmdir(pathz) == 0;
        }
    }
    static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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))));
}

/++
    $(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:
        $(D FileException) on error (which includes if the _symlink already
        exists).
  +/
version (StdDdoc) void symlink(RO, RL)(RO original, RL link)
if ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||
    isConvertibleToString!RO) &&
    (isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!RL) ||
    isConvertibleToString!RL));
else version (Posix) void symlink(RO, RL)(RO original, RL link)
if ((isInputRange!RO && !isInfinite!RO && isSomeChar!(ElementEncodingType!RO) ||
    isConvertibleToString!RO) &&
    (isInputRange!RL && !isInfinite!RL && isSomeChar!(ElementEncodingType!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:
        $(D FileException) on error.
  +/
version (StdDdoc) string readLink(R)(R link)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) ||
    isConvertibleToString!R);
else version (Posix) string readLink(R)(R link)
if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!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!dchar 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: $(D FileException) on error.
 */
version (Windows) string getcwd()
{
    import std.conv : to;
    /* 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.
    */
    wchar[4096] buffW = void; //enough for most common case
    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 ptr = cast(wchar*) malloc(wchar.sizeof * n);
        scope(exit) free(ptr);
        immutable n2 = GetCurrentDirectoryW(n, ptr);
        cenforce(n2 && n2 < n, "getcwd");
        return ptr[0 .. n2].to!string;
    }
}
else version (Solaris) string getcwd()
{
    /* 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()
{
    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;
}

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

version (OSX)
    private extern (C) int _NSGetExecutablePath(char* buf, uint* bufsize);
else version (FreeBSD)
    private extern (C) int sysctl (const int* name, uint namelen, void* oldp,
        size_t* oldlenp, const void* newp, size_t newlen);
else version (NetBSD)
    private extern (C) int sysctl (const int* name, uint namelen, void* oldp,
        size_t* oldlenp, const void* newp, size_t newlen);

/**
 * Returns the full path of the current executable.
 *
 * Throws:
 * $(REF1 Exception, object)
 */
@trusted string thisExePath ()
{
    version (OSX)
    {
        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);
            enforce(len, sysErrorString(GetLastError()));
            if (len != buffer.length)
                return to!(string)(buffer[0 .. len]);
            buffer.length *= 2;
        }
    }
    else version (FreeBSD)
    {
        import std.exception : errnoEnforce, assumeUnique;
        enum
        {
            CTL_KERN = 1,
            KERN_PROC = 14,
            KERN_PROC_PATHNAME = 12
        }

        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)
    {
        return readLink("/proc/self/exe");
    }
    else version (DragonFlyBSD)
    {
        return readLink("/proc/curproc/file");
    }
    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
        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
    {
        /++
            Constructs a $(D DirEntry) for the given file (or directory).

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

            Throws:
                $(D FileException) if the file does not exist.
        +/
        this(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 $(D 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;


        /++
            Returns whether the file represented by this $(D 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();


        /++
            Returns whether the file represented by this $(D DirEntry) is a file.

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

            On Posix systems, if $(D isFile) is $(D 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 $(D isFile) and $(D isDir) to
            be $(D false) for a particular file (in which case, it's a special
            file). You can use $(D attributes) or $(D 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();

        /++
            Returns whether the file represented by this $(D DirEntry) is a
            symbolic link.

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

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

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

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

        /++
            Returns the time that the file represented by this $(D 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
            $(D timeLastAccessed) will return the same value as
            $(D timeLastModified).
          +/
        @property SysTime timeLastAccessed();

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

        /++
            Returns the _attributes of the file represented by this $(D DirEntry).

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

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

        /++
            On Posix systems, if the file represented by this $(D DirEntry) is a
            symbolic link, then $(D linkAttributes) are the attributes of the
            symbolic link itself. Otherwise, $(D linkAttributes) is identical to
            $(D attributes).

            On Windows, $(D linkAttributes) is identical to $(D 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();

        version (Windows)
            alias stat_t = void*;

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

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

        this(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, in WIN32_FIND_DATAW *fd)
        {
            import core.stdc.wchar_ : wcslen;
            import std.conv : to;
            import std.datetime.systime : FILETIMEToSysTime;
            import std.path : buildPath;

            size_t clength = wcslen(fd.cFileName.ptr);
            _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 _name;
        }

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

        @property bool isFile() const pure nothrow
        {
            //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
        {
            return (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
        }

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

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

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

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

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

        @property uint linkAttributes() const pure nothrow
        {
            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
    {
    public:
        alias name this;

        this(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)
        {
            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 _name;
        }

        @property bool isDir()
        {
            _ensureStatOrLStatDone();

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

        @property bool isFile()
        {
            _ensureStatOrLStatDone();

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

        @property bool isSymlink()
        {
            _ensureLStatDone();

            return (_lstatMode & S_IFMT) == S_IFLNK;
        }

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

        @property SysTime timeStatusChanged()
        {
            _ensureStatDone();

            return statTimeToStdTime!'c'(_statBuf);
        }

        @property SysTime timeLastAccessed()
        {
            _ensureStatDone();

            return statTimeToStdTime!'a'(_statBuf);
        }

        @property SysTime timeLastModified()
        {
            _ensureStatDone();

            return statTimeToStdTime!'m'(_statBuf);
        }

        @property uint attributes()
        {
            _ensureStatDone();

            return _statBuf.st_mode;
        }

        @property uint linkAttributes()
        {
            _ensureLStatDone();

            return _lstatMode;
        }

        @property stat_t statBuf()
        {
            _ensureStatDone();

            return _statBuf;
        }

    private:
        /++
            This is to support lazy evaluation, because doing stat's is
            expensive and not always needed.
         +/
        void _ensureStatDone() @safe
        {
            import std.exception : enforce;

            static auto trustedStat(in char[] path, stat_t* buf) @trusted
            {
                return stat(path.tempCString(), buf);
            }
            if (_didStat)
                return;

            enforce(trustedStat(_name, &_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()
        {
            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()
        {
            import std.exception : enforce;

            if (_didLStat)
                return;

            stat_t statbuf = void;

            enforce(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);

            {
                //Issue 8298
                DirEntry de = DirEntry(symfile);

                assert(!de.isFile);
                assert(!de.isDir);
                assert(de.isSymlink);
                assertThrown(de.size);
                assertThrown(de.timeStatusChanged);
                assertThrown(de.timeLastAccessed);
                assertThrown(de.timeLastModified);
                assertThrown(de.attributes);
                assertThrown(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 $(D 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 $(D from) _to file $(D to). File timestamps are preserved.
File attributes are preserved, if $(D preserve) equals $(D Yes.preserveAttributes).
On Windows only $(D 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: $(D FileException) on error.
 */
void copy(RF, RT)(RF from, RT to, PreserveAttributes preserve = preserveAttributesDefault)
if (isInputRange!RF && !isInfinite!RF && isSomeChar!(ElementEncodingType!RF) && !isConvertibleToString!RF &&
    isInputRange!RT && !isInfinite!RT && isSomeChar!(ElementEncodingType!RT) && !isConvertibleToString!RT)
{
    // Place outside of @trusted block
    auto fromz = from.tempCString!FSChar();
    auto toz = to.tempCString!FSChar();

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

    static if (isNarrowString!RT && is(Unqual!(ElementEncodingType!RT) == 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 // issue 15319
{
    assert(__traits(compiles, copy("from.txt", "to.txt")));
}

private void copyImpl(const(char)[] f, const(char)[] t, const(FSChar)* fromz, 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;

            if (!t)
                t = to!(typeof(t))(toz[0 .. wcslen(toz)]);

            throw new FileException(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);

        utimbuf utim = void;
        utim.actime = cast(time_t) statbufr.st_atime;
        utim.modtime = cast(time_t) statbufr.st_mtime;

        cenforce(utime(toz, &utim) != -1, f, fromz);
    }
}

@safe unittest
{
    import std.algorithm, std.file; // issue 14817
    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");
}

@safe version (Posix) @safe unittest //issue 11434
{
    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);
}

@safe unittest // issue 15865
{
    import std.exception : assertThrown;
    auto t = deleteme;
    write(t, "a");
    scope(exit) t.remove();
    assertThrown!FileException(copy(t, t));
    assert(readText(t) == "a");
}

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

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

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

    Throws:
        $(D FileException) if there is an error (including if the given
        file is not a directory).
 +/
void rmdirRecurse(ref DirEntry de)
{
    if (!de.isDir)
        throw new FileException(de.name, "Not a directory");

    if (de.isSymlink)
    {
        version (Windows)
            rmdir(de.name);
        else
            remove(de.name);
    }
    else
    {
        // 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(DirEntry de)
{
    rmdirRecurse(de);
}

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;
    import std.process : executeShell;
    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);
    version (Android) string link_cmd = "ln -s ";
    else string link_cmd = "ln -sf ";
    executeShell(link_cmd~deleteme~"/a/b/c "~deleteme~"/link");
    rmdirRecurse(deleteme);
    enforce(!exists(deleteme));
}

@system unittest
{
    void[] buf;

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

    string unit2_file = deleteme ~ "-unittest_write2.tmp";
    copy(unit_file, unit2_file);
    buf2 = read(unit2_file);
    assert(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 $(D 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,
}

private struct DirIteratorImpl
{
    import std.array : Appender, appender;
    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;
    Appender!(DirHandle[]) _stack;
    Appender!(DirEntry[]) _stashed; //used in depth first mode
    //stack helpers
    void pushExtra(DirEntry de){ _stashed.put(de); }
    //ditto
    bool hasExtra(){ return !_stashed.data.empty; }
    //ditto
    DirEntry popExtra()
    {
        DirEntry de;
        de = _stashed.data[$-1];
        _stashed.shrinkTo(_stashed.data.length - 1);
        return de;

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

        bool stepIn(string directory)
        {
            import std.path : chainPath;

            auto search_pattern = chainPath(directory, "*.*");
            WIN32_FIND_DATAW findinfo;
            HANDLE h = FindFirstFileW(search_pattern.tempCString!FSChar(), &findinfo);
            cenforce(h != INVALID_HANDLE_VALUE, directory);
            _stack.put(DirHandle(directory, h));
            return toNext(false, &findinfo);
        }

        bool next()
        {
            if (_stack.data.empty)
                return false;
            WIN32_FIND_DATAW findinfo;
            return toNext(true, &findinfo);
        }

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

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

        void popDirStack()
        {
            assert(!_stack.data.empty);
            FindClose(_stack.data[$-1].h);
            _stack.shrinkTo(_stack.data.length-1);
        }

        void releaseDirStack()
        {
            foreach ( d;  _stack.data)
                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)
        {
            auto h = directory.length ? opendir(directory.tempCString()) : opendir(".");
            cenforce(h, directory);
            _stack.put(DirHandle(directory, h));
            return next();
        }

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

        void popDirStack()
        {
            assert(!_stack.data.empty);
            closedir(_stack.data[$-1].h);
            _stack.shrinkTo(_stack.data.length-1);
        }

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

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

    this(R)(R pathname, SpanMode mode, bool followSymlink)
        if (isInputRange!R && isSomeChar!(ElementEncodingType!R))
    {
        _mode = mode;
        _followSymlink = followSymlink;
        _stack = appender(cast(DirHandle[])[]);
        if (_mode == SpanMode.depth)
            _stashed = appender(cast(DirEntry[])[]);

        static if (isNarrowString!R && is(Unqual!(ElementEncodingType!R) == 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.data.empty && _stack.data.empty; }
    @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();
    }
}

struct DirIterator
{
private:
    RefCounted!(DirIteratorImpl, RefCountedAutoInitialize.no) impl;
    this(string pathname, SpanMode mode, bool followSymlink)
    {
        impl = typeof(impl)(pathname, mode, followSymlink);
    }
public:
    @property bool empty(){ return impl.empty; }
    @property DirEntry front(){ return impl.front; }
    void popFront(){ impl.popFront(); }

}
/++
    Returns an input range of $(D DirEntry) that lazily iterates a given directory,
    also provides two ways of foreach iteration. The iteration variable can be of
    type $(D string) if only the name is needed, or $(D 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 _path.

    Params:
        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 port-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.

    Throws:
        $(D FileException) if the directory does not exist.

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.system(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);
--------------------
 +/
auto dirEntries(string path, SpanMode mode, bool followSymlink = true)
{
    return DirIterator(path, mode, followSymlink);
}

/// Duplicate functionality of D1's $(D std.file.listdir()):
@safe unittest
{
    string[] listdir(string pathname)
    {
        import std.algorithm;
        import std.array;
        import std.file;
        import std.path;

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

    void main(string[] args)
    {
        import std.stdio;

        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 : dirEntries, buildPath, absolutePath;
    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 = "deleteme.dmd.unittest.std.file" ~ to!string(thisProcessID); // needs to be relative
    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!(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);
    }

    //issue 7264
    foreach (string name; dirEntries(testdir, "*.d", SpanMode.breadth))
    {

    }
    foreach (entry; dirEntries(testdir, SpanMode.breadth))
    {
        static assert(is(typeof(entry) == DirEntry));
    }
    //issue 7138
    auto a = array(dirEntries(testdir, SpanMode.shallow));

    // issue 11392
    auto dFiles = dirEntries(testdir, SpanMode.shallow);
    foreach (d; dFiles){}

    // issue 15146
    dirEntries("", SpanMode.shallow).walkLength();
}

/// Ditto
auto dirEntries(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(path, mode, followSymlink));
}

@system 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)
    {
        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);
        }
    }
}


/**
 * 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, in char[] format)
{
    import std.array : appender;
    import std.conv : text;
    import std.exception : enforce;
    import std.format : formattedRead;
    import std.stdio : File;

    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.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));
}


/**
Returns the path to a directory for temporary files.

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, $(D 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 $(D TMPDIR) environment variable.)
    $(LI The directory given by the $(D TEMP) environment variable.)
    $(LI The directory given by the $(D TMP) environment variable.)
    $(LI $(D /tmp))
    $(LI $(D /var/tmp))
    $(LI $(D /usr/tmp))
)

On all platforms, $(D tempDir) returns $(D ".") on failure, representing
the current working directory.

The return value of the function is cached, so the procedures described
above 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 $(D tempDir) algorithm is inspired by Python's
$(LINK2 http://docs.python.org/library/tempfile.html#tempfile.tempdir, $(D tempfile.tempdir)).
*/
string tempDir() @trusted
{
    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 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 = getcwd();
    }
    return cache;
}
