diff options
author | Chris Wilson <chris+github@qwirx.com> | 2015-01-04 19:41:50 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2015-01-04 19:41:50 +0000 |
commit | 57081a4a47e9c1c66f3f6bb7eae3903892ce407d (patch) | |
tree | 795c9371afb637a75b305c6ac6d0fa2506d39dbf /lib/win32 | |
parent | efda4b302a2494017563e2c9d6c4ce3b0098c61d (diff) |
Add test for hardlink handling.
Diffstat (limited to 'lib/win32')
-rw-r--r-- | lib/win32/emu.cpp | 68 | ||||
-rw-r--r-- | lib/win32/emu.h | 2 |
2 files changed, 70 insertions, 0 deletions
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp index fb8fb437..ee1f461a 100644 --- a/lib/win32/emu.cpp +++ b/lib/win32/emu.cpp @@ -1667,6 +1667,73 @@ int emu_mkdir(const char* pPathName) return 0; } +int emu_link(const char* pOldPath, const char* pNewPath) +{ + std::string AbsOldPathWithUnicode = + ConvertPathToAbsoluteUnicode(pOldPath); + + if (AbsOldPathWithUnicode.size() == 0) + { + // error already logged by ConvertPathToAbsoluteUnicode() + return -1; + } + + std::string AbsNewPathWithUnicode = + ConvertPathToAbsoluteUnicode(pNewPath); + + if (AbsNewPathWithUnicode.size() == 0) + { + // error already logged by ConvertPathToAbsoluteUnicode() + return -1; + } + + WCHAR* pOldBuffer = ConvertUtf8ToWideString(AbsOldPathWithUnicode.c_str()); + if (!pOldBuffer) + { + return -1; + } + + WCHAR* pNewBuffer = ConvertUtf8ToWideString(AbsNewPathWithUnicode.c_str()); + if (!pNewBuffer) + { + delete [] pOldBuffer; + return -1; + } + + BOOL result = CreateHardLinkW(pNewBuffer, pOldBuffer, NULL); + DWORD err = GetLastError(); + delete [] pOldBuffer; + delete [] pNewBuffer; + + if (!result) + { + if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) + { + errno = ENOENT; + } + else if (err == ERROR_SHARING_VIOLATION) + { + errno = EBUSY; + } + else if (err == ERROR_ACCESS_DENIED) + { + errno = EACCES; + } + else + { + ::syslog(LOG_WARNING, "Failed to hardlink file " + "'%s' to '%s': %s", pOldPath, pNewPath, + GetErrorMessage(err).c_str()); + errno = ENOSYS; + } + + return -1; + } + + return 0; + +} + int emu_unlink(const char* pFileName) { std::string AbsPathWithUnicode = @@ -1709,6 +1776,7 @@ int emu_unlink(const char* pFileName) GetErrorMessage(err).c_str()); errno = ENOSYS; } + return -1; } diff --git a/lib/win32/emu.h b/lib/win32/emu.h index c28b0bdb..05f2f561 100644 --- a/lib/win32/emu.h +++ b/lib/win32/emu.h @@ -353,6 +353,7 @@ bool ConvertTime_tToFileTime(const time_t from, FILETIME *pTo); int emu_chdir (const char* pDirName); int emu_mkdir (const char* pPathName); +int emu_link (const char* pOldPath, const char* pNewPath); int emu_unlink (const char* pFileName); int emu_fstat (HANDLE file, struct emu_stat* st); int emu_stat (const char* pName, struct emu_stat* st); @@ -363,6 +364,7 @@ int emu_rename (const char* pOldName, const char* pNewName); #define chdir(directory) emu_chdir (directory) #define mkdir(path, mode) emu_mkdir (path) +#define link(oldpath, newpath) emu_link (oldpath, newpath) #define unlink(file) emu_unlink (file) #define utimes(buffer, times) emu_utimes (buffer, times) #define chmod(file, mode) emu_chmod (file, mode) |