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