//  operations.cpp  --------------------------------------------------------------------//

//  Copyright 2002-2009 Beman Dawes
//  Copyright 2001 Dietmar Kuehl

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  See library home page at http://www.boost.org/libs/filesystem

//--------------------------------------------------------------------------------------// 

#include <boost/config.hpp>
#if !defined( BOOST_NO_STD_WSTRING )
// Boost.Filesystem V3 and later requires std::wstring support.
// During the transition to V3, libraries are compiled with both V2 and V3 sources.
// On old compilers that don't support V3 anyhow, we just skip everything so the compile
// will succeed and the library can be built.

// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)

#define BOOST_FILESYSTEM_SOURCE 

#ifndef BOOST_SYSTEM_NO_DEPRECATED 
# define BOOST_SYSTEM_NO_DEPRECATED
#endif

#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS  // Sun readdir_r()needs this
#endif

#if !(defined(__HP_aCC) && defined(_ILP32) && \
      !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
#endif
#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
      // 64-bit systems or on 32-bit systems which don't have files larger 
      // than can be represented by a traditional POSIX/UNIX off_t type. 
      // OTOH, defining them should kick in 64-bit off_t's (and thus 
      // st_size)on 32-bit systems that provide the Large File
      // Support (LFS)interface, such as Linux, Solaris, and IRIX.
      // The defines are given before any headers are included to
      // ensure that they are available to all included headers.
      // That is required at least on Solaris, and possibly on other
      // systems as well.

#include <boost/filesystem/v3/operations.hpp>
#include <boost/scoped_array.hpp>
#include <boost/detail/workaround.hpp>
#include <cstdlib>  // for malloc, free

#ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM
# include <iostream>
#endif

namespace fs = boost::filesystem3;
using boost::filesystem3::path;
using boost::filesystem3::filesystem_error;
using boost::system::error_code;
using boost::system::error_category;
using boost::system::system_category;
using std::string;
using std::wstring;

# ifdef BOOST_POSIX_API

#   include <sys/types.h>
#   if !defined(__APPLE__) && !defined(__OpenBSD__)
#     include <sys/statvfs.h>
#     define BOOST_STATVFS statvfs
#     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
#   else
#     ifdef __OpenBSD__
#     include <sys/param.h>
#     endif
#     include <sys/mount.h>
#     define BOOST_STATVFS statfs
#     define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>(vfs.f_bsize)
#   endif
#   include <dirent.h>
#   include <unistd.h>
#   include <fcntl.h>
#   include <utime.h>
#   include "limits.h"

# else // BOOST_WINDOW_API

#   if (defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(WINVER)
      // Versions of MinGW or Cygwin that support Filesystem V3 support at least WINVER 0x501.
      // See MinGW's windef.h
#     define WINVER 0x501
#   endif
#   include <windows.h>
#   include <winnt.h>
#   if !defined(_WIN32_WINNT)
#     define  _WIN32_WINNT   0x0500
#   endif
#   if defined(__BORLANDC__) || defined(__MWERKS__)
#     if defined(__BORLANDC__)
        using std::time_t;
#     endif
#     include <utime.h>
#   else
#     include <sys/utime.h>
#   endif

//  REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part of the 
//  Windows Device Driver Kit. Since that's inconvenient, the definitions are provided
//  here. See http://msdn.microsoft.com/en-us/library/ms791514.aspx

#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE)  // mingw winnt.h does provide the defs

#define SYMLINK_FLAG_RELATIVE 1

typedef struct _REPARSE_DATA_BUFFER {
  ULONG  ReparseTag;
  USHORT  ReparseDataLength;
  USHORT  Reserved;
  union {
    struct {
      USHORT  SubstituteNameOffset;
      USHORT  SubstituteNameLength;
      USHORT  PrintNameOffset;
      USHORT  PrintNameLength;
      ULONG  Flags;
      WCHAR  PathBuffer[1];
  /*  Example of distinction between substitute and print names:
        mklink /d ldrive c:\
        SubstituteName: c:\\??\
        PrintName: c:\
  */
     } SymbolicLinkReparseBuffer;
    struct {
      USHORT  SubstituteNameOffset;
      USHORT  SubstituteNameLength;
      USHORT  PrintNameOffset;
      USHORT  PrintNameLength;
      WCHAR  PathBuffer[1];
      } MountPointReparseBuffer;
    struct {
      UCHAR  DataBuffer[1];
    } GenericReparseBuffer;
  };
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;

#define REPARSE_DATA_BUFFER_HEADER_SIZE \
  FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)

#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE  ( 16 * 1024 )
#endif

# ifndef FSCTL_GET_REPARSE_POINT
#   define FSCTL_GET_REPARSE_POINT 0x900a8
# endif

# ifndef IO_REPARSE_TAG_SYMLINK
#   define IO_REPARSE_TAG_SYMLINK (0xA000000CL)       
# endif

# endif  // BOOST_WINDOWS_API

//  BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
//  dir_itr_increment. The config tests are placed here because some of the
//  macros being tested come from dirent.h.
//
// TODO: find out what macros indicate dirent::d_type present in more libraries
# if defined(BOOST_WINDOWS_API)\
  || defined(_DIRENT_HAVE_D_TYPE)// defined by GNU C library if d_type present
#   define BOOST_FILESYSTEM_STATUS_CACHE
# endif

#include <sys/stat.h>  // even on Windows some functions use stat()
#include <string>
#include <cstring>
#include <cstdio>      // for remove, rename
#include <cerrno>
#include <cassert>
// #include <iostream>    // for debugging only; comment out when not in use

//  POSIX/Windows macros  ----------------------------------------------------//

//  Portions of the POSIX and Windows API's are very similar, except for name,
//  order of arguments, and meaning of zero/non-zero returns. The macros below
//  abstract away those differences. They follow Windows naming and order of
//  arguments, and return true to indicate no error occurred. [POSIX naming,
//  order of arguments, and meaning of return were followed initially, but
//  found to be less clear and cause more coding errors.]

# if defined(BOOST_POSIX_API)

//  POSIX uses a 0 return to indicate success
#   define BOOST_ERRNO    errno 
#   define BOOST_SET_CURRENT_DIRECTORY(P)(::chdir(P)== 0)
#   define BOOST_CREATE_DIRECTORY(P)(::mkdir(P, S_IRWXU|S_IRWXG|S_IRWXO)== 0)
#   define BOOST_CREATE_HARD_LINK(F,T)(::link(T, F)== 0)
#   define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(::symlink(T, F)== 0)
#   define BOOST_REMOVE_DIRECTORY(P)(::rmdir(P)== 0)
#   define BOOST_DELETE_FILE(P)(::unlink(P)== 0)
#   define BOOST_COPY_DIRECTORY(F,T)(!(::stat(from.c_str(), &from_stat)!= 0\
         || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
#   define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
#   define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
#   define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)

#   define BOOST_ERROR_NOT_SUPPORTED ENOSYS
#   define BOOST_ERROR_ALREADY_EXISTS EEXIST

# else  // BOOST_WINDOWS_API

