osdep.c revision 747f7d13e472f42742f74fdfa70ffd6b2998362e
1/* 2 * QEMU low level functions 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24#include <stdlib.h> 25#include <stdio.h> 26#include <stdarg.h> 27#include <string.h> 28#include <errno.h> 29#include <unistd.h> 30#include <fcntl.h> 31 32/* Needed early for CONFIG_BSD etc. */ 33#include "config-host.h" 34 35#ifdef CONFIG_SOLARIS 36#include <sys/types.h> 37#include <sys/statvfs.h> 38#endif 39 40#ifdef CONFIG_EVENTFD 41#include <sys/eventfd.h> 42#endif 43 44#ifdef _WIN32 45#include <windows.h> 46#elif defined(CONFIG_BSD) 47#include <stdlib.h> 48#else 49#include <malloc.h> 50#endif 51 52#ifdef CONFIG_ANDROID 53#ifdef WIN32 54#include <winsock2.h> 55#include <stdint.h> 56typedef int32_t socklen_t; 57#else 58#include <sys/socket.h> 59#endif 60#endif /* CONFIG_ANDROID */ 61 62#include "qemu-common.h" 63#include "sysemu.h" 64#include "qemu_socket.h" 65 66#if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__) || defined(__APPLE__) 67static void *oom_check(void *ptr) 68{ 69 if (ptr == NULL) { 70#if defined(_WIN32) 71 fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError()); 72#else 73 fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno)); 74#endif 75 abort(); 76 } 77 return ptr; 78} 79#endif 80 81#if defined(_WIN32) 82void *qemu_memalign(size_t alignment, size_t size) 83{ 84 if (!size) { 85 abort(); 86 } 87 return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); 88} 89 90void *qemu_vmalloc(size_t size) 91{ 92 /* FIXME: this is not exactly optimal solution since VirtualAlloc 93 has 64Kb granularity, but at least it guarantees us that the 94 memory is page aligned. */ 95 if (!size) { 96 abort(); 97 } 98 return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); 99} 100 101void qemu_vfree(void *ptr) 102{ 103 VirtualFree(ptr, 0, MEM_RELEASE); 104} 105 106#else 107 108void *qemu_memalign(size_t alignment, size_t size) 109{ 110#if defined(_POSIX_C_SOURCE) && !defined(__sun__) && !defined(__APPLE__) 111 int ret; 112 void *ptr; 113 ret = posix_memalign(&ptr, alignment, size); 114 if (ret != 0) { 115 fprintf(stderr, "Failed to allocate %zu B: %s\n", 116 size, strerror(ret)); 117 abort(); 118 } 119 return ptr; 120#elif defined(CONFIG_BSD) 121 return oom_check(valloc(size)); 122#else 123 return oom_check(memalign(alignment, size)); 124#endif 125} 126 127/* alloc shared memory pages */ 128void *qemu_vmalloc(size_t size) 129{ 130 return qemu_memalign(getpagesize(), size); 131} 132 133void qemu_vfree(void *ptr) 134{ 135 free(ptr); 136} 137 138#endif 139 140int qemu_create_pidfile(const char *filename) 141{ 142 char buffer[128]; 143 int len; 144#ifndef _WIN32 145 int fd; 146 147 fd = qemu_open(filename, O_RDWR | O_CREAT, 0600); 148 if (fd == -1) 149 return -1; 150 151 if (lockf(fd, F_TLOCK, 0) == -1) 152 return -1; 153 154 len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); 155 if (write(fd, buffer, len) != len) 156 return -1; 157#else 158 HANDLE file; 159 OVERLAPPED overlap; 160 BOOL ret; 161 memset(&overlap, 0, sizeof(overlap)); 162 163 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 164 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 165 166 if (file == INVALID_HANDLE_VALUE) 167 return -1; 168 169 len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); 170 ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, 171 &overlap, NULL); 172 if (ret == 0) 173 return -1; 174#endif 175 return 0; 176} 177 178#ifdef _WIN32 179 180/* mingw32 needs ffs for compilations without optimization. */ 181int ffs(int i) 182{ 183 /* Use gcc's builtin ffs. */ 184 return __builtin_ffs(i); 185} 186 187/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ 188#define _W32_FT_OFFSET (116444736000000000ULL) 189 190int qemu_gettimeofday(qemu_timeval *tp) 191{ 192 union { 193 unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ 194 FILETIME ft; 195 } _now; 196 197 if(tp) 198 { 199 GetSystemTimeAsFileTime (&_now.ft); 200 tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); 201 tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); 202 } 203 /* Always return 0 as per Open Group Base Specifications Issue 6. 204 Do not set errno on error. */ 205 return 0; 206} 207#endif /* _WIN32 */ 208 209 210#ifdef _WIN32 211#ifndef CONFIG_ANDROID 212void socket_set_nonblock(int fd) 213{ 214 unsigned long opt = 1; 215 ioctlsocket(fd, FIONBIO, &opt); 216} 217#endif 218 219int inet_aton(const char *cp, struct in_addr *ia) 220{ 221 uint32_t addr = inet_addr(cp); 222 if (addr == 0xffffffff) 223 return 0; 224 ia->s_addr = addr; 225 return 1; 226} 227 228void qemu_set_cloexec(int fd) 229{ 230} 231 232#else 233 234#ifndef CONFIG_ANDROID 235void socket_set_nonblock(int fd) 236{ 237 int f; 238 f = fcntl(fd, F_GETFL); 239 fcntl(fd, F_SETFL, f | O_NONBLOCK); 240} 241#endif 242 243void qemu_set_cloexec(int fd) 244{ 245 int f; 246 f = fcntl(fd, F_GETFD); 247 fcntl(fd, F_SETFD, f | FD_CLOEXEC); 248} 249 250#endif 251 252/* 253 * Opens a file with FD_CLOEXEC set 254 */ 255int qemu_open(const char *name, int flags, ...) 256{ 257 int ret; 258 int mode = 0; 259 260 if (flags & O_CREAT) { 261 va_list ap; 262 263 va_start(ap, flags); 264 mode = va_arg(ap, int); 265 va_end(ap); 266 } 267 268#ifdef O_CLOEXEC 269 ret = open(name, flags | O_CLOEXEC, mode); 270#else 271 ret = open(name, flags, mode); 272 if (ret >= 0) { 273 qemu_set_cloexec(ret); 274 } 275#endif 276 277 return ret; 278} 279 280/* 281 * A variant of write(2) which handles partial write. 282 * 283 * Return the number of bytes transferred. 284 * Set errno if fewer than `count' bytes are written. 285 * 286 * This function don't work with non-blocking fd's. 287 * Any of the possibilities with non-bloking fd's is bad: 288 * - return a short write (then name is wrong) 289 * - busy wait adding (errno == EAGAIN) to the loop 290 */ 291ssize_t qemu_write_full(int fd, const void *buf, size_t count) 292{ 293 ssize_t ret = 0; 294 ssize_t total = 0; 295 296 while (count) { 297 ret = write(fd, buf, count); 298 if (ret < 0) { 299 if (errno == EINTR) 300 continue; 301 break; 302 } 303 304 count -= ret; 305 buf += ret; 306 total += ret; 307 } 308 309 return total; 310} 311 312#ifndef _WIN32 313/* 314 * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set. 315 */ 316int qemu_eventfd(int fds[2]) 317{ 318#ifdef CONFIG_EVENTFD 319 int ret; 320 321 ret = eventfd(0, 0); 322 if (ret >= 0) { 323 fds[0] = ret; 324 qemu_set_cloexec(ret); 325 if ((fds[1] = dup(ret)) == -1) { 326 close(ret); 327 return -1; 328 } 329 qemu_set_cloexec(fds[1]); 330 return 0; 331 } 332 333 if (errno != ENOSYS) { 334 return -1; 335 } 336#endif 337 338 return qemu_pipe(fds); 339} 340 341/* 342 * Creates a pipe with FD_CLOEXEC set on both file descriptors 343 */ 344int qemu_pipe(int pipefd[2]) 345{ 346 int ret; 347 348#ifdef CONFIG_PIPE2 349 ret = pipe2(pipefd, O_CLOEXEC); 350 if (ret != -1 || errno != ENOSYS) { 351 return ret; 352 } 353#endif 354 ret = pipe(pipefd); 355 if (ret == 0) { 356 qemu_set_cloexec(pipefd[0]); 357 qemu_set_cloexec(pipefd[1]); 358 } 359 360 return ret; 361} 362#endif 363 364/* 365 * Opens a socket with FD_CLOEXEC set 366 */ 367int qemu_socket(int domain, int type, int protocol) 368{ 369 int ret; 370 371#ifdef SOCK_CLOEXEC 372 ret = socket(domain, type | SOCK_CLOEXEC, protocol); 373 if (ret != -1 || errno != EINVAL) { 374 return ret; 375 } 376#endif 377 ret = socket(domain, type, protocol); 378 if (ret >= 0) { 379 qemu_set_cloexec(ret); 380 } 381 382 return ret; 383} 384 385/* 386 * Accept a connection and set FD_CLOEXEC 387 */ 388int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 389{ 390 int ret; 391 392#ifdef CONFIG_ACCEPT4 393 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); 394 if (ret != -1 || errno != ENOSYS) { 395 return ret; 396 } 397#endif 398 ret = accept(s, addr, addrlen); 399 if (ret >= 0) { 400 qemu_set_cloexec(ret); 401 } 402 403 return ret; 404} 405 406#ifdef WIN32 407int asprintf( char **, char *, ... ); 408int vasprintf( char **, char *, va_list ); 409 410int vasprintf( char **sptr, char *fmt, va_list argv ) 411{ 412 int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv ); 413 if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) ) 414 return vsprintf( *sptr, fmt, argv ); 415 416 return wanted; 417} 418 419int asprintf( char **sptr, char *fmt, ... ) 420{ 421 int retval; 422 va_list argv; 423 va_start( argv, fmt ); 424 retval = vasprintf( sptr, fmt, argv ); 425 va_end( argv ); 426 return retval; 427} 428#endif 429