summaryrefslogtreecommitdiff
path: root/lib/win32
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2015-01-04 19:41:50 +0000
committerChris Wilson <chris+github@qwirx.com>2015-01-04 19:41:50 +0000
commit57081a4a47e9c1c66f3f6bb7eae3903892ce407d (patch)
tree795c9371afb637a75b305c6ac6d0fa2506d39dbf /lib/win32
parentefda4b302a2494017563e2c9d6c4ce3b0098c61d (diff)
Add test for hardlink handling.
Diffstat (limited to 'lib/win32')
-rw-r--r--lib/win32/emu.cpp68
-rw-r--r--lib/win32/emu.h2
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)