//  Windows uses a non-0 return to indicate success
#   define BOOST_ERRNO    ::GetLastError()
#   define BOOST_SET_CURRENT_DIRECTORY(P)(::SetCurrentDirectoryW(P)!= 0)
#   define BOOST_CREATE_DIRECTORY(P)(::CreateDirectoryW(P, 0)!= 0)
#   define BOOST_CREATE_HARD_LINK(F,T)(create_hard_link_api(F, T, 0)!= 0)
#   define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(create_symbolic_link_api(F, T, Flag)!= 0)
#   define BOOST_REMOVE_DIRECTORY(P)(::RemoveDirectoryW(P)!= 0)
#   define BOOST_DELETE_FILE(P)(::DeleteFileW(P)!= 0)
#   define BOOST_COPY_DIRECTORY(F,T)(::CreateDirectoryExW(F, T, 0)!= 0)
#   define BOOST_COPY_FILE(F,T,FailIfExistsBool)(::CopyFileW(F, T, FailIfExistsBool)!= 0)
#   define BOOST_MOVE_FILE(OLD,NEW)(::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING)!= 0)
#   define BOOST_RESIZE_FILE(P,SZ)(resize_file_api(P, SZ)!= 0)
#   define BOOST_READ_SYMLINK(P,T)

#   define BOOST_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS
#   define BOOST_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED

# endif

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                        helpers (all operating systems)                              //
//                                                                                      //
//--------------------------------------------------------------------------------------//

namespace
{

# ifdef BOOST_POSIX_API
  const char dot = '.';
# else
  const wchar_t dot = L'.';
# endif

  fs::file_type query_file_type(const path& p, error_code* ec);

  boost::filesystem3::directory_iterator end_dir_itr;

  const std::size_t buf_size(128);
  const error_code ok;

  bool error(bool was_error, error_code* ec, const string& message)
  {
    if (!was_error)
    {
      if (ec != 0) ec->clear();
    }
    else  
    { //  error
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(message,
          error_code(BOOST_ERRNO, system_category())));
      else
        ec->assign(BOOST_ERRNO, system_category());
    }
    return was_error;
  }

  bool error(bool was_error, const path& p, error_code* ec, const string& message)
  {
    if (!was_error)
    {
      if (ec != 0) ec->clear();
    }
    else  
    { //  error
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(message,
          p, error_code(BOOST_ERRNO, system_category())));
      else
        ec->assign(BOOST_ERRNO, system_category());
    }
    return was_error;
  }

  bool error(bool was_error, const path& p1, const path& p2, error_code* ec,
    const string& message)
  {
    if (!was_error)
    {
      if (ec != 0) ec->clear();
    }
    else  
    { //  error
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(message,
          p1, p2, error_code(BOOST_ERRNO, system_category())));
      else
        ec->assign(BOOST_ERRNO, system_category());
    }
    return was_error;
  }

  bool error(bool was_error, const error_code& result,
    const path& p, error_code* ec, const string& message)
    //  Overwrites ec if there has already been an error
  {
    if (!was_error)
    {
      if (ec != 0) ec->clear();
    }
    else  
    { //  error
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(message, p, result));
      else
        *ec = result;
    }
    return was_error;
  }

  bool error(bool was_error, const error_code& result,
    const path& p1, const path& p2, error_code* ec, const string& message)
    //  Overwrites ec if there has already been an error
  {
    if (!was_error)
    {
      if (ec != 0) ec->clear();
    }
    else  
    { //  error
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(message, p1, p2, result));
      else
        *ec = result;
    }
    return was_error;
  }

  bool is_empty_directory(const path& p)
  {
    return fs::directory_iterator(p)== end_dir_itr;
  }

  bool remove_directory(const path& p) // true if succeeds
    { return BOOST_REMOVE_DIRECTORY(p.c_str()); }
  
  bool remove_file(const path& p) // true if succeeds
    { return BOOST_DELETE_FILE(p.c_str()); }
  
  // called by remove and remove_all_aux
  bool remove_file_or_directory(const path& p, fs::file_type type, error_code* ec)
    // return true if file removed, false if not removed
  {
    if (type == fs::file_not_found)
    {
      if (ec != 0) ec->clear();
      return false;
    }

    if (type == fs::directory_file
#     ifdef BOOST_WINDOWS_API
        || type == fs::_detail_directory_symlink
#     endif
      )
    {
      if (error(!remove_directory(p), p, ec, "boost::filesystem::remove"))
        return false;
    }
    else
    {
      if (error(!remove_file(p), p, ec, "boost::filesystem::remove"))
        return false;
    }
    return true;
  }

  boost::uintmax_t remove_all_aux(const path& p, fs::file_type type,
    error_code* ec)
  {
    boost::uintmax_t count = 1;

    if (type == fs::directory_file)  // but not a directory symlink
    {
      for (fs::directory_iterator itr(p);
            itr != end_dir_itr; ++itr)
      {
        fs::file_type tmp_type = query_file_type(itr->path(), ec);
        if (ec != 0 && *ec)
          return count;
        count += remove_all_aux(itr->path(), tmp_type, ec);
      }
    }
    remove_file_or_directory(p, type, ec);
    return count;
  }

#ifdef BOOST_POSIX_API

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                            POSIX-specific helpers                                    //
//                                                                                      //
//--------------------------------------------------------------------------------------//

  bool not_found_error(int errval)
  {
    return errno == ENOENT || errno == ENOTDIR;
  }

  bool // true if ok
  copy_file_api(const std::string& from_p,
    const std::string& to_p, bool fail_if_exists)
  {
    const std::size_t buf_sz = 32768;
    boost::scoped_array<char> buf(new char [buf_sz]);
    int infile=-1, outfile=-1;  // -1 means not open

    // bug fixed: code previously did a stat()on the from_file first, but that
    // introduced a gratuitous race condition; the stat()is now done after the open()

    if ((infile = ::open(from_p.c_str(), O_RDONLY))< 0)
      { return false; }

    struct stat from_stat;
    if (::stat(from_p.c_str(), &from_stat)!= 0)
      { return false; }

    int oflag = O_CREAT | O_WRONLY | O_TRUNC;
    if (fail_if_exists)
      oflag |= O_EXCL;
    if ((outfile = ::open(to_p.c_str(), oflag, from_stat.st_mode))< 0)
    {
      int open_errno = errno;
      BOOST_ASSERT(infile >= 0);
      ::close(infile);
      errno = open_errno;
      return false;
    }

    ssize_t sz, sz_read=1, sz_write;
    while (sz_read > 0
      && (sz_read = ::read(infile, buf.get(), buf_sz))> 0)
    {
      // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
      // Marc Rochkind, Addison-Wesley, 2004, page 94
      sz_write = 0;
      do
      {
        if ((sz = ::write(outfile, buf.get() + sz_write,
          sz_read - sz_write))< 0)
        { 
          sz_read = sz; // cause read loop termination
          break;        //  and error to be thrown after closes
        }
        sz_write += sz;
      } while (sz_write < sz_read);
    }

    if (::close(infile)< 0)sz_read = -1;
    if (::close(outfile)< 0)sz_read = -1;

    return sz_read >= 0;
  }

  inline fs::file_type query_file_type(const path& p, error_code* ec)
  {
    return fs::detail::symlink_status(p, ec).type();
  }

