Statistics
| Branch: | Revision:

root / osdep.c @ cd245a19

History | View | Annotate | Download (8.4 kB)

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
#include "qemu-common.h"
53
#include "trace.h"
54
#include "sysemu.h"
55
#include "qemu_socket.h"
56

    
57
#if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__)
58
static void *oom_check(void *ptr)
59
{
60
    if (ptr == NULL) {
61
#if defined(_WIN32)
62
        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
63
#else
64
        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
65
#endif
66
        abort();
67
    }
68
    return ptr;
69
}
70
#endif
71

    
72
#if defined(_WIN32)
73
void *qemu_memalign(size_t alignment, size_t size)
74
{
75
    void *ptr;
76

    
77
    if (!size) {
78
        abort();
79
    }
80
    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
81
    trace_qemu_memalign(alignment, size, ptr);
82
    return ptr;
83
}
84

    
85
void *qemu_vmalloc(size_t size)
86
{
87
    void *ptr;
88

    
89
    /* FIXME: this is not exactly optimal solution since VirtualAlloc
90
       has 64Kb granularity, but at least it guarantees us that the
91
       memory is page aligned. */
92
    if (!size) {
93
        abort();
94
    }
95
    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
96
    trace_qemu_vmalloc(size, ptr);
97
    return ptr;
98
}
99

    
100
void qemu_vfree(void *ptr)
101
{
102
    trace_qemu_vfree(ptr);
103
    VirtualFree(ptr, 0, MEM_RELEASE);
104
}
105

    
106
#else
107

    
108
void *qemu_memalign(size_t alignment, size_t size)
109
{
110
    void *ptr;
111
#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
112
    int ret;
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
#elif defined(CONFIG_BSD)
120
    ptr = oom_check(valloc(size));
121
#else
122
    ptr = oom_check(memalign(alignment, size));
123
#endif
124
    trace_qemu_memalign(alignment, size, ptr);
125
    return ptr;
126
}
127

    
128
/* alloc shared memory pages */
129
void *qemu_vmalloc(size_t size)
130
{
131
    return qemu_memalign(getpagesize(), size);
132
}
133

    
134
void qemu_vfree(void *ptr)
135
{
136
    trace_qemu_vfree(ptr);
137
    free(ptr);
138
}
139

    
140
#endif
141

    
142
int qemu_create_pidfile(const char *filename)
143
{
144
    char buffer[128];
145
    int len;
146
#ifndef _WIN32
147
    int fd;
148

    
149
    fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
150
    if (fd == -1)
151
        return -1;
152

    
153
    if (lockf(fd, F_TLOCK, 0) == -1)
154
        return -1;
155

    
156
    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
157
    if (write(fd, buffer, len) != len)
158
        return -1;
159
#else
160
    HANDLE file;
161
    OVERLAPPED overlap;
162
    BOOL ret;
163
    memset(&overlap, 0, sizeof(overlap));
164

    
165
    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
166
                      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
167

    
168
    if (file == INVALID_HANDLE_VALUE)
169
      return -1;
170

    
171
    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
172
    ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
173
                      &overlap, NULL);
174
    if (ret == 0)
175
      return -1;
176
#endif
177
    return 0;
178
}
179

    
180
#ifdef _WIN32
181

    
182
/* mingw32 needs ffs for compilations without optimization. */
183
int ffs(int i)
184
{
185
    /* Use gcc's builtin ffs. */
186
    return __builtin_ffs(i);
187
}
188

    
189
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
190
#define _W32_FT_OFFSET (116444736000000000ULL)
191

    
192
int qemu_gettimeofday(qemu_timeval *tp)
193
{
194
  union {
195
    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
196
    FILETIME ft;
197
  }  _now;
198

    
199
  if(tp)
200
    {
201
      GetSystemTimeAsFileTime (&_now.ft);
202
      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
203
      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
204
    }
205
  /* Always return 0 as per Open Group Base Specifications Issue 6.
206
     Do not set errno on error.  */
207
  return 0;
208
}
209
#endif /* _WIN32 */
210

    
211

    
212
#ifdef _WIN32
213
void socket_set_nonblock(int fd)
214
{
215
    unsigned long opt = 1;
216
    ioctlsocket(fd, FIONBIO, &opt);
217
}
218

    
219
int 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

    
228
void qemu_set_cloexec(int fd)
229
{
230
}
231

    
232
#else
233

    
234
void 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

    
241
void qemu_set_cloexec(int fd)
242
{
243
    int f;
244
    f = fcntl(fd, F_GETFD);
245
    fcntl(fd, F_SETFD, f | FD_CLOEXEC);
246
}
247

    
248
#endif
249

    
250
/*
251
 * Opens a file with FD_CLOEXEC set
252
 */
