summaryrefslogtreecommitdiffstats
path: root/Utilities/cmlibarchive/libarchive/archive_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_windows.c')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c1640
1 files changed, 600 insertions, 1040 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index e194d77..8f5d566 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Kees Zeelenberg
* All rights reserved.
*
@@ -51,56 +51,54 @@
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
-#ifndef __BORLANDC__
+#ifdef HAVE_SYS_UTIME_H
#include <sys/utime.h>
#endif
#include <sys/stat.h>
+#include <locale.h>
#include <process.h>
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
-#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
-# define EPOC_TIME (116444736000000000UI64)
-#else
-# define EPOC_TIME (116444736000000000ULL)
-#endif
+#include <share.h>
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
-#if defined(_MSC_VER) && _MSC_VER < 1300
-/* VS 6 does not provide SetFilePointerEx, so define it here. */
-static BOOL SetFilePointerEx(HANDLE hFile,
- LARGE_INTEGER liDistanceToMove,
- PLARGE_INTEGER lpNewFilePointer,
- DWORD dwMoveMethod)
+#if defined(__LA_LSEEK_NEEDED)
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
{
- LARGE_INTEGER li;
- li.QuadPart = liDistanceToMove.QuadPart;
- li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, dwMoveMethod);
- if(lpNewFilePointer) { lpNewFilePointer->QuadPart = li.QuadPart; }
- return li.LowPart != -1 || GetLastError() == NO_ERROR;
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
}
#endif
struct ustat {
- int64_t st_atime;
- uint32_t st_atime_nsec;
- int64_t st_ctime;
- uint32_t st_ctime_nsec;
- int64_t st_mtime;
- uint32_t st_mtime_nsec;
- gid_t st_gid;
- /* 64bits ino */
- int64_t st_ino;
- mode_t st_mode;
- uint32_t st_nlink;
- uint64_t st_size;
- uid_t st_uid;
- dev_t st_dev;
- dev_t st_rdev;
+ int64_t st_atime;
+ uint32_t st_atime_nsec;
+ int64_t st_ctime;
+ uint32_t st_ctime_nsec;
+ int64_t st_mtime;
+ uint32_t st_mtime_nsec;
+ gid_t st_gid;
+ /* 64bits ino */
+ int64_t st_ino;
+ mode_t st_mode;
+ uint32_t st_nlink;
+ uint64_t st_size;
+ uid_t st_uid;
+ dev_t st_dev;
+ dev_t st_rdev;
};
-/* Local replacement for undocumented Windows CRT function. */
-static void la_dosmaperr(unsigned long e);
-
/* Transform 64-bits ino into 32-bits by hashing.
* You do not forget that really unique number size is 64-bits.
*/
@@ -108,10 +106,10 @@ static void la_dosmaperr(unsigned long e);
static __inline ino_t
getino(struct ustat *ub)
{
- ULARGE_INTEGER ino64;
- ino64.QuadPart = ub->st_ino;
- /* I don't know this hashing is correct way */
- return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
+ ULARGE_INTEGER ino64;
+ ino64.QuadPart = ub->st_ino;
+ /* I don't know this hashing is correct way */
+ return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
}
/*
@@ -120,657 +118,332 @@ getino(struct ustat *ub)
* characters.
* see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
*/
-static wchar_t *
-permissive_name(const char *name)
-{
- wchar_t *wn, *wnp;
- wchar_t *ws, *wsp;
- size_t l, len, slen;
- int unc;
-
- len = strlen(name);
- wn = malloc((len + 1) * sizeof(wchar_t));
- if (wn == NULL)
- return (NULL);
- l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len);
- if (l == 0) {
- free(wn);
- return (NULL);
- }
- wn[l] = L'\0';
-
- /* Get a full path names */
- l = GetFullPathNameW(wn, 0, NULL, NULL);
- if (l == 0) {
- free(wn);
- return (NULL);
- }
- wnp = malloc(l * sizeof(wchar_t));
- if (wnp == NULL) {
- free(wn);
- return (NULL);
- }
- len = GetFullPathNameW(wn, l, wnp, NULL);
- free(wn);
- wn = wnp;
-
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'?' && wnp[3] == L'\\')
- /* We have already permissive names. */
- return (wn);
-
- if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
- wnp[2] == L'.' && wnp[3] == L'\\') {
- /* Device names */
- if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
- (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
- wnp[5] == L':' && wnp[6] == L'\\')
- wnp[2] = L'?';/* Not device names. */
- return (wn);
- }
-
- unc = 0;
- if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
- wchar_t *p = &wnp[2];
-
- /* Skip server-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\') {
- wchar_t *rp = ++p;
- /* Skip share-name letters. */
- while (*p != L'\\' && *p != L'\0')
- ++p;
- if (*p == L'\\' && p != rp) {
- /* Now, match patterns such as
- * "\\server-name\share-name\" */
- wnp += 2;
- len -= 2;
- unc = 1;
- }
- }
- }
-
- slen = 4 + (unc * 4) + len + 1;
- ws = wsp = malloc(slen * sizeof(wchar_t));
- if (ws == NULL) {
- free(wn);
- return (NULL);
- }
- /* prepend "\\?\" */
- wcsncpy(wsp, L"\\\\?\\", 4);
- wsp += 4;
- slen -= 4;
- if (unc) {
- /* append "UNC\" ---> "\\?\UNC\" */
- wcsncpy(wsp, L"UNC\\", 4);
- wsp += 4;
- slen -= 4;
- }
- wcsncpy(wsp, wnp, slen);
- wsp[slen - 1] = L'\0'; /* Ensure null termination. */
- free(wn);
- return (ws);
+wchar_t *
+__la_win_permissive_name(const char *name)
+{
+ wchar_t *wn;
+ wchar_t *ws;
+ size_t ll;
+
+ ll = strlen(name);
+ wn = malloc((ll + 1) * sizeof(wchar_t));
+ if (wn == NULL)
+ return (NULL);
+ ll = mbstowcs(wn, name, ll);
+ if (ll == (size_t)-1) {
+ free(wn);
+ return (NULL);
+ }
+ wn[ll] = L'\0';
+ ws = __la_win_permissive_name_w(wn);
+ free(wn);
+ return (ws);
+}
+
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+ wchar_t *wn, *wnp;
+ wchar_t *ws, *wsp;
+ DWORD l, len, slen;
+ int unc;
+
+ /* Get a full-pathname. */
+ l = GetFullPathNameW(wname, 0, NULL, NULL);
+ if (l == 0)
+ return (NULL);
+ /* NOTE: GetFullPathNameW has a bug that if the length of the file
+ * name is just one that return imcomplete buffer size. Thus, we
+ * have to add three to the size to allocate a sufficient buffer
+ * size for the full-pathname of the file name. */
+ l += 3;
+ wnp = malloc(l * sizeof(wchar_t));
+ if (wnp == NULL)
+ return (NULL);
+ len = GetFullPathNameW(wname, l, wnp, NULL);
+ wn = wnp;
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'?' && wnp[3] == L'\\')
+ /* We have already a permissive name. */
+ return (wn);
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'.' && wnp[3] == L'\\') {
+ /* This is a device name */
+ if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+ (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+ wnp[5] == L':' && wnp[6] == L'\\')
+ wnp[2] = L'?';/* Not device name. */
+ return (wn);
+ }
+
+ unc = 0;
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+ wchar_t *p = &wnp[2];
+
+ /* Skip server-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\') {
+ wchar_t *rp = ++p;
+ /* Skip share-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\' && p != rp) {
+ /* Now, match patterns such as
+ * "\\server-name\share-name\" */
+ wnp += 2;
+ len -= 2;
+ unc = 1;
+ }
+ }
+ }
+
+ slen = 4 + (unc * 4) + len + 1;
+ ws = wsp = malloc(slen * sizeof(wchar_t));
+ if (ws == NULL) {
+ free(wn);
+ return (NULL);
+ }
+ /* prepend "\\?\" */
+ wcsncpy(wsp, L"\\\\?\\", 4);
+ wsp += 4;
+ slen -= 4;
+ if (unc) {
+ /* append "UNC\" ---> "\\?\UNC\" */
+ wcsncpy(wsp, L"UNC\\", 4);
+ wsp += 4;
+ slen -= 4;
+ }
+ wcsncpy(wsp, wnp, slen);
+ wsp[slen - 1] = L'\0'; /* Ensure null termination. */
+ free(wn);
+ return (ws);
}
+/*
+ * Create a file handle.
+ * This can exceed MAX_PATH limitation.
+ */
static HANDLE
la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
- wchar_t *wpath;
- HANDLE handle;
-
- handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
- lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- hTemplateFile);
- if (handle != INVALID_HANDLE_VALUE)
- return (handle);
- if (GetLastError() != ERROR_PATH_NOT_FOUND)
- return (handle);
- wpath = permissive_name(path);
- if (wpath == NULL)
- return (handle);
- handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
- lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
- hTemplateFile);
- free(wpath);
- return (handle);
-}
-
-static void *
-la_GetFunctionKernel32(const char *name)
-{
- static HINSTANCE lib;
- static int set;
- if (!set) {
- set = 1;
- lib = LoadLibrary("kernel32.dll");
- }
- if (lib == NULL) {
- fprintf(stderr, "Can't load kernel32.dll?!\n");
- exit(1);
- }
- return (void *)GetProcAddress(lib, name);
-}
-
-static int
-la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
-{
- static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
- static int set;
- if (!set) {
- set = 1;
- f = la_GetFunctionKernel32("CreateHardLinkW");
- }
- return f == NULL ? 0 : (*f)(linkname, target, NULL);
-}
-
-
-/* Make a link to src called dst. */
-static int
-__link(const char *src, const char *dst, int sym)
-{
- wchar_t *wsrc, *wdst;
- int res, retval;
- DWORD attr;
-
- if (src == NULL || dst == NULL) {
- set_errno (EINVAL);
- return -1;
- }
-
- wsrc = permissive_name(src);
- wdst = permissive_name(dst);
- if (wsrc == NULL || wdst == NULL) {
- free(wsrc);
- free(wdst);
- set_errno (EINVAL);
- return -1;
- }
-
- if ((attr = GetFileAttributesW(wsrc)) != -1) {
- res = la_CreateHardLinkW(wdst, wsrc);
- } else {
- /* wsrc does not exist; try src prepend it with the dirname of wdst */
- wchar_t *wnewsrc, *slash;
- int i, n, slen, wlen;
-
- if (strlen(src) >= 3 && isalpha((unsigned char)src[0]) &&
- src[1] == ':' && src[2] == '\\') {
- /* Original src name is already full-path */
- retval = -1;
- goto exit;
- }
- if (src[0] == '\\') {
- /* Original src name is almost full-path
- * (maybe src name is without drive) */
- retval = -1;
- goto exit;
- }
-
- wnewsrc = malloc ((wcslen(wsrc) + wcslen(wdst) + 1) * sizeof(wchar_t));
- if (wnewsrc == NULL) {
- errno = ENOMEM;
- retval = -1;
- goto exit;
- }
- /* Copying a dirname of wdst */
- wcscpy(wnewsrc, wdst);
- slash = wcsrchr(wnewsrc, L'\\');
- if (slash != NULL)
- *++slash = L'\0';
- else
- wcscat(wnewsrc, L"\\");
- /* Converting multi-byte src to wide-char src */
- wlen = wcslen(wsrc);
- slen = strlen(src);
- n = MultiByteToWideChar(CP_ACP, 0, src, slen, wsrc, slen);
- if (n == 0) {
- free (wnewsrc);
- retval = -1;
- goto exit;
- }
- for (i = 0; i < n; i++)
- if (wsrc[i] == L'/')
- wsrc[i] = L'\\';
- wcsncat(wnewsrc, wsrc, n);
- /* Check again */
- attr = GetFileAttributesW(wnewsrc);
- if (attr == -1 || (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- if (attr == -1)
- la_dosmaperr(GetLastError());
- else
- errno = EPERM;
- free (wnewsrc);
- retval = -1;
- goto exit;
- }
- res = la_CreateHardLinkW(wdst, wnewsrc);
- free (wnewsrc);
- }
- if (res == 0) {
- la_dosmaperr(GetLastError());
- retval = -1;
- } else
- retval = 0;
-exit:
- free(wsrc);
- free(wdst);
- return (retval);
-}
-
-/* Make a hard link to src called dst. */
-int
-__la_link(const char *src, const char *dst)
-{
- return __link (src, dst, 0);
-}
-
-int
-__la_ftruncate(int fd, off_t length)
-{
- LARGE_INTEGER distance;
- HANDLE handle;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = length;
- if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- if (!SetEndOfFile(handle)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-#define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10))
-static int
-__hutimes(HANDLE handle, const struct __timeval *times)
-{
- ULARGE_INTEGER wintm;
- FILETIME fatime, fmtime;
-
- wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec);
- fatime.dwLowDateTime = wintm.LowPart;
- fatime.dwHighDateTime = wintm.HighPart;
- wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec);
- fmtime.dwLowDateTime = wintm.LowPart;
- fmtime.dwHighDateTime = wintm.HighPart;
- if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) {
- errno = EINVAL;
- return (-1);
- }
- return (0);
-}
-
-int
-__la_futimes(int fd, const struct __timeval *times)
-{
-
- return (__hutimes((HANDLE)_get_osfhandle(fd), times));
-}
-
-int
-__la_utimes(const char *name, const struct __timeval *times)
-{
- int ret;
- HANDLE handle;
-
- handle = la_CreateFile(name, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ret = __hutimes(handle, times);
- CloseHandle(handle);
- return (ret);
-}
-
-int
-__la_chdir(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = SetCurrentDirectoryA(path);
- if (r == 0) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- } else
- return (0);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = SetCurrentDirectoryW(ws);
- free(ws);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-int
-__la_chmod(const char *path, mode_t mode)
-{
- wchar_t *ws;
- int r;
-
- r = _chmod(path, mode);
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = _wchmod(ws, mode);
- free(ws);
- return (r);
-}
-
-/*
- * This fcntl is limited implemention.
- */
-int
-__la_fcntl(int fd, int cmd, int val)
-{
- HANDLE handle;
-
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- if (cmd == F_SETFL && val == 0) {
- DWORD mode = PIPE_WAIT;
- if (SetNamedPipeHandleState(
- handle, &mode, NULL, NULL) != 0)
- return (0);
- }
- }
- errno = EINVAL;
- return (-1);
-}
-
+ wchar_t *wpath;
+ HANDLE handle;
+
+ handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile);
+ if (handle != INVALID_HANDLE_VALUE)
+ return (handle);
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ return (handle);
+ wpath = __la_win_permissive_name(path);
+ if (wpath == NULL)
+ return (handle);
+ handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile);
+ free(wpath);
+ return (handle);
+}
+
+#if defined(__LA_LSEEK_NEEDED)
__int64
__la_lseek(int fd, __int64 offset, int whence)
{
- LARGE_INTEGER distance;
- LARGE_INTEGER newpointer;
- HANDLE handle;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- errno = EBADF;
- return (-1);
- }
- distance.QuadPart = offset;
- if (!SetFilePointerEx(handle, distance, &newpointer, whence)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_BROKEN_PIPE)
- return (0);
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return (newpointer.QuadPart);
-}
-
-int
-__la_mkdir(const char *path, mode_t mode)
-{
- wchar_t *ws;
- int r;
-
- (void)mode;/* UNUSED */
- r = CreateDirectoryA(path, NULL);
- if (r == 0) {
- DWORD lasterr = GetLastError();
- if (lasterr != ERROR_FILENAME_EXCED_RANGE &&
- lasterr != ERROR_PATH_NOT_FOUND) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- } else
- return (0);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = CreateDirectoryW(ws, NULL);
- free(ws);
- if (r == 0) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-/* Windows' mbstowcs is differrent error handling from other unix mbstowcs.
- * That one is using MultiByteToWideChar function with MB_PRECOMPOSED and
- * MB_ERR_INVALID_CHARS flags.
- * This implements for only to pass libarchive_test.
- */
-size_t
-__la_mbstowcs(wchar_t *wcstr, const char *mbstr, size_t nwchars)
-{
-
- return (MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS,
- mbstr, (int)strlen(mbstr), wcstr,
- (int)nwchars));
+ LARGE_INTEGER distance;
+ LARGE_INTEGER newpointer;
+ HANDLE handle;
+
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ handle = (HANDLE)_get_osfhandle(fd);
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
+ errno = EBADF;
+ return (-1);
+ }
+ distance.QuadPart = offset;
+ if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_BROKEN_PIPE)
+ return (0);
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return (newpointer.QuadPart);
}
+#endif
+/* This can exceed MAX_PATH limitation. */
int
__la_open(const char *path, int flags, ...)
{
- va_list ap;
- wchar_t *ws;
- int r, pmode;
- DWORD attr;
-
- va_start(ap, flags);
- pmode = va_arg(ap, int);
- va_end(ap);
- ws = NULL;
- if ((flags & ~O_BINARY) == O_RDONLY) {
- /*
- * When we open a directory, _open function returns
- * "Permission denied" error.
- */
- attr = GetFileAttributesA(path);
- if (attr == -1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- attr = GetFileAttributesW(ws);
- }
- if (attr == -1) {
- la_dosmaperr(GetLastError());
- free(ws);
- return (-1);
- }
- if (attr & FILE_ATTRIBUTE_DIRECTORY) {
- HANDLE handle;
-
- if (ws != NULL)
- handle = CreateFileW(ws, 0, 0, NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_ATTRIBUTE_READONLY,
- NULL);
- else
- handle = CreateFileA(path, 0, 0, NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS |
- FILE_ATTRIBUTE_READONLY,
- NULL);
- free(ws);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
- return (r);
- }
- }
- if (ws == NULL) {
-#ifdef __BORLANDC__
- r = _open(path, flags);
+ va_list ap;
+ wchar_t *ws;
+ int r, pmode;
+ DWORD attr;
+
+ va_start(ap, flags);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+ ws = NULL;
+ if ((flags & ~O_BINARY) == O_RDONLY) {
+ /*
+ * When we open a directory, _open function returns
+ * "Permission denied" error.
+ */
+ attr = GetFileAttributesA(path);
+ if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+ ws = __la_win_permissive_name(path);
+ if (ws == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ attr = GetFileAttributesW(ws);
+ }
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ free(ws);
+ return (-1);
+ }
+ if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+ HANDLE handle;
+
+ if (ws != NULL)
+ handle = CreateFileW(ws, 0, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_ATTRIBUTE_READONLY,
+ NULL);
+ else
+ handle = CreateFileA(path, 0, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_ATTRIBUTE_READONLY,
+ NULL);
+ free(ws);
+ if (handle == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
+ return (r);
+ }
+ }
+ if (ws == NULL) {
+#if defined(__BORLANDC__)
+ /* Borland has no mode argument.
+ TODO: Fix mode of new file. */
+ r = _open(path, flags);
#else
- r = _open(path, flags, pmode);
+ r = _open(path, flags, pmode);
#endif
- if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* simular other POSIX system action to pass a test */
- attr = GetFileAttributesA(path);
- if (attr == -1)
- la_dosmaperr(GetLastError());
- else if (attr & FILE_ATTRIBUTE_DIRECTORY)
- errno = EISDIR;
- else
- errno = EACCES;
- return (-1);
- }
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- }
- r = _wopen(ws, flags, pmode);
- if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
- /* simular other POSIX system action to pass a test */
- attr = GetFileAttributesW(ws);
- if (attr == -1)
- la_dosmaperr(GetLastError());
- else if (attr & FILE_ATTRIBUTE_DIRECTORY)
- errno = EISDIR;
- else
- errno = EACCES;
- }
- free(ws);
- return (r);
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+ /* Simulate other POSIX system action to pass our test suite. */
+ attr = GetFileAttributesA(path);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ return (-1);
+ }
+ if (r >= 0 || errno != ENOENT)
+ return (r);
+ ws = __la_win_permissive_name(path);
+ if (ws == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ }
+ r = _wopen(ws, flags, pmode);
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+ /* Simulate other POSIX system action to pass our test suite. */
+ attr = GetFileAttributesW(ws);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ }
+ free(ws);
+ return (r);
}
ssize_t
__la_read(int fd, void *buf, size_t nbytes)
{
- HANDLE handle;
- DWORD bytes_read, lasterr;
- int r;
+ HANDLE handle;
+ DWORD bytes_read, lasterr;
+ int r;
#ifdef _WIN64
- if (nbytes > UINT32_MAX)
- nbytes = UINT32_MAX;
+ if (nbytes > UINT32_MAX)
+ nbytes = UINT32_MAX;
#endif
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- handle = (HANDLE)_get_osfhandle(fd);
- if (GetFileType(handle) == FILE_TYPE_PIPE) {
- DWORD sta;
- if (GetNamedPipeHandleState(
- handle, &sta, NULL, NULL, NULL, NULL, 0) != 0 &&
- (sta & PIPE_NOWAIT) == 0) {
- DWORD avail = -1;
- int cnt = 3;
-
- while (PeekNamedPipe(
- handle, NULL, 0, NULL, &avail, NULL) != 0 &&
- avail == 0 && --cnt)
- Sleep(100);
- if (avail == 0)
- return (0);
- }
- }
- r = ReadFile(handle, buf, (uint32_t)nbytes,
- &bytes_read, NULL);
- if (r == 0) {
- lasterr = GetLastError();
- if (lasterr == ERROR_NO_DATA) {
- errno = EAGAIN;
- return (-1);
- }
- if (lasterr == ERROR_BROKEN_PIPE)
- return (0);
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return ((ssize_t)bytes_read);
-}
-
-/* Remove directory */
-int
-__la_rmdir(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = _rmdir(path);
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = _wrmdir(ws);
- free(ws);
- return (r);
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ /* Do not pass 0 to third parameter of ReadFile(), read bytes.
+ * This will not return to application side. */
+ if (nbytes == 0)
+ return (0);
+ handle = (HANDLE)_get_osfhandle(fd);
+ r = ReadFile(handle, buf, (uint32_t)nbytes,
+ &bytes_read, NULL);
+ if (r == 0) {
+ lasterr = GetLastError();
+ if (lasterr == ERROR_NO_DATA) {
+ errno = EAGAIN;
+ return (-1);
+ }
+ if (lasterr == ERROR_BROKEN_PIPE)
+ return (0);
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return ((ssize_t)bytes_read);
}
/* Convert Windows FILETIME to UTC */
__inline static void
fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
{
- ULARGE_INTEGER utc;
+ ULARGE_INTEGER utc;
- utc.HighPart = filetime->dwHighDateTime;
- utc.LowPart = filetime->dwLowDateTime;
- if (utc.QuadPart >= EPOC_TIME) {
- utc.QuadPart -= EPOC_TIME;
- *time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
- *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
- } else {
- *time = 0;
- *ns = 0;
- }
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ *time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
}
/* Stat by handle
- * Windows' stat() does not accept path which is added "\\?\" especially "?"
+ * Windows' stat() does not accept the path added "\\?\" especially "?"
* character.
- * It means we cannot access a long name path(which is longer than MAX_PATH).
+ * It means we cannot access the long name path longer than MAX_PATH.
* So I've implemented simular Windows' stat() to access the long name path.
* And I've added some feature.
* 1. set st_ino by nFileIndexHigh and nFileIndexLow of
@@ -781,252 +454,240 @@ fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
static int
__hstat(HANDLE handle, struct ustat *st)
{
- BY_HANDLE_FILE_INFORMATION info;
- ULARGE_INTEGER ino64;
- DWORD ftype;
- mode_t mode;
- time_t time;
- long ns;
-
- switch (ftype = GetFileType(handle)) {
- case FILE_TYPE_UNKNOWN:
- errno = EBADF;
- return (-1);
- case FILE_TYPE_CHAR:
- case FILE_TYPE_PIPE:
- if (ftype == FILE_TYPE_CHAR) {
- st->st_mode = S_IFCHR;
- st->st_size = 0;
- } else {
- DWORD avail;
-
- st->st_mode = S_IFIFO;
- if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
- st->st_size = avail;
- else
- st->st_size = 0;
- }
- st->st_atime = 0;
- st->st_atime_nsec = 0;
- st->st_mtime = 0;
- st->st_mtime_nsec = 0;
- st->st_ctime = 0;
- st->st_ctime_nsec = 0;
- st->st_ino = 0;
- st->st_nlink = 1;
- st->st_uid = 0;
- st->st_gid = 0;
- st->st_rdev = 0;
- st->st_dev = 0;
- return (0);
- case FILE_TYPE_DISK:
- break;
- default:
- /* This ftype is undocumented type. */
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- ZeroMemory(&info, sizeof(info));
- if (!GetFileInformationByHandle (handle, &info)) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
-
- mode = S_IRUSR | S_IRGRP | S_IROTH;
- if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
- else
- mode |= S_IFREG;
- st->st_mode = mode;
-
- fileTimeToUTC(&info.ftLastAccessTime, &time, &ns);
- st->st_atime = time;
- st->st_atime_nsec = ns;
- fileTimeToUTC(&info.ftLastWriteTime, &time, &ns);
- st->st_mtime = time;
- st->st_mtime_nsec = ns;
- fileTimeToUTC(&info.ftCreationTime, &time, &ns);
- st->st_ctime = time;
- st->st_ctime_nsec = ns;
- st->st_size =
- ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
- + (int64_t)(info.nFileSizeLow);
+ BY_HANDLE_FILE_INFORMATION info;
+ ULARGE_INTEGER ino64;
+ DWORD ftype;
+ mode_t mode;
+ time_t time;
+ long ns;
+
+ switch (ftype = GetFileType(handle)) {
+ case FILE_TYPE_UNKNOWN:
+ errno = EBADF;
+ return (-1);
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_PIPE:
+ if (ftype == FILE_TYPE_CHAR) {
+ st->st_mode = S_IFCHR;
+ st->st_size = 0;
+ } else {
+ DWORD avail;
+
+ st->st_mode = S_IFIFO;
+ if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
+ st->st_size = avail;
+ else
+ st->st_size = 0;
+ }
+ st->st_atime = 0;
+ st->st_atime_nsec = 0;
+ st->st_mtime = 0;
+ st->st_mtime_nsec = 0;
+ st->st_ctime = 0;
+ st->st_ctime_nsec = 0;
+ st->st_ino = 0;
+ st->st_nlink = 1;
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_rdev = 0;
+ st->st_dev = 0;
+ return (0);
+ case FILE_TYPE_DISK:
+ break;
+ default:
+ /* This ftype is undocumented type. */
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ ZeroMemory(&info, sizeof(info));
+ if (!GetFileInformationByHandle (handle, &info)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else
+ mode |= S_IFREG;
+ st->st_mode = mode;
+
+ fileTimeToUTC(&info.ftLastAccessTime, &time, &ns);
+ st->st_atime = time;
+ st->st_atime_nsec = ns;
+ fileTimeToUTC(&info.ftLastWriteTime, &time, &ns);
+ st->st_mtime = time;
+ st->st_mtime_nsec = ns;
+ fileTimeToUTC(&info.ftCreationTime, &time, &ns);
+ st->st_ctime = time;
+ st->st_ctime_nsec = ns;
+ st->st_size =
+ ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+ + (int64_t)(info.nFileSizeLow);
#ifdef SIMULATE_WIN_STAT
- st->st_ino = 0;
- st->st_nlink = 1;
- st->st_dev = 0;
+ st->st_ino = 0;
+ st->st_nlink = 1;
+ st->st_dev = 0;
#else
- /* Getting FileIndex as i-node. We have to remove a sequence which
- * is high-16-bits of nFileIndexHigh. */
- ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
- ino64.LowPart = info.nFileIndexLow;
- st->st_ino = ino64.QuadPart;
- st->st_nlink = info.nNumberOfLinks;
- if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- ++st->st_nlink;/* Add parent directory. */
- st->st_dev = info.dwVolumeSerialNumber;
+ /* Getting FileIndex as i-node. We should remove a sequence which
+ * is high-16-bits of nFileIndexHigh. */
+ ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
+ ino64.LowPart = info.nFileIndexLow;
+ st->st_ino = ino64.QuadPart;
+ st->st_nlink = info.nNumberOfLinks;
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ++st->st_nlink;/* Add parent directory. */
+ st->st_dev = info.dwVolumeSerialNumber;
#endif
- st->st_uid = 0;
- st->st_gid = 0;
- st->st_rdev = 0;
- return (0);
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_rdev = 0;
+ return (0);
}
static void
copy_stat(struct stat *st, struct ustat *us)
{
- st->st_atime = us->st_atime;
- st->st_ctime = us->st_ctime;
- st->st_mtime = us->st_mtime;
- st->st_gid = us->st_gid;
- st->st_ino = getino(us);
- st->st_mode = us->st_mode;
- st->st_nlink = us->st_nlink;
- st->st_size = us->st_size;
- st->st_uid = us->st_uid;
- st->st_dev = us->st_dev;
- st->st_rdev = us->st_rdev;
+ st->st_atime = us->st_atime;
+ st->st_ctime = us->st_ctime;
+ st->st_mtime = us->st_mtime;
+ st->st_gid = us->st_gid;
+ st->st_ino = getino(us);
+ st->st_mode = us->st_mode;
+ st->st_nlink = us->st_nlink;
+ st->st_size = us->st_size;
+ st->st_uid = us->st_uid;
+ st->st_dev = us->st_dev;
+ st->st_rdev = us->st_rdev;
}
+/*
+ * TODO: Remove a use of __la_fstat and __la_stat.
+ * We should use GetFileInformationByHandle in place
+ * where We still use the *stat functions.
+ */
int
__la_fstat(int fd, struct stat *st)
{
- struct ustat u;
- int ret;
-
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
- if (ret >= 0) {
- copy_stat(st, &u);
- if (u.st_mode & (S_IFCHR | S_IFIFO)) {
- st->st_dev = fd;
- st->st_rdev = fd;
- }
- }
- return (ret);
-}
-
+ struct ustat u;
+ int ret;
+
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
+ if (ret >= 0) {
+ copy_stat(st, &u);
+ if (u.st_mode & (S_IFCHR | S_IFIFO)) {
+ st->st_dev = fd;
+ st->st_rdev = fd;
+ }
+ }
+ return (ret);
+}
+
+/* This can exceed MAX_PATH limitation. */
int
__la_stat(const char *path, struct stat *st)
{
- HANDLE handle;
- struct ustat u;
- int ret;
-
- handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
- NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ret = __hstat(handle, &u);
- CloseHandle(handle);
- if (ret >= 0) {
- char *p;
-
- copy_stat(st, &u);
- p = strrchr(path, '.');
- if (p != NULL && strlen(p) == 4) {
- char exttype[4];
-
- ++ p;
- exttype[0] = toupper(*p++);
- exttype[1] = toupper(*p++);
- exttype[2] = toupper(*p++);
- exttype[3] = '\0';
- if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
- !strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
- st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- }
- }
- return (ret);
-}
-
-int
-__la_unlink(const char *path)
-{
- wchar_t *ws;
- int r;
-
- r = _unlink(path);
- if (r >= 0 || errno != ENOENT)
- return (r);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = _wunlink(ws);
- free(ws);
- return (r);
+ HANDLE handle;
+ struct ustat u;
+ int ret;
+
+ handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ ret = __hstat(handle, &u);
+ CloseHandle(handle);
+ if (ret >= 0) {
+ char *p;
+
+ copy_stat(st, &u);
+ p = strrchr(path, '.');
+ if (p != NULL && strlen(p) == 4) {
+ char exttype[4];
+
+ ++ p;
+ exttype[0] = toupper(*p++);
+ exttype[1] = toupper(*p++);
+ exttype[2] = toupper(*p++);
+ exttype[3] = '\0';
+ if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
+ !strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
+ st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ }
+ }
+ return (ret);
}
/*
- * This waitpid is limited implemention.
+ * This waitpid is limited implementation.
*/
pid_t
__la_waitpid(pid_t wpid, int *status, int option)
{
- HANDLE child;
- DWORD cs, ret;
-
- (void)option;/* UNUSED */
- child = OpenProcess(PROCESS_ALL_ACCESS, FALSE, wpid);
- if (child == NULL) {
- la_dosmaperr(GetLastError());
- return (-1);
- }
- ret = WaitForSingleObject(child, INFINITE);
- if (ret == WAIT_FAILED) {
- CloseHandle(child);
- la_dosmaperr(GetLastError());
- return (-1);
- }
- if (GetExitCodeProcess(child, &cs) == 0) {
- CloseHandle(child);
- la_dosmaperr(GetLastError());
- return (-1);
- }
- if (cs == STILL_ACTIVE)
- *status = 0x100;
- else
- *status = (int)(cs & 0xff);
- CloseHandle(child);
- return (wpid);
+ HANDLE child;
+ DWORD cs, ret;
+
+ (void)option;/* UNUSED */
+ *status = 0;
+ child = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, wpid);
+ if (child == NULL) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ ret = WaitForSingleObject(child, INFINITE);
+ if (ret == WAIT_FAILED) {
+ CloseHandle(child);
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (GetExitCodeProcess(child, &cs) == 0) {
+ CloseHandle(child);
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (cs == STILL_ACTIVE)
+ *status = 0x100;
+ else
+ *status = (int)(cs & 0xff);
+ CloseHandle(child);
+ return (wpid);
}
ssize_t
__la_write(int fd, const void *buf, size_t nbytes)
{
- DWORD bytes_written;
+ DWORD bytes_written;
#ifdef _WIN64
- if (nbytes > UINT32_MAX)
- nbytes = UINT32_MAX;
+ if (nbytes > UINT32_MAX)
+ nbytes = UINT32_MAX;
#endif
- if (fd < 0) {
- errno = EBADF;
- return (-1);
- }
- if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
- &bytes_written, NULL)) {
- DWORD lasterr;
-
- lasterr = GetLastError();
- if (lasterr == ERROR_ACCESS_DENIED)
- errno = EBADF;
- else
- la_dosmaperr(lasterr);
- return (-1);
- }
- return (bytes_written);
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
+ &bytes_written, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return (bytes_written);
}
/*
@@ -1036,12 +697,12 @@ __la_write(int fd, const void *buf, size_t nbytes)
/*-------------------------------------------------------------------------
*
* win32error.c
- * Map win32 error codes to errno values
+ * Map win32 error codes to errno values
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1072,182 +733,81 @@ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
static const struct {
- DWORD winerr;
- int doserr;
+ DWORD winerr;
+ int doserr;
} doserrors[] =
{
- { ERROR_INVALID_FUNCTION, EINVAL },
- { ERROR_FILE_NOT_FOUND, ENOENT },
- { ERROR_PATH_NOT_FOUND, ENOENT },
- { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
- { ERROR_ACCESS_DENIED, EACCES },
- { ERROR_INVALID_HANDLE, EBADF },
- { ERROR_ARENA_TRASHED, ENOMEM },
- { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
- { ERROR_INVALID_BLOCK, ENOMEM },
- { ERROR_BAD_ENVIRONMENT, E2BIG },
- { ERROR_BAD_FORMAT, ENOEXEC },
- { ERROR_INVALID_ACCESS, EINVAL },
- { ERROR_INVALID_DATA, EINVAL },
- { ERROR_INVALID_DRIVE, ENOENT },
- { ERROR_CURRENT_DIRECTORY, EACCES },
- { ERROR_NOT_SAME_DEVICE, EXDEV },
- { ERROR_NO_MORE_FILES, ENOENT },
- { ERROR_LOCK_VIOLATION, EACCES },
- { ERROR_SHARING_VIOLATION, EACCES },
- { ERROR_BAD_NETPATH, ENOENT },
- { ERROR_NETWORK_ACCESS_DENIED, EACCES },
- { ERROR_BAD_NET_NAME, ENOENT },
- { ERROR_FILE_EXISTS, EEXIST },
- { ERROR_CANNOT_MAKE, EACCES },
- { ERROR_FAIL_I24, EACCES },
- { ERROR_INVALID_PARAMETER, EINVAL },
- { ERROR_NO_PROC_SLOTS, EAGAIN },
- { ERROR_DRIVE_LOCKED, EACCES },
- { ERROR_BROKEN_PIPE, EPIPE },
- { ERROR_DISK_FULL, ENOSPC },
- { ERROR_INVALID_TARGET_HANDLE, EBADF },
- { ERROR_INVALID_HANDLE, EINVAL },
- { ERROR_WAIT_NO_CHILDREN, ECHILD },
- { ERROR_CHILD_NOT_COMPLETE, ECHILD },
- { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
- { ERROR_NEGATIVE_SEEK, EINVAL },
- { ERROR_SEEK_ON_DEVICE, EACCES },
- { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
- { ERROR_NOT_LOCKED, EACCES },
- { ERROR_BAD_PATHNAME, ENOENT },
- { ERROR_MAX_THRDS_REACHED, EAGAIN },
- { ERROR_LOCK_FAILED, EACCES },
- { ERROR_ALREADY_EXISTS, EEXIST },
- { ERROR_FILENAME_EXCED_RANGE, ENOENT },
- { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
- { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
+ { ERROR_INVALID_FUNCTION, EINVAL },
+ { ERROR_FILE_NOT_FOUND, ENOENT },
+ { ERROR_PATH_NOT_FOUND, ENOENT },
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
+ { ERROR_ACCESS_DENIED, EACCES },
+ { ERROR_INVALID_HANDLE, EBADF },
+ { ERROR_ARENA_TRASHED, ENOMEM },
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
+ { ERROR_INVALID_BLOCK, ENOMEM },
+ { ERROR_BAD_ENVIRONMENT, E2BIG },
+ { ERROR_BAD_FORMAT, ENOEXEC },
+ { ERROR_INVALID_ACCESS, EINVAL },
+ { ERROR_INVALID_DATA, EINVAL },
+ { ERROR_INVALID_DRIVE, ENOENT },
+ { ERROR_CURRENT_DIRECTORY, EACCES },
+ { ERROR_NOT_SAME_DEVICE, EXDEV },
+ { ERROR_NO_MORE_FILES, ENOENT },
+ { ERROR_LOCK_VIOLATION, EACCES },
+ { ERROR_SHARING_VIOLATION, EACCES },
+ { ERROR_BAD_NETPATH, ENOENT },
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES },
+ { ERROR_BAD_NET_NAME, ENOENT },
+ { ERROR_FILE_EXISTS, EEXIST },
+ { ERROR_CANNOT_MAKE, EACCES },
+ { ERROR_FAIL_I24, EACCES },
+ { ERROR_INVALID_PARAMETER, EINVAL },
+ { ERROR_NO_PROC_SLOTS, EAGAIN },
+ { ERROR_DRIVE_LOCKED, EACCES },
+ { ERROR_BROKEN_PIPE, EPIPE },
+ { ERROR_DISK_FULL, ENOSPC },
+ { ERROR_INVALID_TARGET_HANDLE, EBADF },
+ { ERROR_INVALID_HANDLE, EINVAL },
+ { ERROR_WAIT_NO_CHILDREN, ECHILD },
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD },
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
+ { ERROR_NEGATIVE_SEEK, EINVAL },
+ { ERROR_SEEK_ON_DEVICE, EACCES },
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
+ { ERROR_NOT_LOCKED, EACCES },
+ { ERROR_BAD_PATHNAME, ENOENT },
+ { ERROR_MAX_THRDS_REACHED, EAGAIN },
+ { ERROR_LOCK_FAILED, EACCES },
+ { ERROR_ALREADY_EXISTS, EEXIST },
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT },
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
};
-static void
-la_dosmaperr(unsigned long e)
-{
- int i;
-
- if (e == 0)
- {
- errno = 0;
- return;
- }
-
- for (i = 0; i < sizeof(doserrors); i++)
- {
- if (doserrors[i].winerr == e)
- {
- errno = doserrors[i].doserr;
- return;
- }
- }
-
- /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
- errno = EINVAL;
- return;
-}
-
-#if !defined(HAVE_OPENSSL_MD5_H) && !defined(HAVE_OPENSSL_SHA_H)
-/*
- * Message digest functions.
- */
-static void
-Digest_Init(Digest_CTX *ctx, ALG_ID algId)
-{
-
- ctx->valid = 0;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, 0)) {
- if (GetLastError() != NTE_BAD_KEYSET)
- return;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET))
- return;
- }
-
- if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
- CryptReleaseContext(ctx->cryptProv, 0);
- return;
- }
-
- ctx->valid = 1;
-}
-
-static void
-Digest_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
-{
-
- if (!ctx->valid)
- return;
-
- CryptHashData(ctx->hash,
- (unsigned char *)(uintptr_t)buf,
- (DWORD)len, 0);
-}
-
-static void
-Digest_Final(unsigned char *buf, int bufsize, Digest_CTX *ctx)
+void
+__la_dosmaperr(unsigned long e)
{
- DWORD siglen = bufsize;
-
- if (!ctx->valid)
- return;
-
- CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- CryptDestroyHash(ctx->hash);
- CryptReleaseContext(ctx->cryptProv, 0);
- ctx->valid = 0;
-}
+ int i;
-#define DIGEST_INIT(name, algid) \
-void name ## _Init(Digest_CTX *ctx)\
-{\
- Digest_Init(ctx, algid);\
-}
+ if (e == 0)
+ {
+ errno = 0;
+ return;
+ }
-#define DIGEST_UPDATE(name) \
-void name ## _Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)\
-{\
- Digest_Update(ctx, buf, len);\
-}
+ for (i = 0; i < sizeof(doserrors); i++)
+ {
+ if (doserrors[i].winerr == e)
+ {
+ errno = doserrors[i].doserr;
+ return;
+ }
+ }
-#define DIGEST_FINAL(name, size) \
-void name ## _Final(unsigned char buf[size], Digest_CTX *ctx)\
-{\
- Digest_Final(buf, size, ctx);\
+ /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+ errno = EINVAL;
+ return;
}
-DIGEST_INIT(MD5, CALG_MD5)
-DIGEST_UPDATE(MD5)
-DIGEST_FINAL(MD5, MD5_DIGEST_LENGTH)
-
-DIGEST_INIT(SHA1, CALG_SHA1)
-DIGEST_UPDATE(SHA1)
-DIGEST_FINAL(SHA1, SHA1_DIGEST_LENGTH)
-
-/*
- * SHA256 nor SHA384 nor SHA512 are not supported on Windows XP and Windows 2000.
- */
-#ifdef CALG_SHA256
-DIGEST_INIT(SHA256, CALG_SHA256)
-DIGEST_UPDATE(SHA256)
-DIGEST_FINAL(SHA256, SHA256_DIGEST_LENGTH)
-#endif
-
-#ifdef CALG_SHA384
-DIGEST_INIT(SHA384, CALG_SHA384)
-DIGEST_UPDATE(SHA384)
-DIGEST_FINAL(SHA384, SHA384_DIGEST_LENGTH)
-#endif
-
-#ifdef CALG_SHA512
-DIGEST_INIT(SHA512, CALG_SHA512)
-DIGEST_UPDATE(SHA512)
-DIGEST_FINAL(SHA512, SHA384_DIGEST_LENGTH)
-#endif
-
-#endif /* !HAVE_OPENSSL_MD5_H && !HAVE_OPENSSL_SHA_H */
-
#endif /* _WIN32 && !__CYGWIN__ */