X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=os%2Fwindows%2Fposix.c;h=41fc480df9f14f92a75ff07a5fda30fa098deb06;hb=1246147d5402d46ecb098dc06c9b31bf6810800c;hp=8a52a6849e4b4083b5d6ba0a6c787346714890a7;hpb=01d269552bca14c90bdcc2288e64ba2426c045ea;p=fio.git diff --git a/os/windows/posix.c b/os/windows/posix.c index 8a52a684..41fc480d 100755 --- a/os/windows/posix.c +++ b/os/windows/posix.c @@ -12,12 +12,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include "../os-windows.h" #include "../../lib/hweight.h" @@ -43,6 +46,81 @@ int vsprintf_s( const char *format, va_list argptr); +int win_to_posix_error(DWORD winerr) +{ + switch (winerr) + { + case ERROR_FILE_NOT_FOUND: return ENOENT; + case ERROR_PATH_NOT_FOUND: return ENOENT; + case ERROR_ACCESS_DENIED: return EACCES; + case ERROR_INVALID_HANDLE: return EBADF; + case ERROR_NOT_ENOUGH_MEMORY: return ENOMEM; + case ERROR_INVALID_DATA: return EINVAL; + case ERROR_OUTOFMEMORY: return ENOMEM; + case ERROR_INVALID_DRIVE: return ENODEV; + case ERROR_NOT_SAME_DEVICE: return EXDEV; + case ERROR_WRITE_PROTECT: return EROFS; + case ERROR_BAD_UNIT: return ENODEV; + case ERROR_SHARING_VIOLATION: return EACCES; + case ERROR_LOCK_VIOLATION: return EACCES; + case ERROR_SHARING_BUFFER_EXCEEDED: return ENOLCK; + case ERROR_HANDLE_DISK_FULL: return ENOSPC; + case ERROR_NOT_SUPPORTED: return ENOSYS; + case ERROR_FILE_EXISTS: return EEXIST; + case ERROR_CANNOT_MAKE: return EPERM; + case ERROR_INVALID_PARAMETER: return EINVAL; + case ERROR_NO_PROC_SLOTS: return EAGAIN; + case ERROR_BROKEN_PIPE: return EPIPE; + case ERROR_OPEN_FAILED: return EIO; + case ERROR_NO_MORE_SEARCH_HANDLES: return ENFILE; + case ERROR_CALL_NOT_IMPLEMENTED: return ENOSYS; + case ERROR_INVALID_NAME: return ENOENT; + case ERROR_WAIT_NO_CHILDREN: return ECHILD; + case ERROR_CHILD_NOT_COMPLETE: return EBUSY; + case ERROR_DIR_NOT_EMPTY: return ENOTEMPTY; + case ERROR_SIGNAL_REFUSED: return EIO; + case ERROR_BAD_PATHNAME: return ENOENT; + case ERROR_SIGNAL_PENDING: return EBUSY; + case ERROR_MAX_THRDS_REACHED: return EAGAIN; + case ERROR_BUSY: return EBUSY; + case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_NO_SIGNAL_SENT: return EIO; + case ERROR_FILENAME_EXCED_RANGE: return EINVAL; + case ERROR_META_EXPANSION_TOO_LONG: return EINVAL; + case ERROR_INVALID_SIGNAL_NUMBER: return EINVAL; + case ERROR_THREAD_1_INACTIVE: return EINVAL; + case ERROR_BAD_PIPE: return EINVAL; + case ERROR_PIPE_BUSY: return EBUSY; + case ERROR_NO_DATA: return EPIPE; + case ERROR_MORE_DATA: return EAGAIN; + case ERROR_DIRECTORY: return ENOTDIR; + case ERROR_PIPE_CONNECTED: return EBUSY; + case ERROR_NO_TOKEN: return EINVAL; + case ERROR_PROCESS_ABORTED: return EFAULT; + case ERROR_BAD_DEVICE: return ENODEV; + case ERROR_BAD_USERNAME: return EINVAL; + case ERROR_OPEN_FILES: return EAGAIN; + case ERROR_ACTIVE_CONNECTIONS: return EAGAIN; + case ERROR_DEVICE_IN_USE: return EAGAIN; + case ERROR_INVALID_AT_INTERRUPT_TIME: return EINTR; + case ERROR_IO_DEVICE: return EIO; + case ERROR_NOT_OWNER: return EPERM; + case ERROR_END_OF_MEDIA: return ENOSPC; + case ERROR_EOM_OVERFLOW: return ENOSPC; + case ERROR_BEGINNING_OF_MEDIA: return ESPIPE; + case ERROR_SETMARK_DETECTED: return ESPIPE; + case ERROR_NO_DATA_DETECTED: return ENOSPC; + case ERROR_POSSIBLE_DEADLOCK: return EDEADLOCK; + case ERROR_CRC: return EIO; + case ERROR_NEGATIVE_SEEK: return EINVAL; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_NOACCESS: return EFAULT; + case ERROR_FILE_INVALID: return ENXIO; + } + + return winerr; +} + int GetNumLogicalProcessors(void) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION *processor_info = NULL; @@ -151,6 +229,30 @@ char *dlerror(void) return dl_error; } +/* Copied from http://blogs.msdn.com/b/joshpoley/archive/2007/12/19/date-time-formats-and-conversions.aspx */ +void Time_tToSystemTime(time_t dosTime, SYSTEMTIME *systemTime) +{ + LARGE_INTEGER jan1970FT; + LARGE_INTEGER utcFT; + jan1970FT.QuadPart = 116444736000000000LL; // january 1st 1970 + utcFT.QuadPart = ((unsigned __int64)dosTime) * 10000000 + jan1970FT.QuadPart; + + FileTimeToSystemTime((FILETIME*)&utcFT, systemTime); +} + +char* ctime_r(const time_t *t, char *buf) +{ + SYSTEMTIME systime; + const char * const dayOfWeek[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; + const char * const monthOfYear[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + Time_tToSystemTime(*t, &systime); + /* We don't know how long `buf` is, but assume it's rounded up from the minimum of 25 to 32 */ + StringCchPrintfA(buf, 32, "%s %s %d %02d:%02d:%02d %04d", dayOfWeek[systime.wDayOfWeek - 1], monthOfYear[systime.wMonth - 1], + systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wYear); + return buf; +} + int gettimeofday(struct timeval *restrict tp, void *restrict tzp) { FILETIME fileTime; @@ -214,6 +316,8 @@ void *mmap(void *addr, size_t len, int prot, int flags, if ((flags & MAP_ANON) | (flags & MAP_ANONYMOUS)) { allocAddr = VirtualAlloc(addr, len, MEM_COMMIT, vaProt); + if (allocAddr == NULL) + errno = win_to_posix_error(GetLastError()); } return allocAddr; @@ -221,21 +325,26 @@ void *mmap(void *addr, size_t len, int prot, int flags, int munmap(void *addr, size_t len) { - return !VirtualFree(addr, 0, MEM_RELEASE); + if (!VirtualFree(addr, 0, MEM_RELEASE)) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + return 0; } int fork(void) { log_err("%s is not implemented\n", __func__); errno = ENOSYS; - return (-1); + return -1; } pid_t setsid(void) { log_err("%s is not implemented\n", __func__); errno = ENOSYS; - return (-1); + return -1; } static HANDLE log_file = INVALID_HANDLE_VALUE; @@ -280,7 +389,7 @@ void syslog(int priority, const char *message, ... /* argument */) int kill(pid_t pid, int sig) { errno = ESRCH; - return (-1); + return -1; } /* @@ -301,7 +410,7 @@ int fcntl(int fildes, int cmd, ...) return 0; else if (cmd != F_SETFL) { errno = EINVAL; - return (-1); + return -1; } va_start(ap, 1); @@ -339,6 +448,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) { static LARGE_INTEGER freq = {{0,0}}; LARGE_INTEGER counts; + uint64_t t; QueryPerformanceCounter(&counts); if (freq.QuadPart == 0) @@ -347,7 +457,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) tp->tv_sec = counts.QuadPart / freq.QuadPart; /* Get the difference between the number of ns stored * in 'tv_sec' and that stored in 'counts' */ - uint64_t t = tp->tv_sec * freq.QuadPart; + t = tp->tv_sec * freq.QuadPart; t = counts.QuadPart - t; /* 't' now contains the number of cycles since the last second. * We want the number of nanoseconds, so multiply out by 1,000,000,000 @@ -373,12 +483,42 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) int mlock(const void * addr, size_t len) { - return !VirtualLock((LPVOID)addr, len); + SIZE_T min, max; + BOOL success; + HANDLE process = GetCurrentProcess(); + + success = GetProcessWorkingSetSize(process, &min, &max); + if (!success) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + min += len; + max += len; + success = SetProcessWorkingSetSize(process, min, max); + if (!success) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + success = VirtualLock((LPVOID)addr, len); + if (!success) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + return 0; } int munlock(const void * addr, size_t len) { - return !VirtualUnlock((LPVOID)addr, len); + BOOL success = VirtualUnlock((LPVOID)addr, len); + if (!success) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + return 0; } pid_t waitpid(pid_t pid, int *stat_loc, int options) @@ -412,21 +552,15 @@ char *basename(char *path) return name; } -int ftruncate(int fildes, off_t length) -{ - BOOL bSuccess; - int64_t prev_pos = _telli64(fildes); - _lseeki64(fildes, length, SEEK_SET); - HANDLE hFile = (HANDLE)_get_osfhandle(fildes); - bSuccess = SetEndOfFile(hFile); - _lseeki64(fildes, prev_pos, SEEK_SET); - return !bSuccess; -} - int fsync(int fildes) { HANDLE hFile = (HANDLE)_get_osfhandle(fildes); - return !FlushFileBuffers(hFile); + if (!FlushFileBuffers(hFile)) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + return 0; } int nFileMappings = 0; @@ -454,14 +588,33 @@ void *shmat(int shmid, const void *shmaddr, int shmflg) void* mapAddr; MEMORY_BASIC_INFORMATION memInfo; mapAddr = MapViewOfFile(fileMappings[shmid], FILE_MAP_ALL_ACCESS, 0, 0, 0); - VirtualQuery(mapAddr, &memInfo, sizeof(memInfo)); + if (mapAddr == NULL) { + errno = win_to_posix_error(GetLastError()); + return (void*)-1; + } + + if (VirtualQuery(mapAddr, &memInfo, sizeof(memInfo)) == 0) { + errno = win_to_posix_error(GetLastError()); + return (void*)-1; + } + mapAddr = VirtualAlloc(mapAddr, memInfo.RegionSize, MEM_COMMIT, PAGE_READWRITE); + if (mapAddr == NULL) { + errno = win_to_posix_error(GetLastError()); + return (void*)-1; + } + return mapAddr; } int shmdt(const void *shmaddr) { - return !UnmapViewOfFile(shmaddr); + if (!UnmapViewOfFile(shmaddr)) { + errno = win_to_posix_error(GetLastError()); + return -1; + } + + return 0; } int shmctl(int shmid, int cmd, struct shmid_ds *buf) @@ -472,21 +625,22 @@ int shmctl(int shmid, int cmd, struct shmid_ds *buf) } else { log_err("%s is not implemented\n", __func__); } - return (-1); + errno = ENOSYS; + return -1; } int setuid(uid_t uid) { log_err("%s is not implemented\n", __func__); errno = ENOSYS; - return (-1); + return -1; } int setgid(gid_t gid) { log_err("%s is not implemented\n", __func__); errno = ENOSYS; - return (-1); + return -1; } int nice(int incr) @@ -535,11 +689,6 @@ int getrusage(int who, struct rusage *r_usage) return 0; } -int posix_fadvise(int fd, off_t offset, off_t len, int advice) -{ - return 0; -} - int posix_madvise(void *addr, size_t len, int advice) { log_err("%s is not implemented\n", __func__); @@ -579,14 +728,27 @@ ssize_t readv(int fildes, const struct iovec *iov, int iovcnt) { log_err("%s is not implemented\n", __func__); errno = ENOSYS; - return (-1); + return -1; } ssize_t writev(int fildes, const struct iovec *iov, int iovcnt) { - log_err("%s is not implemented\n", __func__); - errno = ENOSYS; - return (-1); + int i; + DWORD bytes_written = 0; + for (i = 0; i < iovcnt; i++) + { + int len = send((SOCKET)fildes, iov[i].iov_base, iov[i].iov_len, 0); + if (len == SOCKET_ERROR) + { + DWORD err = GetLastError(); + errno = win_to_posix_error(err); + bytes_written = -1; + break; + } + bytes_written += len; + } + + return bytes_written; } long long strtoll(const char *restrict str, char **restrict endptr, @@ -628,7 +790,6 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout) FD_SET(fds[i].fd, &exceptfds); } - rc = select(nfds, &readfds, &writefds, &exceptfds, to); if (rc != SOCKET_ERROR) { @@ -648,7 +809,6 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout) fds[i].revents |= POLLHUP; } } - return rc; } @@ -750,6 +910,14 @@ uid_t geteuid(void) return -1; } +in_addr_t inet_network(const char *cp) +{ + in_addr_t hbo; + in_addr_t nbo = inet_addr(cp); + hbo = ((nbo & 0xFF) << 24) + ((nbo & 0xFF00) << 8) + ((nbo & 0xFF0000) >> 8) + ((nbo & 0xFF000000) >> 24); + return hbo; +} + const char* inet_ntop(int af, const void *restrict src, char *restrict dst, socklen_t size) {