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