osdep.c revision 315ceb8a16eb7a2102fee4946898e7b8a202e86a
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>
55typedef int32_t socklen_t;
56#else
57#include <sys/socket.h>
58#endif
59#endif /* CONFIG_ANDROID */
60
61#include "qemu-common.h"
62#include "sysemu.h"
63#include "qemu_socket.h"
64
65#if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__)
66static void *oom_check(void *ptr)
67{
68    if (ptr == NULL) {
69#if defined(_WIN32)
70        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
71#else
72        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
73#endif
74        abort();
75    }
76    return ptr;
77}
78#endif
79
80#if defined(_WIN32)
81void *qemu_memalign(size_t alignment, size_t size)
82{
83    if (!size) {
84        abort();
85    }
86    return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
87}
88
89void *qemu_vmalloc(size_t size)
90{
91    /* FIXME: this is not exactly optimal solution since VirtualAlloc
92       has 64Kb granularity, but at least it guarantees us that the
93       memory is page aligned. */
94    if (!size) {
95        abort();
96    }
97    return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
98}
99
100void qemu_vfree(void *ptr)
101{
102    VirtualFree(ptr, 0, MEM_RELEASE);
103}
104
105#else
106
107void *qemu_memalign(size_t alignment, size_t size)
108{
109#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
110    int ret;
111    void *ptr;
112    ret = posix_memalign(&ptr, alignment, size);
113    if (ret != 0) {
114        fprintf(stderr, "Failed to allocate %zu B: %s\n",
115                size, strerror(ret));
116        abort();
117    }
118    return ptr;
119#elif defined(CONFIG_BSD)
120    return oom_check(valloc(size));
121#else
122    return oom_check(memalign(alignment, size));
123#endif
124}
125
126/* alloc shared memory pages */
127void *qemu_vmalloc(size_t size)
128{
129    return qemu_memalign(getpagesize(), size);
130}
131
132void qemu_vfree(void *ptr)
133{
134    free(ptr);
135}
136
137#endif
138
139int qemu_create_pidfile(const char *filename)
140{
141    char buffer[128];
142    int len;
143#ifndef _WIN32
144    int fd;
145
146    fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
147    if (fd == -1)
148        return -1;
149
150    if (lockf(fd, F_TLOCK, 0) == -1)
151        return -1;
152
153    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
154    if (write(fd, buffer, len) != len)
155        return -1;
156#else
157    HANDLE file;
158    OVERLAPPED overlap;
159    BOOL ret;
160    memset(&overlap, 0, sizeof(overlap));
161
162    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
163		      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
164
165    if (file == INVALID_HANDLE_VALUE)
166      return -1;
167
168    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
169    ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
170		      &overlap, NULL);
171    if (ret == 0)
172      return -1;
173#endif
174    return 0;
175}
176
177#ifdef _WIN32
178
179/* mingw32 needs ffs for compilations without optimization. */
180int ffs(int i)
181{
182    /* Use gcc's builtin ffs. */
183    return __builtin_ffs(i);
184}
185
186/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
187#define _W32_FT_OFFSET (116444736000000000ULL)
188
189int qemu_gettimeofday(qemu_timeval *tp)
190{
191  union {
192    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
193    FILETIME ft;
194  }  _now;
195
196  if(tp)
197    {
198      GetSystemTimeAsFileTime (&_now.ft);
199      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
200      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
201    }
202  /* Always return 0 as per Open Group Base Specifications Issue 6.
203     Do not set errno on error.  */
204  return 0;
205}
206#endif /* _WIN32 */
207
208
209#ifdef _WIN32
210#ifndef CONFIG_ANDROID
211void socket_set_nonblock(int fd)
212{
213    unsigned long opt = 1;
214    ioctlsocket(fd, FIONBIO, &opt);
215}
216#endif
217
218int inet_aton(const char *cp, struct in_addr *ia)
219{
220    uint32_t addr = inet_addr(cp);
221    if (addr == 0xffffffff)
222	return 0;
223    ia->s_addr = addr;
224    return 1;
225}
226
227void qemu_set_cloexec(int fd)
228{
229}
230
231#else
232
233#ifndef CONFIG_ANDROID
234void socket_set_nonblock(int fd)
235{
236    int f;
237    f = fcntl(fd, F_GETFL);
238    fcntl(fd, F_SETFL, f | O_NONBLOCK);
239}
240#endif
241
242void qemu_set_cloexec(int fd)
243{
244    int f;
245    f = fcntl(fd, F_GETFD);
246    fcntl(fd, F_SETFD, f | FD_CLOEXEC);
247}
248
249#endif
250
251/*
252 * Opens a file with FD_CLOEXEC set
253 */
254int qemu_open(const char *name, int flags, ...)
255{
256    int ret;
257    int mode = 0;
258
259    if (flags & O_CREAT) {
260        va_list ap;
261
262        va_start(ap, flags);
263        mode = va_arg(ap, int);
264        va_end(ap);
265    }
266
267#ifdef O_CLOEXEC
268    ret = open(name, flags | O_CLOEXEC, mode);
269#else
270    ret = open(name, flags, mode);
271    if (ret >= 0) {
272        qemu_set_cloexec(ret);
273    }
274#endif
275
276    return ret;
277}
278
279/*
280 * A variant of write(2) which handles partial write.
281 *
282 * Return the number of bytes transferred.
283 * Set errno if fewer than `count' bytes are written.
284 *
285 * This function don't work with non-blocking fd's.
286 * Any of the possibilities with non-bloking fd's is bad:
287 *   - return a short write (then name is wrong)
288 *   - busy wait adding (errno == EAGAIN) to the loop
289 */
290ssize_t qemu_write_full(int fd, const void *buf, size_t count)
291{
292    ssize_t ret = 0;
293    ssize_t total = 0;
294
295    while (count) {
296        ret = write(fd, buf, count);
297        if (ret < 0) {
298            if (errno == EINTR)
299                continue;
300            break;
301        }
302
303        count -= ret;
304        buf += ret;
305        total += ret;
306    }
307
308    return total;
309}
310
311#ifndef _WIN32
312/*
313 * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
314 */
315int qemu_eventfd(int fds[2])
316{
317#ifdef CONFIG_EVENTFD
318    int ret;
319
320    ret = eventfd(0, 0);
321    if (ret >= 0) {
322        fds[0] = ret;
323        qemu_set_cloexec(ret);
324        if ((fds[1] = dup(ret)) == -1) {
325            close(ret);
326            return -1;
327        }
328        qemu_set_cloexec(fds[1]);
329        return 0;
330    }
331
332    if (errno != ENOSYS) {
333        return -1;
334    }
335#endif
336
337    return qemu_pipe(fds);
338}
339
340/*
341 * Creates a pipe with FD_CLOEXEC set on both file descriptors
342 */
343int qemu_pipe(int pipefd[2])
344{
345    int ret;
346
347#ifdef CONFIG_PIPE2
348    ret = pipe2(pipefd, O_CLOEXEC);
349    if (ret != -1 || errno != ENOSYS) {
350        return ret;
351    }
352#endif
353    ret = pipe(pipefd);
354    if (ret == 0) {
355        qemu_set_cloexec(pipefd[0]);
356        qemu_set_cloexec(pipefd[1]);
357    }
358
359    return ret;
360}
361#endif
362
363/*
364 * Opens a socket with FD_CLOEXEC set
365 */
366int qemu_socket(int domain, int type, int protocol)
367{
368    int ret;
369
370#ifdef SOCK_CLOEXEC
371    ret = socket(domain, type | SOCK_CLOEXEC, protocol);
372    if (ret != -1 || errno != EINVAL) {
373        return ret;
374    }
375#endif
376    ret = socket(domain, type, protocol);
377    if (ret >= 0) {
378        qemu_set_cloexec(ret);
379    }
380
381    return ret;
382}
383
384/*
385 * Accept a connection and set FD_CLOEXEC
386 */
387int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
388{
389    int ret;
390
391#ifdef CONFIG_ACCEPT4
392    ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
393    if (ret != -1 || errno != ENOSYS) {
394        return ret;
395    }
396#endif
397    ret = accept(s, addr, addrlen);
398    if (ret >= 0) {
399        qemu_set_cloexec(ret);
400    }
401
402    return ret;
403}
404
405#ifdef WIN32
406int asprintf( char **, char *, ... );
407int vasprintf( char **, char *, va_list );
408
409int vasprintf( char **sptr, char *fmt, va_list argv )
410{
411    int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv );
412    if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) )
413        return vsprintf( *sptr, fmt, argv );
414
415    return wanted;
416}
417
418int asprintf( char **sptr, char *fmt, ... )
419{
420    int retval;
421    va_list argv;
422    va_start( argv, fmt );
423    retval = vasprintf( sptr, fmt, argv );
424    va_end( argv );
425    return retval;
426}
427#endif
428