18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU low level functions 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2003 Fabrice Bellard 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h> 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h> 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h> 31f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 32f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner/* Needed early for CONFIG_BSD etc. */ 33f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#include "config-host.h" 34f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 35280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE) 36280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#include <sys/mman.h> 37280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#endif 38280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner 392c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_SOLARIS 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h> 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/statvfs.h> 42280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for 43280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner discussion about Solaris header problems */ 44280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerextern int madvise(caddr_t, size_t, int); 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#ifdef _WIN32 482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include <windows.h> 492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#elif defined(CONFIG_BSD) 502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include <stdlib.h> 512910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#else 522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include <malloc.h> 532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#endif 542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner 55315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#ifdef CONFIG_ANDROID 56315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#ifdef WIN32 57315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#include <winsock2.h> 5837a43dcb425d870cb8250633542d70c3fe5dce99David 'Digit' Turner#include <stdint.h> 59315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turnertypedef int32_t socklen_t; 60315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#else 61315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#include <sys/socket.h> 62315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#endif 63315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner#endif /* CONFIG_ANDROID */ 64315ceb8a16eb7a2102fee4946898e7b8a202e86aDavid Turner 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysemu.h" 67f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#include "qemu_socket.h" 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 69280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerint qemu_madvise(void *addr, size_t len, int advice) 70280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner{ 71280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner if (advice == QEMU_MADV_INVALID) { 72280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner errno = EINVAL; 73280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner return -1; 74280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner } 75280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#if defined(CONFIG_MADVISE) 76280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner return madvise(addr, len, advice); 77280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#elif defined(CONFIG_POSIX_MADVISE) 78280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner return posix_madvise(addr, len, advice); 79280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#else 80280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner errno = EINVAL; 81280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner return -1; 82280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#endif 83280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner} 84f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 85f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 86f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner/* 87f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Opens a file with FD_CLOEXEC set 88f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner */ 89f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turnerint qemu_open(const char *name, int flags, ...) 90f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner{ 91f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner int ret; 92f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner int mode = 0; 93f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 94f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (flags & O_CREAT) { 95f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner va_list ap; 96f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 97f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner va_start(ap, flags); 98f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner mode = va_arg(ap, int); 99f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner va_end(ap); 100f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 101f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 102f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#ifdef O_CLOEXEC 103f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = open(name, flags | O_CLOEXEC, mode); 104f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#else 105f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = open(name, flags, mode); 106f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret >= 0) { 107f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner qemu_set_cloexec(ret); 108f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 109f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#endif 110f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 111f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return ret; 112f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner} 113f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 114f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner/* 115f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * A variant of write(2) which handles partial write. 116f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * 117f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Return the number of bytes transferred. 118f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Set errno if fewer than `count' bytes are written. 119f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * 120f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * This function don't work with non-blocking fd's. 121f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Any of the possibilities with non-bloking fd's is bad: 122f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * - return a short write (then name is wrong) 123f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * - busy wait adding (errno == EAGAIN) to the loop 124f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner */ 125f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turnerssize_t qemu_write_full(int fd, const void *buf, size_t count) 126f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner{ 127f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ssize_t ret = 0; 128f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ssize_t total = 0; 129f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 130f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner while (count) { 131f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = write(fd, buf, count); 132f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret < 0) { 133f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (errno == EINTR) 134f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner continue; 135f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner break; 136f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 137f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 138f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner count -= ret; 139f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner buf += ret; 140f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner total += ret; 141f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 142f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 143f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return total; 144f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner} 145f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 146f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner/* 147f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Opens a socket with FD_CLOEXEC set 148f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner */ 149f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turnerint qemu_socket(int domain, int type, int protocol) 150f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner{ 151f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner int ret; 152f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 153f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#ifdef SOCK_CLOEXEC 154f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = socket(domain, type | SOCK_CLOEXEC, protocol); 155f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret != -1 || errno != EINVAL) { 156f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return ret; 157f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 158f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#endif 159f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = socket(domain, type, protocol); 160f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret >= 0) { 161f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner qemu_set_cloexec(ret); 162f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 163f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 164f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return ret; 165f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner} 166f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 167f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner/* 168f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner * Accept a connection and set FD_CLOEXEC 169f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner */ 170f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turnerint qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) 171f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner{ 172f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner int ret; 173f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 174f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#ifdef CONFIG_ACCEPT4 175f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); 176f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret != -1 || errno != ENOSYS) { 177f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return ret; 178f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 179f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner#endif 180f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner ret = accept(s, addr, addrlen); 181f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner if (ret >= 0) { 182f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner qemu_set_cloexec(ret); 183f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner } 184f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner 185f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner return ret; 186f7dd220a26b2c2153e3b331b06826934cac292fbDavid Turner} 187b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner 188b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner#ifdef WIN32 1897f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehint asprintf( char **, const char *, ... ); 1907f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehint vasprintf( char **, const char *, va_list ); 191b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner 1927f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehint vasprintf( char **sptr, const char *fmt, va_list argv ) 193b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner{ 194b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv ); 195b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) ) 196b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner return vsprintf( *sptr, fmt, argv ); 197b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner 198b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner return wanted; 199b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner} 200b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner 2017f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehint asprintf( char **sptr, const char *fmt, ... ) 202b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner{ 203b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner int retval; 204b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner va_list argv; 205b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner va_start( argv, fmt ); 206b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner retval = vasprintf( sptr, fmt, argv ); 207b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner va_end( argv ); 208b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner return retval; 209b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner} 210b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner#endif 211