# else

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                            Windows-specific helpers                                  //
//                                                                                      //
//--------------------------------------------------------------------------------------//

  bool not_found_error(int errval)
  {
    return errval == ERROR_FILE_NOT_FOUND
      || errval == ERROR_PATH_NOT_FOUND
      || errval == ERROR_INVALID_NAME  // "tools/jam/src/:sys:stat.h", "//foo"
      || errval == ERROR_INVALID_DRIVE  // USB card reader with no card inserted
      || errval == ERROR_NOT_READY  // CD/DVD drive with no disc inserted
      || errval == ERROR_INVALID_PARAMETER  // ":sys:stat.h"
      || errval == ERROR_BAD_PATHNAME  // "//nosuch" on Win64
      || errval == ERROR_BAD_NETPATH;  // "//nosuch" on Win32
  }

  // these constants come from inspecting some Microsoft sample code
  std::time_t to_time_t(const FILETIME & ft)
  {
    __int64 t = (static_cast<__int64>(ft.dwHighDateTime)<< 32)
      + ft.dwLowDateTime;
#   if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0
    t -= 116444736000000000LL;
#   else
    t -= 116444736000000000;
#   endif
    t /= 10000000;
    return static_cast<std::time_t>(t);
  }

  void to_FILETIME(std::time_t t, FILETIME & ft)
  {
    __int64 temp = t;
    temp *= 10000000;
#   if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0
    temp += 116444736000000000LL;
#   else
    temp += 116444736000000000;
#   endif
    ft.dwLowDateTime = static_cast<DWORD>(temp);
    ft.dwHighDateTime = static_cast<DWORD>(temp >> 32);
  }

  // Thanks to Jeremy Maitin-Shepard for much help and for permission to
  // base the equivalent()implementation on portions of his 
  // file-equivalence-win32.cpp experimental code.

  struct handle_wrapper
  {
    HANDLE handle;
    handle_wrapper(HANDLE h)
      : handle(h){}
    ~handle_wrapper()
    {
      if (handle != INVALID_HANDLE_VALUE)
        ::CloseHandle(handle);
    }
  };

  HANDLE create_file_handle(const path& p, DWORD dwDesiredAccess,
    DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile)
  {
    return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode,
      lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
      hTemplateFile);
  }

  bool is_reparse_point_a_symlink(const path& p)
  {
    handle_wrapper h(create_file_handle(p, FILE_READ_EA,
      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL));
    if (h.handle == INVALID_HANDLE_VALUE)
      return false;

    boost::scoped_array<char> buf(new char [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);    
 
    // Query the reparse data
    DWORD dwRetLen;
    BOOL result = ::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(),
      MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
    if (!result) return false;
 
    return reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())
      ->ReparseTag == IO_REPARSE_TAG_SYMLINK;
  }

  inline std::size_t get_full_path_name(
    const path& src, std::size_t len, wchar_t* buf, wchar_t** p)
  {
    return static_cast<std::size_t>(
      ::GetFullPathNameW(src.c_str(), static_cast<DWORD>(len), buf, p));
  }

  fs::file_status process_status_failure(const path& p, error_code* ec)
  {
    int errval(::GetLastError());
    if (ec != 0)                             // always report errval, even though some
      ec->assign(errval, system_category());   // errval values are not status_errors

    if (not_found_error(errval))
    {
      return fs::file_status(fs::file_not_found);
    }
    else if ((errval == ERROR_SHARING_VIOLATION))
    {
      return fs::file_status(fs::type_unknown);
    }
    if (ec == 0)
      BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
        p, error_code(errval, system_category())));
    return fs::file_status(fs::status_error);
  }

  //  differs from symlink_status() in that directory symlinks are reported as
  //  _detail_directory_symlink, as required on Windows by remove() and its helpers.
  fs::file_type query_file_type(const path& p, error_code* ec)
  {
    DWORD attr(::GetFileAttributesW(p.c_str()));
    if (attr == 0xFFFFFFFF)
    {
      return process_status_failure(p, ec).type();
    }

    if (ec != 0) ec->clear();

    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
    {
      if (is_reparse_point_a_symlink(p))
        return (attr & FILE_ATTRIBUTE_DIRECTORY)
          ? fs::_detail_directory_symlink
          : fs::symlink_file;
      return fs::reparse_file;
    }

    return (attr & FILE_ATTRIBUTE_DIRECTORY)
      ? fs::directory_file
      : fs::regular_file;
  }

  BOOL resize_file_api(const wchar_t* p, boost::uintmax_t size)
  {
    HANDLE handle = CreateFileW(p, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL, 0);
    LARGE_INTEGER sz;
    sz.QuadPart = size;
    return handle != INVALID_HANDLE_VALUE
      && ::SetFilePointerEx(handle, sz, 0, FILE_BEGIN)
      && ::SetEndOfFile(handle)
      && ::CloseHandle(handle);
  }

  //  Windows kernel32.dll functions that may or may not be present
  //  must be accessed through pointers

  typedef BOOL (WINAPI *PtrCreateHardLinkW)(
    /*__in*/       LPCWSTR lpFileName,
    /*__in*/       LPCWSTR lpExistingFileName,
    /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes
   );

  PtrCreateHardLinkW create_hard_link_api = PtrCreateHardLinkW(
    ::GetProcAddress(
      ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW"));

  typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)(
    /*__in*/ LPCWSTR lpSymlinkFileName,
    /*__in*/ LPCWSTR lpTargetFileName,
    /*__in*/ DWORD dwFlags
   );

  PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW(
    ::GetProcAddress(
      ::GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW"));

#endif

//#ifdef BOOST_WINDOWS_API
//
//
//  inline bool get_free_disk_space(const std::wstring& ph,
//    PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free)
//    { return ::GetDiskFreeSpaceExW(ph.c_str(), avail, total, free)!= 0; }
//
//#endif

} // unnamed namespace

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                operations functions declared in operations.hpp                       //
//                            in alphabetic order                                       //
//                                                                                      //
//--------------------------------------------------------------------------------------//

namespace boost
{
namespace filesystem3
{

  BOOST_FILESYSTEM_DECL
  path absolute(const path& p, const path& base)
  {
//    if ( p.empty() || p.is_absolute() )
//      return p;
//    //  recursively calling absolute is sub-optimal, but is simple
//    path abs_base(base.is_absolute() ? base : absolute(base));
//# ifdef BOOST_WINDOWS_API
//    if (p.has_root_directory())
//      return abs_base.root_name() / p;
//    //  !p.has_root_directory
//    if (p.has_root_name())
//      return p.root_name()
//        / abs_base.root_directory() / abs_base.relative_path() / p.relative_path();
//    //  !p.has_root_name()
//# endif
//    return abs_base / p;

    //  recursively calling absolute is sub-optimal, but is sure and simple
    path abs_base(base.is_absolute() ? base : absolute(base));

    //  store expensive to compute values that are needed multiple times
    path p_root_name (p.root_name());
    path base_root_name (abs_base.root_name());
    path p_root_directory (p.root_directory());

    if (p.empty())
      return abs_base;

    if (!p_root_name.empty())  // p.has_root_name()
    {
      if (p_root_directory.empty())  // !p.has_root_directory()
        return p_root_name / abs_base.root_directory()
        / abs_base.relative_path() / p.relative_path();
      // p is absolute, so fall through to return p at end of block
    }

    else if (!p_root_directory.empty())  // p.has_root_directory()
    {
#     ifdef BOOST_POSIX_API
      // POSIX can have root name it it is a network path
      if (base_root_name.empty())   // !abs_base.has_root_name()
        return p;
#     endif
      return base_root_name / p;
    }

    else
    {
      return abs_base / p;
    }

    return p;  // p.is_absolute() is true
  }

namespace detail
{
  BOOST_FILESYSTEM_DECL bool possible_large_file_size_support()
  {
#   ifdef BOOST_POSIX_API
    struct stat lcl_stat;
    return sizeof(lcl_stat.st_size)> 4;
#   else
    return true;
#   endif
  }

  BOOST_FILESYSTEM_DECL
  void copy(const path& from, const path& to, system::error_code* ec)
  {
    file_status s(symlink_status(from, *ec));
    if (ec != 0 && *ec) return;

    if(is_symlink(s))
    {
      copy_symlink(from, to, *ec);
    }
    else if(is_directory(s))
    {
      copy_directory(from, to, *ec);
    }
    else if(is_regular_file(s))
    {
      copy_file(from, to, copy_option::fail_if_exists, *ec);
    }
    else
    {
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy",
          from, to, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category())));
      ec->assign(BOOST_ERROR_NOT_SUPPORTED, system_category());
    }
  }

  BOOST_FILESYSTEM_DECL
  void copy_directory(const path& from, const path& to, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    struct stat from_stat;
#   endif
    error(!BOOST_COPY_DIRECTORY(from.c_str(), to.c_str()),
      from, to, ec, "boost::filesystem::copy_directory");
  }

  BOOST_FILESYSTEM_DECL
  void copy_file(const path& from, const path& to,
                  BOOST_SCOPED_ENUM(copy_option)option,
                  error_code* ec)
  {
    error(!BOOST_COPY_FILE(from.c_str(), to.c_str(),
      option == copy_option::fail_if_exists),
        from, to, ec, "boost::filesystem::copy_file");
  }

  BOOST_FILESYSTEM_DECL
  void copy_symlink(const path& existing_symlink, const path& new_symlink,
    system::error_code* ec)
  {
# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
    error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
      new_symlink, existing_symlink, ec,
      "boost::filesystem::copy_symlink");

# else  // modern Windows or BOOST_POSIX_API 
    path p(read_symlink(existing_symlink, ec));
    if (ec != 0 && *ec) return;
    create_symlink(p, new_symlink, ec);

# endif
  }

  BOOST_FILESYSTEM_DECL
  bool create_directories(const path& p, system::error_code* ec)
  {
    if (p.empty() || exists(p))
    {
      if (!p.empty() && !is_directory(p))
      {
        if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error(
            "boost::filesystem::create_directories", p,
            error_code(system::errc::file_exists, system::generic_category())));
        else ec->assign(system::errc::file_exists, system::generic_category());
      }
      return false;
    }

    // First create branch, by calling ourself recursively
    create_directories(p.parent_path(), ec);
    // Now that parent's path exists, create the directory
    create_directory(p, ec);
    return true;
  }

  BOOST_FILESYSTEM_DECL
  bool create_directory(const path& p, error_code* ec)
  {
    if (BOOST_CREATE_DIRECTORY(p.c_str()))
    {
      if (ec != 0) ec->clear();
      return true;
    }

    //  attempt to create directory failed
    int errval(BOOST_ERRNO);  // save reason for failure
    error_code dummy;
    if (errval == BOOST_ERROR_ALREADY_EXISTS && is_directory(p, dummy))
    {
      if (ec != 0) ec->clear();
      return false;
    }

    //  attempt to create directory failed && it doesn't already exist
    if (ec == 0)
      BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::create_directory",
        p, error_code(errval, system_category())));
    else
      ec->assign(errval, system_category());
    return false;
  }

  BOOST_FILESYSTEM_DECL
  void create_directory_symlink(const path& to, const path& from,
                                 system::error_code* ec)
  {
#   if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600  // SDK earlier than Vista and Server 2008

    error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
      "boost::filesystem::create_directory_symlink");