253
int qemu_open(const char *name, int flags, ...)
254
{
255
    int ret;
256
    int mode = 0;
257

    
258
    if (flags & O_CREAT) {
259
        va_list ap;
260

    
261
        va_start(ap, flags);
262
        mode = va_arg(ap, int);
263
        va_end(ap);
264
    }
265

    
266
#ifdef O_CLOEXEC
267
    ret = open(name, flags | O_CLOEXEC, mode);
268
#else
269
    ret = open(name, flags, mode);
270
    if (ret >= 0) {
271
        qemu_set_cloexec(ret);
272
    }
273
#endif
274

    
275
    return ret;
276
}
277

    
278
/*
279
 * A variant of write(2) which handles partial write.
280
 *
281
 * Return the number of bytes transferred.
282
 * Set errno if fewer than `count' bytes are written.
283
 *
284
 * This function don't work with non-blocking fd's.
285
 * Any of the possibilities with non-bloking fd's is bad:
286
 *   - return a short write (then name is wrong)
287
 *   - busy wait adding (errno == EAGAIN) to the loop
288
 */
289
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
290
{
291
    ssize_t ret = 0;
292
    ssize_t total = 0;
293

    
294
    while (count) {
295
        ret = write(fd, buf, count);
296
        if (ret < 0) {
297
            if (errno == EINTR)
298
                continue;
299
            break;
300
        }
301

    
302
        count -= ret;
303
        buf += ret;
304
        total += ret;
305
    }
306

    
307
    return total;
308
}
309

    
310
#ifndef _WIN32
311
/*
312
 * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
313
 */
314
int qemu_eventfd(int fds[2])
315
{
316
#ifdef CONFIG_EVENTFD
317
    int ret;
318

    
319
    ret = eventfd(0, 0);
320
    if (ret >= 0) {
321
        fds[0] = ret;
322
        qemu_set_cloexec(ret);
323
        if ((fds[1] = dup(ret)) == -1) {
324
            close(ret);
325
            return -1;
326
        }
327
        qemu_set_cloexec(fds[1]);
328
        return 0;
329
    }
330

    
331
    if (errno != ENOSYS) {
332
        return -1;
333
    }
334
#endif
335

    
336
    return qemu_pipe(fds);
337
}
338

    
339
/*
340
 * Creates a pipe with FD_CLOEXEC set on both file descriptors
341
 */
342
int qemu_pipe(int pipefd[2])
343
{
344
    int ret;
345

    
346
#ifdef CONFIG_PIPE2
347
    ret = pipe2(pipefd, O_CLOEXEC);
348
    if (ret != -1 || errno != ENOSYS) {
349
        return ret;
350
    }
351
#endif
352
    ret = pipe(pipefd);
353
    if (ret == 0) {
354
        qemu_set_cloexec(pipefd[0]);
355
        qemu_set_cloexec(pipefd[1]);
356
    }
357

    
358
    return ret;
359
}
360
#endif
361

    
362
/*
363
 * Opens a socket with FD_CLOEXEC set
364
 */
365
int qemu_socket(int domain, int type, int protocol)
366
{
367
    int ret;
368

    
369
#ifdef SOCK_CLOEXEC
370
    ret = socket(domain, type | SOCK_CLOEXEC, protocol);
371
    if (ret != -1 || errno != EINVAL) {
372
        return ret;
373
    }
374
#endif
375
    ret = socket(domain, type, protocol);
376
    if (ret >= 0) {
377
        qemu_set_cloexec(ret);
378
    }
379

    
380
    return ret;
381
}
382

    
383
/*
384
 * Accept a connection and set FD_CLOEXEC
385
 */
386
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
387
{
388
    int ret;
389

    
390
#ifdef CONFIG_ACCEPT4
391
    ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
392
    if (ret != -1 || errno != ENOSYS) {
393
        return ret;
394
    }
395
#endif
396
    ret = accept(s, addr, addrlen);
397
    if (ret >= 0) {
398
        qemu_set_cloexec(ret);
399
    }
400

    
401
    return ret;
402
}