X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=osdep.c;h=56e6963f1572589d1dbfc3bda8915ae6368ffd5a;hb=2798b5e1747095592e3b83b3527ef91a78364c76;hp=7509c5b22e43694c57ef4ea8baaa434b2b4905be;hpb=40ff6d7e8dceca227e7f8a3e8e0d58b2c66d19b4;p=qemu.git diff --git a/osdep.c b/osdep.c index 7509c5b22..56e6963f1 100644 --- a/osdep.c +++ b/osdep.c @@ -28,201 +28,42 @@ #include #include #include -#ifdef CONFIG_SOLARIS -#include -#include -#endif /* Needed early for CONFIG_BSD etc. */ #include "config-host.h" -#ifdef _WIN32 -#include -#elif defined(CONFIG_BSD) -#include -#else -#include -#endif - -#include "qemu-common.h" -#include "sysemu.h" -#include "qemu_socket.h" - -#if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__) -static void *oom_check(void *ptr) -{ - if (ptr == NULL) { - abort(); - } - return ptr; -} +#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE) +#include #endif -#if defined(_WIN32) -void *qemu_memalign(size_t alignment, size_t size) -{ - if (!size) { - abort(); - } - return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); -} - -void *qemu_vmalloc(size_t size) -{ - /* FIXME: this is not exactly optimal solution since VirtualAlloc - has 64Kb granularity, but at least it guarantees us that the - memory is page aligned. */ - if (!size) { - abort(); - } - return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); -} - -void qemu_vfree(void *ptr) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - -#else - -void *qemu_memalign(size_t alignment, size_t size) -{ -#if defined(_POSIX_C_SOURCE) && !defined(__sun__) - int ret; - void *ptr; - ret = posix_memalign(&ptr, alignment, size); - if (ret != 0) - abort(); - return ptr; -#elif defined(CONFIG_BSD) - return oom_check(valloc(size)); -#else - return oom_check(memalign(alignment, size)); +#ifdef CONFIG_SOLARIS +#include +#include +/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for + discussion about Solaris header problems */ +extern int madvise(caddr_t, size_t, int); #endif -} - -/* alloc shared memory pages */ -void *qemu_vmalloc(size_t size) -{ - return qemu_memalign(getpagesize(), size); -} - -void qemu_vfree(void *ptr) -{ - free(ptr); -} -#endif +#include "qemu-common.h" +#include "trace.h" +#include "qemu_socket.h" -int qemu_create_pidfile(const char *filename) +int qemu_madvise(void *addr, size_t len, int advice) { - char buffer[128]; - int len; -#ifndef _WIN32 - int fd; - - fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); - if (fd == -1) - return -1; - - if (lockf(fd, F_TLOCK, 0) == -1) - return -1; - - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); - if (write(fd, buffer, len) != len) + if (advice == QEMU_MADV_INVALID) { + errno = EINVAL; return -1; -#else - HANDLE file; - DWORD flags; - OVERLAPPED overlap; - BOOL ret; - - /* Open for writing with no sharing. */ - file = CreateFile(filename, GENERIC_WRITE, 0, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file == INVALID_HANDLE_VALUE) - return -1; - - flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; - overlap.hEvent = 0; - /* Lock 1 byte. */ - ret = LockFileEx(file, flags, 0, 0, 1, &overlap); - if (ret == 0) - return -1; - - /* Write PID to file. */ - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); - ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, - &overlap, NULL); - if (ret == 0) - return -1; -#endif - return 0; -} - -#ifdef _WIN32 - -/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ -#define _W32_FT_OFFSET (116444736000000000ULL) - -int qemu_gettimeofday(qemu_timeval *tp) -{ - union { - unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } _now; - - if(tp) - { - GetSystemTimeAsFileTime (&_now.ft); - tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); - tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); } - /* Always return 0 as per Open Group Base Specifications Issue 6. - Do not set errno on error. */ - return 0; -} -#endif /* _WIN32 */ - - -#ifdef _WIN32 -void socket_set_nonblock(int fd) -{ - unsigned long opt = 1; - ioctlsocket(fd, FIONBIO, &opt); -} - -int inet_aton(const char *cp, struct in_addr *ia) -{ - uint32_t addr = inet_addr(cp); - if (addr == 0xffffffff) - return 0; - ia->s_addr = addr; - return 1; -} - -void qemu_set_cloexec(int fd) -{ -} - +#if defined(CONFIG_MADVISE) + return madvise(addr, len, advice); +#elif defined(CONFIG_POSIX_MADVISE) + return posix_madvise(addr, len, advice); #else - -void socket_set_nonblock(int fd) -{ - int f; - f = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, f | O_NONBLOCK); -} - -void qemu_set_cloexec(int fd) -{ - int f; - f = fcntl(fd, F_GETFD); - fcntl(fd, F_SETFD, f | FD_CLOEXEC); + errno = EINVAL; + return -1; +#endif } -#endif /* * Opens a file with FD_CLOEXEC set @@ -252,27 +93,37 @@ int qemu_open(const char *name, int flags, ...) return ret; } -#ifndef _WIN32 /* - * Creates a pipe with FD_CLOEXEC set on both file descriptors + * A variant of write(2) which handles partial write. + * + * Return the number of bytes transferred. + * Set errno if fewer than `count' bytes are written. + * + * This function don't work with non-blocking fd's. + * Any of the possibilities with non-bloking fd's is bad: + * - return a short write (then name is wrong) + * - busy wait adding (errno == EAGAIN) to the loop */ -int qemu_pipe(int pipefd[2]) -{ - int ret; - -#ifdef CONFIG_PIPE2 - ret = pipe2(pipefd, O_CLOEXEC); -#else - ret = pipe(pipefd); - if (ret == 0) { - qemu_set_cloexec(pipefd[0]); - qemu_set_cloexec(pipefd[1]); +ssize_t qemu_write_full(int fd, const void *buf, size_t count) +{ + ssize_t ret = 0; + ssize_t total = 0; + + while (count) { + ret = write(fd, buf, count); + if (ret < 0) { + if (errno == EINTR) + continue; + break; + } + + count -= ret; + buf += ret; + total += ret; } -#endif - return ret; + return total; } -#endif /* * Opens a socket with FD_CLOEXEC set @@ -283,12 +134,14 @@ int qemu_socket(int domain, int type, int protocol) #ifdef SOCK_CLOEXEC ret = socket(domain, type | SOCK_CLOEXEC, protocol); -#else + if (ret != -1 || errno != EINVAL) { + return ret; + } +#endif ret = socket(domain, type, protocol); if (ret >= 0) { qemu_set_cloexec(ret); } -#endif return ret; } @@ -302,12 +155,14 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) #ifdef CONFIG_ACCEPT4 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); -#else + if (ret != -1 || errno != ENOSYS) { + return ret; + } +#endif ret = accept(s, addr, addrlen); if (ret >= 0) { qemu_set_cloexec(ret); } -#endif return ret; }