#   else

#     if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
        // see if actually supported by Windows runtime dll
        if (error(!create_symbolic_link_api,
            error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
            to, from, ec,
            "boost::filesystem::create_directory_symlink"))
          return;
#     endif

    error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY),
      to, from, ec, "boost::filesystem::create_directory_symlink");
#   endif
  }

  BOOST_FILESYSTEM_DECL
  void create_hard_link(const path& to, const path& from, error_code* ec)
  {

#   if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0500  // SDK earlier than Win 2K

    error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
      "boost::filesystem::create_hard_link");
#   else

#     if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0500
        // see if actually supported by Windows runtime dll
        if (error(!create_hard_link_api,
            error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
            to, from, ec,
            "boost::filesystem::create_hard_link"))
          return;
#     endif

    error(!BOOST_CREATE_HARD_LINK(from.c_str(), to.c_str()), to, from, ec,
      "boost::filesystem::create_hard_link");
#   endif
  }

  BOOST_FILESYSTEM_DECL
  void create_symlink(const path& to, const path& from, error_code* ec)
  {
#   if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600  // SDK earlier than Vista and Server 2008
    error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
      "boost::filesystem::create_directory_symlink");
#   else

#     if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
        // see if actually supported by Windows runtime dll
        if (error(!create_symbolic_link_api,
            error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
            to, from, ec,
            "boost::filesystem::create_symlink"))
          return;
#     endif

    error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), 0),
      to, from, ec, "boost::filesystem::create_symlink");
