summaryrefslogtreecommitdiff
path: root/lib/win32/emu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/win32/emu.cpp')
-rw-r--r--lib/win32/emu.cpp68
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;
}