Index: src/shared/platform/win/nacl_host_desc.c |
diff --git a/src/shared/platform/win/nacl_host_desc.c b/src/shared/platform/win/nacl_host_desc.c |
index edd0c8e07ca24a58251cab1323d41275ba9f8d6d..b893a4feb8658c6c1dcd50caee27d8563067c6fc 100644 |
--- a/src/shared/platform/win/nacl_host_desc.c |
+++ b/src/shared/platform/win/nacl_host_desc.c |
@@ -1397,3 +1397,233 @@ int NaClHostDescUnlink(const char *path) { |
return -errno; |
return 0; |
} |
+ |
+int NaClHostDescTruncate(const char *path, off_t length) { |
+ HANDLE hFile; |
+ LARGE_INTEGER to_move; |
+ DWORD err; |
+ int retval = 0; |
+ |
+ hFile = CreateFileA(path, GENERIC_WRITE, |
+ FILE_SHARE_WRITE, |
+ NULL, |
+ OPEN_EXISTING, |
+ FILE_ATTRIBUTE_NORMAL, |
+ NULL); |
+ |
+ to_move.QuadPart = length; |
+ if (!SetFilePointerEx(hFile, to_move, (LARGE_INTEGER *) NULL, FILE_BEGIN)) { |
+ err = GetLastError(); |
+ retval = -NaClXlateSystemError(err); |
+ goto out_file; |
+ } |
+ |
+ if (!SetEndOfFile(hFile)) { |
+ err = GetLastError(); |
+ retval = -NaClXlateSystemError(err); |
+ goto out_file; |
+ } |
+ |
+out_file: |
+ CloseHandle(hFile); |
+out: |
+ return retval; |
+} |
+ |
+int NaClHostDescLstat(char const *host_os_pathname, nacl_host_stat_t *nhsp) { |
+} |
+ |
+int NaClHostDescLink(const char *oldpath, const char *newpath) { |
+ if (!CreateHardLink(newpath, oldpath, NULL)) { |
+ DWORD err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescChmod(const char *path, int mode) { |
+ if (-1 == _chmod(path, mode)) { |
+ return -GetErrno(); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescAccess(const char *pathname, int mode) { |
+ return -_access_s(path, mode); |
+} |
+ |
+int NaClHostDescRename(const char *oldpath, const char *newpath) { |
+ if (-1 == rename(oldpath, newpath)) { |
+ return -GetErrno(); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescReadlink(const char *path, char *buf, size_t bufsiz) { |
+ DWORD attributes; |
+ HANDLE hFile; |
+ char buffer[16384]; |
+ REPARSE_DATA_BUFFER rpBuffer; |
+ PREPARSE_DATA_BUFFER *pBuffer; |
+ wchar_t *rpath; |
+ int retval; |
+ errno_t err; |
+ |
+ if (INVALID_FILE_ATTRIBUTES == (attributes = GetFileAttributes(path))) { |
+ DWORD err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ |
+ if (0 == (attr & REPARSE_FOLDER)) { |
+ return -NACL_ABI_EINVAL; |
+ } |
+ |
+ if (0 == (GetFileAttributes(path) & REPARSE_FOLDER)) { |
+ return -NACL_ABI_EINVAL; |
+ } |
+ |
+ hFile = CreateFileA(path, GENERIC_READ, |
+ 0, |
+ NULL, |
+ OPEN_EXISTING, |
+ FILE_FLAG_OPEN_REPARSE_POINT, |
+ NULL); |
+ |
+ if (!DeviceIoControl(hFile, |
+ FSCTL_GET_REPARSE_POINT, |
+ NULL, |
+ 0, |
+ &buffer, |
+ sizeof buffer, |
+ &bytesReturned, |
+ NULL)) { |
+ } |
+ |
+ CloseHandle(hFile); |
+ |
+ offset = pBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof wchar_t; |
+ len = pBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength; |
+ pathbuf = &pBuffer->SymbolicLinkReparseBuffer.PathBuffer[offset]; |
+ |
+ if (0 == (retval = WideCharToMultiByte(CP_UTF8, |
+ WC_COMPOSITECHECK, |
+ pathbuf, |
+ pathlen |
+ buf, |
+ bufsiz, |
+ NULL, |
+ NULL))) { |
+ DWORD err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ |
+ if (0 != (err = wcstombs_s(&retval, buf, bufsiz, pathbuf, _TRUNCATE))) { |
+ return -err; |
+ } |
+ return retval; |
+} |
+ |
+int NaClHostDescSymlink(const char *oldpath, const char *newpath) { |
+ struct _stati64 buffer; |
+ DWORD dwFlags; |
+ |
+ if (-1 == _stati64(oldpath, &buffer)) { |
+ return -GetErrno(); |
+ } |
+ |
+ dwFlags = buffer.st_mode & _S_IFDIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0x0; |
+ if (!CreateSymbolicLink(newpath, oldpath, dwFlags)) { |
+ DWORD err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescUtimes(const char *filename, |
+ const struct nacl_abi_timeval times[2]) { |
+ struct _utimbuf times; |
+ |
+ if (-1 == _utime64(filename, ×)) { |
+ return -GetErrno(); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescFcntl(struct NaClHostDesc *d, int cmd, long arg) { |
+ NaClHostDescCheckValidity("NaClHostDescFcntl", d); |
+} |
+ |
+int NaClHostDescFchmod(struct NaClHostDesc *d, int mode) { |
+ NaClHostDescCheckValidity("NaClHostDescFchmod", d); |
+ |
+ if (-1 == _chmod(path, mode)) { |
+ return -GetErrno(); |
+ } |
+ return 0; |
+} |
+ |
+int NaClHostDescFsync(struct NaClHostDesc *d) { |
+ HANDLE hFile; |
+ DWORD err; |
+ |
+ NaClHostDescCheckValidity("NaClHostDescFsync", d); |
+ |
+ hFile = (HANDLE) _get_osfhandle(d->d); |
+ CHECK(INVALID_HANDLE_VALUE != hFile); |
+ |
+ if (!FlushFileBuffers(hFile)) { |
+ err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ |
+ return 0; |
+} |
+ |
+int NaClHostDescFdatasync(struct NaClHostDesc *d) { |
+ HANDLE hFile; |
+ DWORD err; |
+ |
+ NaClHostDescCheckValidity("NaClHostDescFdatasync", d); |
+ |
+ hFile = (HANDLE) _get_osfhandle(d->d); |
+ CHECK(INVALID_HANDLE_VALUE != hFile); |
+ |
+ if (!FlushFileBuffers(hFile)) { |
+ err = GetLastError(); |
+ return -NaClXlateSystemError(err); |
+ } |
+ |
+ return 0; |
+} |
+ |
+int NaClHostDescFtruncate(struct NaClHostDesc *d, off_t length) { |
+ HANDLE hFile; |
+ LARGE_INTEGER to_move; |
+ DWORD err; |
+ nacl_off64_t orig_pos = 0; |
+ |
+ NaClHostDescCheckValidity("NaClHostDescFtruncate", d); |
+ |
+ hFile = (HANDLE) _get_osfhandle(d->d); |
+ CHECK(INVALID_HANDLE_VALUE != hFile); |
+ |
+ /* |
+ * Ensure that we do not corrupt shared implicit file position. |
+ */ |
+ if (d->protect_filepos) { |
+ orig_pos = NaClLockAndGetCurrentFilePos(fh); |
+ } |
+ to_move.QuadPart = length; |
+ if (!SetFilePointerEx(hFile, to_move, (LARGE_INTEGER *) NULL, FILE_BEGIN)) { |
+ err = GetLastError(); |
+ retval = -NaClXlateSystemError(err); |
+ goto out_file; |
+ } |
+ if (!SetEndOfFile(hFile)) { |
+ err = GetLastError(); |
+ retval = -NaClXlateSystemError(err); |
+ } |
+ if (d->protect_filepos) { |
+ NaClSetCurrentFilePosAndUnlock(fh, orig_pos); |
+ } |
+} |