#   endif
  }

  BOOST_FILESYSTEM_DECL
  path current_path(error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    path cur;
    for (long path_max = 128;; path_max *=2)// loop 'til buffer large enough
    {
      boost::scoped_array<char>
        buf(new char[static_cast<std::size_t>(path_max)]);
      if (::getcwd(buf.get(), static_cast<std::size_t>(path_max))== 0)
      {
        if (error(errno != ERANGE
      // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set 
#         if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
          && errno != 0
#         endif
          , ec, "boost::filesystem::current_path"))
        {
          break;
        }
      }
      else
      {
        cur = buf.get();
        if (ec != 0) ec->clear();
        break;
      }
    }
    return cur;

#   else
    DWORD sz;
    if ((sz = ::GetCurrentDirectoryW(0, NULL))== 0)sz = 1;
    boost::scoped_array<path::value_type> buf(new path::value_type[sz]);
    error(::GetCurrentDirectoryW(sz, buf.get())== 0, ec,
      "boost::filesystem::current_path");
    return path(buf.get());
#   endif
  }


  BOOST_FILESYSTEM_DECL
  void current_path(const path& p, system::error_code* ec)
  {
    error(!BOOST_SET_CURRENT_DIRECTORY(p.c_str()),
      p, ec, "boost::filesystem::current_path");
  }

  BOOST_FILESYSTEM_DECL
  bool equivalent(const path& p1, const path& p2, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    struct stat s2;
    int e2(::stat(p2.c_str(), &s2));
    struct stat s1;
    int e1(::stat(p1.c_str(), &s1));

    if (e1 != 0 || e2 != 0)
    {
      // if one is invalid and the other isn't then they aren't equivalent,
      // but if both are invalid then it is an error
      error (e1 != 0 && e2 != 0, p1, p2, ec, "boost::filesystem::equivalent");
      return false;
    }

    // both stats now known to be valid
    return  s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
        // According to the POSIX stat specs, "The st_ino and st_dev fields
        // taken together uniquely identify the file within the system."
        // Just to be sure, size and mod time are also checked.
        && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;

#   else  // Windows

    // Note well: Physical location on external media is part of the
    // equivalence criteria. If there are no open handles, physical location
    // can change due to defragmentation or other relocations. Thus handles
    // must be held open until location information for both paths has
    // been retrieved.

    // p2 is done first, so any error reported is for p1
    handle_wrapper h2(
      create_file_handle(
          p2.c_str(),
          0,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
          0,
          OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS,
          0));

    handle_wrapper h1(
      create_file_handle(
          p1.c_str(),
          0,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
          0,
          OPEN_EXISTING,
          FILE_FLAG_BACKUP_SEMANTICS,
          0));

    if (h1.handle == INVALID_HANDLE_VALUE
      || h2.handle == INVALID_HANDLE_VALUE)
    {
      // if one is invalid and the other isn't, then they aren't equivalent,
      // but if both are invalid then it is an error
      error(h1.handle == INVALID_HANDLE_VALUE
        && h2.handle == INVALID_HANDLE_VALUE, p1, p2, ec,
          "boost::filesystem::equivalent");
      return false;
    }

    // at this point, both handles are known to be valid

    BY_HANDLE_FILE_INFORMATION info1, info2;

    if (error(!::GetFileInformationByHandle(h1.handle, &info1),
      p1, p2, ec, "boost::filesystem::equivalent"))
        return  false;

    if (error(!::GetFileInformationByHandle(h2.handle, &info2),
      p1, p2, ec, "boost::filesystem::equivalent"))
        return  false;

    // In theory, volume serial numbers are sufficient to distinguish between
    // devices, but in practice VSN's are sometimes duplicated, so last write
    // time and file size are also checked.
      return 
        info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
        && info1.nFileIndexHigh == info2.nFileIndexHigh
        && info1.nFileIndexLow == info2.nFileIndexLow
        && info1.nFileSizeHigh == info2.nFileSizeHigh
        && info1.nFileSizeLow == info2.nFileSizeLow
        && info1.ftLastWriteTime.dwLowDateTime
          == info2.ftLastWriteTime.dwLowDateTime
        && info1.ftLastWriteTime.dwHighDateTime
          == info2.ftLastWriteTime.dwHighDateTime;

#   endif
  }

  BOOST_FILESYSTEM_DECL
  boost::uintmax_t file_size(const path& p, error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (error(::stat(p.c_str(), &path_stat)!= 0,
        p, ec, "boost::filesystem::file_size"))
      return static_cast<boost::uintmax_t>(-1);
   if (error(!S_ISREG(path_stat.st_mode),
      error_code(EPERM, system_category()),
        p, ec, "boost::filesystem::file_size"))
      return static_cast<boost::uintmax_t>(-1);

    return static_cast<boost::uintmax_t>(path_stat.st_size);

#   else  // Windows

    // assume uintmax_t is 64-bits on all Windows compilers

    WIN32_FILE_ATTRIBUTE_DATA fad;

    if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0,
        p, ec, "boost::filesystem::file_size"))
        return static_cast<boost::uintmax_t>(-1);

    if (error((fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!= 0,
      error_code(ERROR_NOT_SUPPORTED, system_category()),
        p, ec, "boost::filesystem::file_size"))
      return static_cast<boost::uintmax_t>(-1);

    return (static_cast<boost::uintmax_t>(fad.nFileSizeHigh)
              << (sizeof(fad.nFileSizeLow)*8)) + fad.nFileSizeLow;
#   endif
  }

  BOOST_FILESYSTEM_DECL
  boost::uintmax_t hard_link_count(const path& p, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    return error(::stat(p.c_str(), &path_stat)!= 0,
                  p, ec, "boost::filesystem::hard_link_count")
           ? 0
           : static_cast<boost::uintmax_t>(path_stat.st_nlink);

#   else // Windows

    // Link count info is only available through GetFileInformationByHandle
    BY_HANDLE_FILE_INFORMATION info;
    handle_wrapper h(
      create_file_handle(p.c_str(), 0,
          FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
    return
      !error(h.handle == INVALID_HANDLE_VALUE,
              p, ec, "boost::filesystem::hard_link_count")
      && !error(::GetFileInformationByHandle(h.handle, &info)== 0,
                 p, ec, "boost::filesystem::hard_link_count")
           ? info.nNumberOfLinks
           : 0;
#   endif
  }

  BOOST_FILESYSTEM_DECL
  path initial_path(error_code* ec)
  {
      static path init_path;
      if (init_path.empty())
        init_path = current_path(ec);
      else if (ec != 0) ec->clear();
      return init_path;
  }

  BOOST_FILESYSTEM_DECL
  bool is_empty(const path& p, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (error(::stat(p.c_str(), &path_stat)!= 0,
        p, ec, "boost::filesystem::is_empty"))
      return false;        
    return S_ISDIR(path_stat.st_mode)
      ? is_empty_directory(p)
      : path_stat.st_size == 0;
#   else

    WIN32_FILE_ATTRIBUTE_DATA fad;
    if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0,
      p, ec, "boost::filesystem::is_empty"))
        return false;

    if (ec != 0) ec->clear();
    return 
      (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        ? is_empty_directory(p)
        : (!fad.nFileSizeHigh && !fad.nFileSizeLow);
#   endif
  }

  BOOST_FILESYSTEM_DECL
  std::time_t last_write_time(const path& p, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (error(::stat(p.c_str(), &path_stat)!= 0,
      p, ec, "boost::filesystem::last_write_time"))
        return std::time_t(-1);
    return path_stat.st_mtime;

#   else

    handle_wrapper hw(
      create_file_handle(p.c_str(), 0,
        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));

    if (error(hw.handle == INVALID_HANDLE_VALUE,
      p, ec, "boost::filesystem::last_write_time"))
        return std::time_t(-1);

    FILETIME lwt;

    if (error(::GetFileTime(hw.handle, 0, 0, &lwt)== 0,
      p, ec, "boost::filesystem::last_write_time"))
        return std::time_t(-1);

    return to_time_t(lwt);
#   endif
  }

  BOOST_FILESYSTEM_DECL
  void last_write_time(const path& p, const std::time_t new_time,
                        system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (error(::stat(p.c_str(), &path_stat)!= 0,
      p, ec, "boost::filesystem::last_write_time"))
        return;
    ::utimbuf buf;
    buf.actime = path_stat.st_atime; // utime()updates access time too:-(
    buf.modtime = new_time;
    error(::utime(p.c_str(), &buf)!= 0,
      p, ec, "boost::filesystem::last_write_time");

#   else

    handle_wrapper hw(
      create_file_handle(p.c_str(), FILE_WRITE_ATTRIBUTES,
        FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));

    if (error(hw.handle == INVALID_HANDLE_VALUE,
      p, ec, "boost::filesystem::last_write_time"))
        return;

    FILETIME lwt;
    to_FILETIME(new_time, lwt);

    error(::SetFileTime(hw.handle, 0, 0, &lwt)== 0,
      p, ec, "boost::filesystem::last_write_time");
#   endif
  }

  BOOST_FILESYSTEM_DECL
  path read_symlink(const path& p, system::error_code* ec)
  {
    path symlink_path;

#   ifdef BOOST_POSIX_API

    for (std::size_t path_max = 64;; path_max *= 2)// loop 'til buffer large enough
    {
      boost::scoped_array<char> buf(new char[path_max]);
      ssize_t result;
      if ((result=::readlink(p.c_str(), buf.get(), path_max))== -1)
      {
        if (ec == 0)
          BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::read_symlink",
            p, error_code(errno, system_category())));
        else ec->assign(errno, system_category());
        break;
      }
      else
      {
        if(result != static_cast<ssize_t>(path_max))
        {
          symlink_path.assign(buf.get(), buf.get() + result);
          if (ec != 0) ec->clear();
          break;
        }
      }
    }

