diff options
Diffstat (limited to 'lib/win32/emu.cpp')
-rw-r--r-- | lib/win32/emu.cpp | 68 |
1 files changed, 68 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; } |