X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fwin32%2Fcompat%2Fcompat.cpp;h=e93ce9c45b39d3beb4d2fc3f13f724f1892c5b7e;hb=a33d3671776f81795bb6bd649572d845a4bcea10;hp=152dc23b1a011eae72eb6533fbe8dd763b487c57;hpb=f815c961561470cc92aa3173a1e01b19d8bd4846;p=bacula%2Fbacula diff --git a/bacula/src/win32/compat/compat.cpp b/bacula/src/win32/compat/compat.cpp index 152dc23b1a..e93ce9c45b 100644 --- a/bacula/src/win32/compat/compat.cpp +++ b/bacula/src/win32/compat/compat.cpp @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -40,6 +40,7 @@ #include "bacula.h" #include "compat.h" #include "jcr.h" +#include "findlib/find.h" #define b_errno_win32 (1<<29) @@ -532,11 +533,6 @@ int fcntl(int fd, int cmd) return 0; } -int chmod(const char *, mode_t) -{ - return 0; -} - int chown(const char *k, uid_t, gid_t) { return 0; @@ -644,6 +640,7 @@ statDir(const char *file, struct stat *sb) sb->st_ctime = now; sb->st_mtime = now; sb->st_atime = now; + sb->st_rdev = 0; return 0; } @@ -654,6 +651,7 @@ statDir(const char *file, struct stat *sb) POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, file); + Dmsg1(100, "FindFirstFileW=%s\n", file); h = p_FindFirstFileW((LPCWSTR)pwszBuf, &info_w); free_pool_memory(pwszBuf); @@ -667,6 +665,7 @@ statDir(const char *file, struct stat *sb) // use ASCII } else if (p_FindFirstFileA) { + Dmsg1(100, "FindFirstFileA=%s\n", file); h = p_FindFirstFileA(file, &info_a); pdwFileAttributes = &info_a.dwFileAttributes; @@ -676,14 +675,22 @@ statDir(const char *file, struct stat *sb) pftLastAccessTime = &info_a.ftLastAccessTime; pftLastWriteTime = &info_a.ftLastWriteTime; pftCreationTime = &info_a.ftCreationTime; + } else { + Dmsg0(100, "No findFirstFile A or W found\n"); } if (h == INVALID_HANDLE_VALUE) { const char *err = errorString(); - Dmsg2(99, "FindFirstFile(%s):%s\n", file, err); + /* + * Note, in creating leading paths, it is normal that + * the file does not exist. + */ + Dmsg2(2099, "FindFirstFile(%s):%s\n", file, err); LocalFree((void *)err); errno = b_errno_win32; return -1; + } else { + FindClose(h); } sb->st_mode = 0777; /* start with everything */ @@ -695,12 +702,23 @@ statDir(const char *file, struct stat *sb) sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */ sb->st_mode |= S_IFDIR; - /* Use st_rdev to store reparse attribute */ - sb->st_rdev = (*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; - if (sb->st_rdev == 1 && *pdwReserved0 & IO_REPARSE_TAG_MOUNT_POINT) { - sb->st_rdev = 2; /* mount point */ - } - + /* + * Store reparse/mount point info in st_rdev. Note a + * Win32 reparse point (junction point) is like a link + * though it can have many properties (directory link, + * soft link, hard link, HSM, ... + * A mount point is a reparse point where another volume + * is mounted, so it is like a Unix mount point (change of + * filesystem). + */ + if (*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (*pdwReserved0 & IO_REPARSE_TAG_MOUNT_POINT) { + sb->st_rdev = WIN32_MOUNT_POINT; /* mount point */ + } else { + sb->st_rdev = WIN32_REPARSE_POINT; /* reparse point */ + } + } + Dmsg2(100, "st_rdev=%d file=%s\n", sb->st_rdev, file); sb->st_size = *pnFileSizeHigh; sb->st_size <<= 32; sb->st_size |= *pnFileSizeLow; @@ -710,20 +728,18 @@ statDir(const char *file, struct stat *sb) sb->st_atime = cvt_ftime_to_utime(*pftLastAccessTime); sb->st_mtime = cvt_ftime_to_utime(*pftLastWriteTime); sb->st_ctime = cvt_ftime_to_utime(*pftCreationTime); - FindClose(h); return 0; } int -fstat(int fd, struct stat *sb) +fstat(intptr_t fd, struct stat *sb) { BY_HANDLE_FILE_INFORMATION info; - char tmpbuf[1024]; - if (!GetFileInformationByHandle((HANDLE)fd, &info)) { + if (!GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) { const char *err = errorString(); - Dmsg2(99, "GetfileInformationByHandle(%s): %s\n", tmpbuf, err); + Dmsg1(2099, "GetfileInformationByHandle: %s\n", err); LocalFree((void *)err); errno = b_errno_win32; return -1; @@ -748,7 +764,11 @@ fstat(int fd, struct stat *sb) sb->st_mode |= S_IFREG; /* Use st_rdev to store reparse attribute */ - sb->st_rdev = (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; + if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + sb->st_rdev = WIN32_REPARSE_POINT; + } + Dmsg3(100, "st_rdev=%d sizino=%d ino=%lld\n", sb->st_rdev, sizeof(sb->st_ino), + (long long)sb->st_ino); sb->st_size = info.nFileSizeHigh; sb->st_size <<= 32; @@ -765,10 +785,10 @@ fstat(int fd, struct stat *sb) static int stat2(const char *file, struct stat *sb) { - HANDLE h; + HANDLE h = INVALID_HANDLE_VALUE; int rval = 0; - char tmpbuf[1024]; - conv_unix_to_win32_path(file, tmpbuf, 1024); + char tmpbuf[5000]; + conv_unix_to_win32_path(file, tmpbuf, 5000); DWORD attr = (DWORD)-1; @@ -777,38 +797,43 @@ stat2(const char *file, struct stat *sb) make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf); attr = p_GetFileAttributesW((LPCWSTR) pwszBuf); + if (p_CreateFileW) { + h = CreateFileW((LPCWSTR)pwszBuf, GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + } free_pool_memory(pwszBuf); } else if (p_GetFileAttributesA) { attr = p_GetFileAttributesA(tmpbuf); + h = CreateFileA(tmpbuf, GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } if (attr == (DWORD)-1) { const char *err = errorString(); - Dmsg2(99, "GetFileAttributes(%s): %s\n", tmpbuf, err); + Dmsg2(2099, "GetFileAttributes(%s): %s\n", tmpbuf, err); LocalFree((void *)err); + if (h != INVALID_HANDLE_VALUE) { + CloseHandle(h); + } errno = b_errno_win32; return -1; } - h = CreateFileA(tmpbuf, GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (h == INVALID_HANDLE_VALUE) { const char *err = errorString(); - Dmsg2(99, "Cannot open file for stat (%s):%s\n", tmpbuf, err); + Dmsg2(2099, "Cannot open file for stat (%s):%s\n", tmpbuf, err); LocalFree((void *)err); errno = b_errno_win32; return -1; } - rval = fstat((int)h, sb); + rval = fstat((intptr_t)h, sb); CloseHandle(h); if (attr & FILE_ATTRIBUTE_DIRECTORY && file[1] == ':' && file[2] != 0) { - statDir(file, sb); + rval = statDir(file, sb); } - return rval; } @@ -818,12 +843,11 @@ stat(const char *file, struct stat *sb) WIN32_FILE_ATTRIBUTE_DATA data; errno = 0; - memset(sb, 0, sizeof(*sb)); if (p_GetFileAttributesExW) { /* dynamically allocate enough space for UCS2 filename */ - POOLMEM* pwszBuf = get_pool_memory (PM_FNAME); + POOLMEM *pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, file); BOOL b = p_GetFileAttributesExW((LPCWSTR)pwszBuf, GetFileExInfoStandard, &data); @@ -832,6 +856,7 @@ stat(const char *file, struct stat *sb) if (!b) { return stat2(file, sb); } + } else if (p_GetFileAttributesExA) { if (!p_GetFileAttributesExA(file, GetFileExInfoStandard, &data)) { return stat2(file, sb); @@ -881,6 +906,8 @@ stat(const char *file, struct stat *sb) file[1] == ':' && file[2] != 0) { statDir(file, sb); } + Dmsg3(100, "sizino=%d ino=%lld file=%s\n", sizeof(sb->st_ino), + (long long)sb->st_ino, file); return 0; } @@ -1337,6 +1364,73 @@ WSA_Init(void) return 0; } +int win32_chmod(const char *path, mode_t mode) +{ + DWORD attr = (DWORD)-1; + + Dmsg1(100, "Enter win32_chmod. path=%s\n", path); + if (p_GetFileAttributesW) { + POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); + make_win32_path_UTF8_2_wchar(&pwszBuf, path); + + attr = p_GetFileAttributesW((LPCWSTR) pwszBuf); + if (attr != INVALID_FILE_ATTRIBUTES) { + /* Use Bacula mappings define in stat() above */ + if (mode & (S_IRUSR|S_IRGRP|S_IROTH)) { + attr |= FILE_ATTRIBUTE_READONLY; + } else { + attr &= ~FILE_ATTRIBUTE_READONLY; + } + if (mode & S_ISVTX) { + attr |= FILE_ATTRIBUTE_HIDDEN; + } else { + attr &= ~FILE_ATTRIBUTE_HIDDEN; + } + if (mode & S_IRWXO) { + attr |= FILE_ATTRIBUTE_SYSTEM; + } else { + attr &= ~FILE_ATTRIBUTE_SYSTEM; + } + attr = p_SetFileAttributesW((LPCWSTR)pwszBuf, attr); + } + free_pool_memory(pwszBuf); + Dmsg0(100, "Leave win32_chmod. AttributesW\n"); + } else if (p_GetFileAttributesA) { + if (mode & (S_IRUSR|S_IRGRP|S_IROTH)) { + attr |= FILE_ATTRIBUTE_READONLY; + } else { + attr &= ~FILE_ATTRIBUTE_READONLY; + } + if (mode & S_ISVTX) { + attr |= FILE_ATTRIBUTE_HIDDEN; + } else { + attr &= ~FILE_ATTRIBUTE_HIDDEN; + } + if (mode & S_IRWXO) { + attr |= FILE_ATTRIBUTE_SYSTEM; + } else { + attr &= ~FILE_ATTRIBUTE_SYSTEM; + } + attr = p_GetFileAttributesA(path); + if (attr != INVALID_FILE_ATTRIBUTES) { + attr = p_SetFileAttributesA(path, attr); + } + Dmsg0(100, "Leave win32_chmod did AttributesA\n"); + } else { + Dmsg0(100, "Leave win32_chmod did nothing\n"); + } + + + if (attr == (DWORD)-1) { + const char *err = errorString(); + Dmsg2(99, "Get/SetFileAttributes(%s): %s\n", path, err); + LocalFree((void *)err); + errno = b_errno_win32; + return -1; + } + return 0; +} + int win32_chdir(const char *dir) @@ -1353,14 +1447,14 @@ win32_chdir(const char *dir) errno = b_errno_win32; return -1; } - } - else if (p_SetCurrentDirectoryA) { + } else if (p_SetCurrentDirectoryA) { if (0 == p_SetCurrentDirectoryA(dir)) { errno = b_errno_win32; return -1; } + } else { + return -1; } - else return -1; return 0; } @@ -1368,15 +1462,18 @@ win32_chdir(const char *dir) int win32_mkdir(const char *dir) { + Dmsg1(100, "enter win32_mkdir. dir=%s\n", dir); if (p_wmkdir){ POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, dir); int n = p_wmkdir((LPCWSTR)pwszBuf); free_pool_memory(pwszBuf); + Dmsg0(100, "Leave win32_mkdir did wmkdir\n"); return n; } + Dmsg0(100, "Leave win32_mkdir did _mkdir\n"); return _mkdir(dir); } @@ -1519,8 +1616,10 @@ win32_unlink(const char *filename) nRetCode = _wunlink((LPCWSTR) pwszBuf); - /* special case if file is readonly, - we retry but unset attribute before */ + /* + * special case if file is readonly, + * we retry but unset attribute before + */ if (nRetCode == -1 && errno == EACCES && p_SetFileAttributesW && p_GetFileAttributesW) { DWORD dwAttr = p_GetFileAttributesW((LPCWSTR)pwszBuf); if (dwAttr != INVALID_FILE_ATTRIBUTES) { @@ -1828,6 +1927,96 @@ GetApplicationName(const char *cmdline, char **pexe, const char **pargs) return true; } +/** + * Create the process with WCHAR API + */ +static BOOL +CreateChildProcessW(const char *comspec, const char *cmdLine, + PROCESS_INFORMATION *hProcInfo, + HANDLE in, HANDLE out, HANDLE err) +{ + STARTUPINFOW siStartInfo; + BOOL bFuncRetn = FALSE; + + // Set up members of the STARTUPINFO structure. + ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); + siStartInfo.cb = sizeof(siStartInfo); + // setup new process to use supplied handles for stdin,stdout,stderr + + siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; + + siStartInfo.hStdInput = in; + siStartInfo.hStdOutput = out; + siStartInfo.hStdError = err; + + // Convert argument to WCHAR + POOLMEM *cmdLine_wchar = get_pool_memory(PM_FNAME); + POOLMEM *comspec_wchar = get_pool_memory(PM_FNAME); + + UTF8_2_wchar(&cmdLine_wchar, cmdLine); + UTF8_2_wchar(&comspec_wchar, comspec); + + // Create the child process. + Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar); + + // try to execute program + bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar, + (WCHAR*)cmdLine_wchar,// command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + hProcInfo); // receives PROCESS_INFORMATION + free_pool_memory(cmdLine_wchar); + free_pool_memory(comspec_wchar); + + return bFuncRetn; +} + + +/** + * Create the process with ANSI API + */ +static BOOL +CreateChildProcessA(const char *comspec, char *cmdLine, + PROCESS_INFORMATION *hProcInfo, + HANDLE in, HANDLE out, HANDLE err) +{ + STARTUPINFOA siStartInfo; + BOOL bFuncRetn = FALSE; + + // Set up members of the STARTUPINFO structure. + ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); + siStartInfo.cb = sizeof(siStartInfo); + // setup new process to use supplied handles for stdin,stdout,stderr + siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; + + siStartInfo.hStdInput = in; + siStartInfo.hStdOutput = out; + siStartInfo.hStdError = err; + + // Create the child process. + Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); + + // try to execute program + bFuncRetn = p_CreateProcessA(comspec, + cmdLine, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo,// STARTUPINFO pointer + hProcInfo);// receives PROCESS_INFORMATION + return bFuncRetn; +} + /** * OK, so it would seem CreateProcess only handles true executables: * .com or .exe files. So grab $COMSPEC value and pass command line to it. @@ -1837,43 +2026,29 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err) { static const char *comspec = NULL; PROCESS_INFORMATION piProcInfo; - STARTUPINFOA siStartInfo; BOOL bFuncRetn = FALSE; - if (comspec == NULL) { + if (!p_CreateProcessA || !p_CreateProcessW) + return INVALID_HANDLE_VALUE; + + if (comspec == NULL) comspec = getenv("COMSPEC"); - } if (comspec == NULL) // should never happen return INVALID_HANDLE_VALUE; // Set up members of the PROCESS_INFORMATION structure. ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); - // Set up members of the STARTUPINFO structure. - - ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); - siStartInfo.cb = sizeof(STARTUPINFO); - // setup new process to use supplied handles for stdin,stdout,stderr // if supplied handles are not used the send a copy of our STD_HANDLE // as appropriate - siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; - - if (in != INVALID_HANDLE_VALUE) - siStartInfo.hStdInput = in; - else - siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + if (in == INVALID_HANDLE_VALUE) + in = GetStdHandle(STD_INPUT_HANDLE); - if (out != INVALID_HANDLE_VALUE) - siStartInfo.hStdOutput = out; - else - siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); - if (err != INVALID_HANDLE_VALUE) - siStartInfo.hStdError = err; - else - siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); + if (out == INVALID_HANDLE_VALUE) + out = GetStdHandle(STD_OUTPUT_HANDLE); - // Create the child process. + if (err == INVALID_HANDLE_VALUE) + err = GetStdHandle(STD_ERROR_HANDLE); char *exeFile; const char *argStart; @@ -1882,43 +2057,33 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err) return INVALID_HANDLE_VALUE; } - int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1; - - char *cmdLine = (char *)alloca(cmdLen); - - snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart); + POOL_MEM cmdLine(PM_FNAME); + Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart); free(exeFile); - Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); - - // try to execute program - bFuncRetn = CreateProcessA(comspec, - cmdLine, // command line - NULL, // process security attributes - NULL, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - NULL, // use parent's environment - NULL, // use parent's current directory - &siStartInfo, // STARTUPINFO pointer - &piProcInfo); // receives PROCESS_INFORMATION + // New function disabled + if (p_CreateProcessW && p_MultiByteToWideChar) { + bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo, + in, out, err); + } else { + bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo, + in, out, err); + } if (bFuncRetn == 0) { ErrorExit("CreateProcess failed\n"); const char *err = errorString(); - Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", comspec, cmdLine, err); + Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err); LocalFree((void *)err); return INVALID_HANDLE_VALUE; } // we don't need a handle on the process primary thread so we close // this now. CloseHandle(piProcInfo.hThread); - return piProcInfo.hProcess; } - void ErrorExit (LPCSTR lpszMessage) { @@ -2036,7 +2201,7 @@ open_bpipe(char *prog, int wait, const char *mode) // process terminates we can // detect eof. // ugly but convert WIN32 HANDLE to FILE* - int rfd = _open_osfhandle((long)hChildStdoutRdDup, O_RDONLY | O_BINARY); + int rfd = _open_osfhandle((intptr_t)hChildStdoutRdDup, O_RDONLY | O_BINARY); if (rfd >= 0) { bpipe->rfd = _fdopen(rfd, "rb"); } @@ -2045,7 +2210,7 @@ open_bpipe(char *prog, int wait, const char *mode) CloseHandle(hChildStdinRd); // close our read side so as not // to interfre with child's copy // ugly but convert WIN32 HANDLE to FILE* - int wfd = _open_osfhandle((long)hChildStdinWrDup, O_WRONLY | O_BINARY); + int wfd = _open_osfhandle((intptr_t)hChildStdinWrDup, O_WRONLY | O_BINARY); if (wfd >= 0) { bpipe->wfd = _fdopen(wfd, "wb"); } @@ -2151,8 +2316,7 @@ close_wpipe(BPIPE *bpipe) return result; } -#include "findlib/find.h" - +#ifndef MINGW64 int utime(const char *fname, struct utimbuf *times) { @@ -2167,10 +2331,10 @@ utime(const char *fname, struct utimbuf *times) HANDLE h = INVALID_HANDLE_VALUE; if (p_CreateFileW) { - POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); - make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf); + POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); + make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf); - h = p_CreateFileW((LPCWSTR)pwszBuf, + h = p_CreateFileW((LPCWSTR)pwszBuf, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, @@ -2178,9 +2342,9 @@ utime(const char *fname, struct utimbuf *times) FILE_FLAG_BACKUP_SEMANTICS, // required for directories NULL); - free_pool_memory(pwszBuf); + free_pool_memory(pwszBuf); } else if (p_CreateFileA) { - h = p_CreateFileA(tmpbuf, + h = p_CreateFileA(tmpbuf, FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, @@ -2190,11 +2354,11 @@ utime(const char *fname, struct utimbuf *times) } if (h == INVALID_HANDLE_VALUE) { - const char *err = errorString(); - Dmsg2(99, "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err); - LocalFree((void *)err); - errno = b_errno_win32; - return -1; + const char *err = errorString(); + Dmsg2(99, "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err); + LocalFree((void *)err); + errno = b_errno_win32; + return -1; } int rval = SetFileTime(h, NULL, &acc, &mod) ? 0 : -1; @@ -2204,54 +2368,55 @@ utime(const char *fname, struct utimbuf *times) } return rval; } +#endif #if 0 int file_open(const char *file, int flags, int mode) { - DWORD access = 0; - DWORD shareMode = 0; - DWORD create = 0; - DWORD msflags = 0; - HANDLE foo = INVALID_HANDLE_VALUE; - const char *remap = file; - - if (flags & O_WRONLY) access = GENERIC_WRITE; - else if (flags & O_RDWR) access = GENERIC_READ|GENERIC_WRITE; - else access = GENERIC_READ; - - if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) - create = CREATE_NEW; - else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) - create = CREATE_ALWAYS; - else if (flags & O_CREAT) - create = OPEN_ALWAYS; - else if (flags & O_TRUNC) - create = TRUNCATE_EXISTING; - else - create = OPEN_EXISTING; - - shareMode = 0; - - if (flags & O_APPEND) { - printf("open...APPEND not implemented yet."); - exit(-1); - } + DWORD access = 0; + DWORD shareMode = 0; + DWORD create = 0; + DWORD msflags = 0; + HANDLE foo = INVALID_HANDLE_VALUE; + const char *remap = file; + + if (flags & O_WRONLY) access = GENERIC_WRITE; + else if (flags & O_RDWR) access = GENERIC_READ|GENERIC_WRITE; + else access = GENERIC_READ; + + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) + create = CREATE_NEW; + else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) + create = CREATE_ALWAYS; + else if (flags & O_CREAT) + create = OPEN_ALWAYS; + else if (flags & O_TRUNC) + create = TRUNCATE_EXISTING; + else + create = OPEN_EXISTING; + + shareMode = 0; + + if (flags & O_APPEND) { + printf("open...APPEND not implemented yet."); + exit(-1); + } - if (p_CreateFileW) { - POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); - make_win32_path_UTF8_2_wchar(&pwszBuf, file); + if (p_CreateFileW) { + POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); + make_win32_path_UTF8_2_wchar(&pwszBuf, file); - foo = p_CreateFileW((LPCWSTR) pwszBuf, access, shareMode, NULL, create, msflags, NULL); - free_pool_memory(pwszBuf); - } else if (p_CreateFileA) - foo = CreateFile(file, access, shareMode, NULL, create, msflags, NULL); + foo = p_CreateFileW((LPCWSTR) pwszBuf, access, shareMode, NULL, create, msflags, NULL); + free_pool_memory(pwszBuf); + } else if (p_CreateFileA) + foo = CreateFile(file, access, shareMode, NULL, create, msflags, NULL); - if (INVALID_HANDLE_VALUE == foo) { - errno = b_errno_win32; - return(int) -1; - } - return (int)foo; + if (INVALID_HANDLE_VALUE == foo) { + errno = b_errno_win32; + return (int)-1; + } + return (int)foo; } @@ -2331,6 +2496,72 @@ file_dup2(int, int) } #endif +#ifdef xxx +/* + * Emulation of mmap and unmmap for tokyo dbm + */ +void *mmap(void *start, size_t length, int prot, int flags, + int fd, off_t offset) +{ + DWORD fm_access = 0; + DWORD mv_access = 0; + HANDLE h; + HANDLE mv; + + if (length == 0) { + return MAP_FAILED; + } + if (!fd) { + return MAP_FAILED; + } + + if (flags & PROT_WRITE) { + fm_access |= PAGE_READWRITE; + } else if (flags & PROT_READ) { + fm_access |= PAGE_READONLY; + } + + if (flags & PROT_READ) { + mv_access |= FILE_MAP_READ; + } + if (flags & PROT_WRITE) { + mv_access |= FILE_MAP_WRITE; + } + + h = CreateFileMapping((HANDLE)_get_osfhandle (fd), + NULL /* security */, + fm_access, + 0 /* MaximumSizeHigh */, + 0 /* MaximumSizeLow */, + NULL /* name of the file mapping object */); + + if (!h || h == INVALID_HANDLE_VALUE) { + return MAP_FAILED; + } + + mv = MapViewOfFile(h, mv_access, + 0 /* offset hi */, + 0 /* offset lo */, + length); + CloseHandle(h); + + if (!mv || mv == INVALID_HANDLE_VALUE) { + return MAP_FAILED; + } + + return (void *) mv; +} + +int munmap(void *start, size_t length) +{ + if (!start) { + return -1; + } + UnmapViewOfFile(start); + return 0; +} +#endif + #ifdef HAVE_MINGW /* syslog function, added by Nicolas Boichat */ void openlog(const char *ident, int option, int facility) {}