#   elif _WIN32_WINNT < 0x0600  // SDK earlier than Vista and Server 2008
    error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), p, ec,
          "boost::filesystem::read_symlink");
#   else  // Vista and Server 2008 SDK, or later

    union info_t
    {
      char buf[REPARSE_DATA_BUFFER_HEADER_SIZE+MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
      REPARSE_DATA_BUFFER rdb;
    } info;

    handle_wrapper h(
      create_file_handle(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0));

    if (error(h.handle == INVALID_HANDLE_VALUE, p, ec, "boost::filesystem::read_symlink"))
      return symlink_path;

    DWORD sz;

    if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT,
          0, 0, info.buf, sizeof(info), &sz, 0) == 0, p, ec,
          "boost::filesystem::read_symlink" ))
      symlink_path.assign(
        static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
        + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t),
        static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
        + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t)
        + info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t));
#     endif
    return symlink_path;
  }
  
  BOOST_FILESYSTEM_DECL
  bool remove(const path& p, error_code* ec)
  {
    error_code tmp_ec;
    file_type type = query_file_type(p, &tmp_ec);
    if (error(type == status_error, tmp_ec, p, ec,
        "boost::filesystem::remove"))
      return false;

    // Since POSIX remove() is specified to work with either files or directories, in a
    // perfect world it could just be called. But some important real-world operating
    // systems (Windows, Mac OS X, for example) don't implement the POSIX spec. So
    // remove_file_or_directory() is always called to kep it simple.
    return remove_file_or_directory(p, type, ec);
  }

  BOOST_FILESYSTEM_DECL
  boost::uintmax_t remove_all(const path& p, error_code* ec)
  {
    error_code tmp_ec;
    file_type type = query_file_type(p, &tmp_ec);
    if (error(type == status_error, tmp_ec, p, ec,
      "boost::filesystem::remove_all"))
      return 0;

    return (type != status_error && type != file_not_found) // exists
      ? remove_all_aux(p, type, ec)
      : 0;
  }

  BOOST_FILESYSTEM_DECL
  void rename(const path& old_p, const path& new_p, error_code* ec)
  {
    error(!BOOST_MOVE_FILE(old_p.c_str(), new_p.c_str()), old_p, new_p, ec,
      "boost::filesystem::rename");
  }

  BOOST_FILESYSTEM_DECL
  void resize_file(const path& p, uintmax_t size, system::error_code* ec)
  {
    error(!BOOST_RESIZE_FILE(p.c_str(), size), p, ec, "boost::filesystem::resize_file");
  }

  BOOST_FILESYSTEM_DECL
  space_info space(const path& p, error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    struct BOOST_STATVFS vfs;
    space_info info;
    if (!error(::BOOST_STATVFS(p.c_str(), &vfs)!= 0,
      p, ec, "boost::filesystem::space"))
    {
      info.capacity 
        = static_cast<boost::uintmax_t>(vfs.f_blocks)* BOOST_STATVFS_F_FRSIZE;
      info.free 
        = static_cast<boost::uintmax_t>(vfs.f_bfree)* BOOST_STATVFS_F_FRSIZE;
      info.available
        = static_cast<boost::uintmax_t>(vfs.f_bavail)* BOOST_STATVFS_F_FRSIZE;
    }

#   else
    ULARGE_INTEGER avail, total, free;
    space_info info;

    if (!error(::GetDiskFreeSpaceExW(p.c_str(), &avail, &total, &free)== 0,
       p, ec, "boost::filesystem::space"))
    {
      info.capacity
        = (static_cast<boost::uintmax_t>(total.HighPart)<< 32)
          + total.LowPart;
      info.free
        = (static_cast<boost::uintmax_t>(free.HighPart)<< 32)
          + free.LowPart;
      info.available
        = (static_cast<boost::uintmax_t>(avail.HighPart)<< 32)
          + avail.LowPart;
    }

#   endif

    else
    {
      info.capacity = info.free = info.available = 0;
    }
    return info;
  }

  BOOST_FILESYSTEM_DECL
  file_status status(const path& p, error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (::stat(p.c_str(), &path_stat)!= 0)
    {
      if (ec != 0)                            // always report errno, even though some
        ec->assign(errno, system_category());   // errno values are not status_errors

      if (not_found_error(errno))
      {
        return fs::file_status(fs::file_not_found);
      }
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
          p, error_code(errno, system_category())));
      return fs::file_status(fs::status_error);
    }
    if (ec != 0) ec->clear();;
    if (S_ISDIR(path_stat.st_mode))
      return fs::file_status(fs::directory_file);
    if (S_ISREG(path_stat.st_mode))
      return fs::file_status(fs::regular_file);
    if (S_ISBLK(path_stat.st_mode))
      return fs::file_status(fs::block_file);
    if (S_ISCHR(path_stat.st_mode))
      return fs::file_status(fs::character_file);
    if (S_ISFIFO(path_stat.st_mode))
      return fs::file_status(fs::fifo_file);
    if (S_ISSOCK(path_stat.st_mode))
      return fs::file_status(fs::socket_file);
    return fs::file_status(fs::type_unknown);

#   else  // Windows

    DWORD attr(::GetFileAttributesW(p.c_str()));
    if (attr == 0xFFFFFFFF)
    {
      return process_status_failure(p, ec);
    }

    //  reparse point handling
    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
    {
      handle_wrapper h(
        create_file_handle(
            p.c_str(),
            0,  // dwDesiredAccess; attributes only
            FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
            0,  // lpSecurityAttributes
            OPEN_EXISTING,
            FILE_FLAG_BACKUP_SEMANTICS,
            0)); // hTemplateFile
      if (h.handle == INVALID_HANDLE_VALUE)
      {
        return process_status_failure(p, ec);
      }
    }

    if (ec != 0) ec->clear();
    return (attr & FILE_ATTRIBUTE_DIRECTORY)
      ? file_status(directory_file)
      : file_status(regular_file);

#   endif
  }

  BOOST_FILESYSTEM_DECL
  file_status symlink_status(const path& p, error_code* ec)
  {
#   ifdef BOOST_POSIX_API

    struct stat path_stat;
    if (::lstat(p.c_str(), &path_stat)!= 0)
    {
      if (ec != 0)                            // always report errno, even though some
        ec->assign(errno, system_category());   // errno values are not status_errors

      if (errno == ENOENT || errno == ENOTDIR) // these are not errors
      {
        return fs::file_status(fs::file_not_found);
      }
      if (ec == 0)
        BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
          p, error_code(errno, system_category())));
      return fs::file_status(fs::status_error);
    }
    if (ec != 0) ec->clear();
    if (S_ISREG(path_stat.st_mode))
      return fs::file_status(fs::regular_file);
    if (S_ISDIR(path_stat.st_mode))
      return fs::file_status(fs::directory_file);
    if (S_ISLNK(path_stat.st_mode))
      return fs::file_status(fs::symlink_file);
    if (S_ISBLK(path_stat.st_mode))
      return fs::file_status(fs::block_file);
    if (S_ISCHR(path_stat.st_mode))
      return fs::file_status(fs::character_file);
    if (S_ISFIFO(path_stat.st_mode))
      return fs::file_status(fs::fifo_file);
    if (S_ISSOCK(path_stat.st_mode))
      return fs::file_status(fs::socket_file);
    return fs::file_status(fs::type_unknown);

#   else  // Windows

    DWORD attr(::GetFileAttributesW(p.c_str()));
    if (attr == 0xFFFFFFFF)
    {
      return process_status_failure(p, ec);
    }

    if (ec != 0) ec->clear();

    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
      return is_reparse_point_a_symlink(p)
             ? file_status(symlink_file)
             : file_status(reparse_file);

    return (attr & FILE_ATTRIBUTE_DIRECTORY)
      ? file_status(directory_file)
      : file_status(regular_file);

#   endif
  }

  BOOST_FILESYSTEM_DECL
  path system_complete(const path& p, system::error_code* ec)
  {
#   ifdef BOOST_POSIX_API
    return (p.empty() || p.is_absolute())
      ? p : current_path()/ p;

#   else
    if (p.empty())
    {
      if (ec != 0) ec->clear();
      return p;
    }
    wchar_t buf[buf_size];
    wchar_t* pfn;
    std::size_t len = get_full_path_name(p, buf_size, buf, &pfn);

    if (error(len == 0, p, ec, "boost::filesystem::system_complete"))
      return path();

    if (len < buf_size)// len does not include null termination character
      return path(&buf[0]);

    boost::scoped_array<wchar_t> big_buf(new wchar_t[len]);

    return error(get_full_path_name(p, len , big_buf.get(), &pfn)== 0,
      p, ec, "boost::filesystem::system_complete")
      ? path()
      : path(big_buf.get());
#   endif
  }

}  // namespace detail

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                                 directory_entry                                      //
//                                                                                      //
//--------------------------------------------------------------------------------------//

  file_status
  directory_entry::m_get_status(system::error_code* ec) const
  {
    if (!status_known(m_status))
    {
      // optimization: if the symlink status is known, and it isn't a symlink,
      // then status and symlink_status are identical so just copy the
      // symlink status to the regular status.
      if (status_known(m_symlink_status)
        && !is_symlink(m_symlink_status))
      { 
        m_status = m_symlink_status;
        if (ec != 0) ec->clear();
      }
      else m_status = detail::status(m_path, ec);
    }
    else if (ec != 0) ec->clear();
    return m_status;
  }

  file_status
  directory_entry::m_get_symlink_status(system::error_code* ec) const
  {
    if (!status_known(m_symlink_status))
      m_symlink_status = detail::symlink_status(m_path, ec);
    else if (ec != 0) ec->clear();
    return m_symlink_status;
  }

//  dispatch directory_entry supplied here rather than in 
//  <boost/filesystem/path_traits.hpp>, thus avoiding header circularity.
//  test cases are in operations_unit_test.cpp

namespace path_traits
{
  void dispatch(const directory_entry & de,
#                ifdef BOOST_WINDOWS_API
                 std::wstring& to,
#                else   
                 std::string& to,
#                endif
                 const codecvt_type &)
  {
    to = de.path().native();
  }

}  // namespace path_traits
} // namespace filesystem3
} // namespace boost

//--------------------------------------------------------------------------------------//
//                                                                                      //
//                               directory_iterator                                     //
//                                                                                      //
//--------------------------------------------------------------------------------------//

namespace
{
# ifdef BOOST_POSIX_API

  error_code path_max(std::size_t & result)
  // this code is based on Stevens and Rago, Advanced Programming in the
  // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49
  {
#   ifdef PATH_MAX
    static std::size_t max = PATH_MAX;
#   else
    static std::size_t max = 0;
#   endif
    if (max == 0)
    {
      errno = 0;
      long tmp = ::pathconf("/", _PC_NAME_MAX);
      if (tmp < 0)
      {
        if (errno == 0)// indeterminate
          max = 4096; // guess
        else return error_code(errno, system_category());
      }
      else max = static_cast<std::size_t>(tmp + 1); // relative root
    }
    result = max;
    return ok;
  }

  error_code dir_itr_first(void *& handle, void *& buffer,
    const char* dir, string& target,
    fs::file_status &, fs::file_status &)
  {
    if ((handle = ::opendir(dir))== 0)
      return error_code(errno, system_category());
    target = string(".");  // string was static but caused trouble
                             // when iteration called from dtor, after
                             // static had already been destroyed
    std::size_t path_size (0);  // initialization quiets gcc warning (ticket #3509)
    error_code ec = path_max(path_size);
    if (ec)return ec;
    dirent de;
    buffer = std::malloc((sizeof(dirent) - sizeof(de.d_name))
      +  path_size + 1); // + 1 for "/0"
    return ok;
  }  

  // warning: the only dirent member updated is d_name
  inline int readdir_r_simulator(DIR * dirp, struct dirent * entry,
    struct dirent ** result)// *result set to 0 on end of directory
  {
    errno = 0;

#   if !defined(__CYGWIN__)\
    && defined(_POSIX_THREAD_SAFE_FUNCTIONS)\
    && defined(_SC_THREAD_SAFE_FUNCTIONS)\
    && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0)\
    && (!defined(__hpux) || defined(_REENTRANT)) \
    && (!defined(_AIX) || defined(__THREAD_SAFE))
    if (::sysconf(_SC_THREAD_SAFE_FUNCTIONS)>= 0)
      { return ::readdir_r(dirp, entry, result); }
#   endif

    struct dirent * p;
    *result = 0;
    if ((p = ::readdir(dirp))== 0)
      return errno;
    std::strcpy(entry->d_name, p->d_name);
    *result = entry;
    return 0;
  }

  error_code dir_itr_increment(void *& handle, void *& buffer,
    string& target, fs::file_status & sf, fs::file_status & symlink_sf)
  {
    BOOST_ASSERT(buffer != 0);
    dirent * entry(static_cast<dirent *>(buffer));
    dirent * result;
    int return_code;
    if ((return_code = readdir_r_simulator(static_cast<DIR*>(handle),
      entry, &result))!= 0)return error_code(errno, system_category());
    if (result == 0)
      return fs::detail::dir_itr_close(handle, buffer);
    target = entry->d_name;
#   ifdef BOOST_FILESYSTEM_STATUS_CACHE
    if (entry->d_type == DT_UNKNOWN) // filesystem does not supply d_type value
    {
      sf = symlink_sf = fs::file_status(fs::status_error);
    }
    else  // filesystem supplies d_type value
    {
      if (entry->d_type == DT_DIR)
        sf = symlink_sf = fs::file_status(fs::directory_file);
      else if (entry->d_type == DT_REG)
        sf = symlink_sf = fs::file_status(fs::regular_file);
      else if (entry->d_type == DT_LNK)
      {
        sf = fs::file_status(fs::status_error);
        symlink_sf = fs::file_status(fs::symlink_file);
      }
      else sf = symlink_sf = fs::file_status(fs::status_error);
    }
#   else
    sf = symlink_sf = fs::file_status(fs::status_error);
#    endif
    return ok;
  }

# else // BOOST_WINDOWS_API

  error_code dir_itr_first(void *& handle, const fs::path& dir,
    wstring& target, fs::file_status & sf, fs::file_status & symlink_sf)
  // Note: an empty root directory has no "." or ".." entries, so this
  // causes a ERROR_FILE_NOT_FOUND error which we do not considered an
  // error. It is treated as eof instead.
  {
    // use a form of search Sebastian Martel reports will work with Win98
    wstring dirpath(dir.wstring());
    dirpath += (dirpath.empty()
      || (dirpath[dirpath.size()-1] != L'\\'
        && dirpath[dirpath.size()-1] != L'/'
        && dirpath[dirpath.size()-1] != L':'))? L"\\*" : L"*";

    WIN32_FIND_DATAW data;
    if ((handle = ::FindFirstFileW(dirpath.c_str(), &data))
      == INVALID_HANDLE_VALUE)
    { 
      handle = 0;
      return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND
                       // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551                                           
                       || ::GetLastError() == ERROR_NO_MORE_FILES) 
        ? 0 : ::GetLastError(), system_category() );
    }
    target = data.cFileName;
    if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
    else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
    return error_code();
  }

  error_code  dir_itr_increment(void *& handle, wstring& target,
    fs::file_status & sf, fs::file_status & symlink_sf)
  {
    WIN32_FIND_DATAW data;
    if (::FindNextFileW(handle, &data)== 0)// fails
    {
      int error = ::GetLastError();
      fs::detail::dir_itr_close(handle);
      return error_code(error == ERROR_NO_MORE_FILES ? 0 : error, system_category());
    }
    target = data.cFileName;
    if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
    else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
    return error_code();
  }
#endif

  const error_code not_found_error_code (
#     ifdef BOOST_WINDOWS_API
        ERROR_PATH_NOT_FOUND
#     else
        ENOENT 
#     endif
        , system_category());

}  // unnamed namespace

namespace boost
{
namespace filesystem3
{

namespace detail
{
  //  dir_itr_close is called both from the ~dir_itr_imp()destructor 
  //  and dir_itr_increment()
  BOOST_FILESYSTEM_DECL
  system::error_code dir_itr_close( // never throws
    void *& handle
#   if defined(BOOST_POSIX_API)
    , void *& buffer
#   endif
   )
  {
#   ifdef BOOST_POSIX_API
    std::free(buffer);
    buffer = 0;
    if (handle == 0)return ok;
    DIR * h(static_cast<DIR*>(handle));
    handle = 0;
    return error_code(::closedir(h)== 0 ? 0 : errno, system_category());

#   else
    if (handle != 0)
    {
      ::FindClose(handle);
      handle = 0;
    }
    return ok;

#   endif
  }

  void directory_iterator_construct(directory_iterator& it,
    const path& p, system::error_code* ec)    
  {
    if (error(p.empty(), not_found_error_code, p, ec,
       "boost::filesystem::directory_iterator::construct"))return;

    path::string_type filename;
    file_status file_stat, symlink_file_stat;
    error_code result = dir_itr_first(it.m_imp->handle,
#     if defined(BOOST_POSIX_API)
      it.m_imp->buffer,
#     endif
      p.c_str(), filename, file_stat, symlink_file_stat);

    if (result)
    {
      it.m_imp.reset();
      error(true, result, p,
        ec, "boost::filesystem::directory_iterator::construct");
      return;
    }
    
    if (it.m_imp->handle == 0)it.m_imp.reset(); // eof, so make end iterator
    else // not eof
    {
      it.m_imp->dir_entry.assign(p / filename,
        file_stat, symlink_file_stat);
      if (filename[0] == dot // dot or dot-dot
        && (filename.size()== 1
          || (filename[1] == dot
            && filename.size()== 2)))
        {  it.increment(); }
    }
  }

  void directory_iterator_increment(directory_iterator& it,
    system::error_code* ec)
  {
    BOOST_ASSERT(it.m_imp.get() && "attempt to increment end iterator");
    BOOST_ASSERT(it.m_imp->handle != 0 && "internal program error");
    
    path::string_type filename;
    file_status file_stat, symlink_file_stat;
    system::error_code temp_ec;

    for (;;)
    {
      temp_ec = dir_itr_increment(it.m_imp->handle,
#       if defined(BOOST_POSIX_API)
        it.m_imp->buffer,
#       endif
        filename, file_stat, symlink_file_stat);

      if (temp_ec)
      {
        it.m_imp.reset();
        if (ec == 0)
          BOOST_FILESYSTEM_THROW(
            filesystem_error("boost::filesystem::directory_iterator::operator++",
              it.m_imp->dir_entry.path().parent_path(),
              error_code(BOOST_ERRNO, system_category())));
        ec->assign(BOOST_ERRNO, system_category());
        return;
      }
      else if (ec != 0) ec->clear();

      if (it.m_imp->handle == 0){ it.m_imp.reset(); return; } // eof, make end
      if (!(filename[0] == dot // !(dot or dot-dot)
        && (filename.size()== 1
          || (filename[1] == dot
            && filename.size()== 2))))
      {
        it.m_imp->dir_entry.replace_filename(
          filename, file_stat, symlink_file_stat);
        return;
      }
    }
  }
}  // namespace detail
} // namespace filesystem3
} // namespace boost

#endif  // no wide character support
