Statistics
| Branch: | Revision:

root / osdep.c @ a74cdab4

History | View | Annotate | Download (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
#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
36
#include <sys/mman.h>
37
#endif
38

    
39
#ifdef CONFIG_SOLARIS
40
#include <sys/types.h>
41
#include <sys/statvfs.h>
42
/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
43
   discussion about Solaris header problems */
44
extern int madvise(caddr_t, size_t, int);
45
#endif
46

    
47
#include "qemu-common.h"
48
#include "trace.h"
49
#include "qemu_socket.h"
50

    
51
int qemu_madvise(void *addr, size_t len, int advice)
52
{
53
    if (advice == QEMU_MADV_INVALID) {
54
        errno = EINVAL;
55
        return -1;
56
    }
57
#if defined(CONFIG_MADVISE)
58
    return madvise(addr, len, advice);
59
#elif defined(CONFIG_POSIX_MADVISE)
60
    return posix_madvise(addr, len, advice);
61
#else
62
    errno = EINVAL;
63
    return -1;
64
#endif
65
}
66

    
67

    
68
/*
69
 * Opens a file with FD_CLOEXEC set
70
 */
71
int qemu_open(const char *name, int flags, ...)
72
{
73
    int ret;
74
    int mode = 0;
75

    
76
    if (flags & O_CREAT) {
77
        va_list ap;
78

    
79
        va_start(ap, flags);
80
        mode = va_arg(ap, int);
81
        va_end(ap);
82
    }
83

    
84
#ifdef O_CLOEXEC
85
    ret = open(name, flags | O_CLOEXEC, mode);
86
#else
87
    ret = open(name, flags, mode);
88
    if (ret >= 0) {
89
        qemu_set_cloexec(ret);
90
    }
91
#endif
92

    
93
    return ret;
94
}
95

    
96
/*
97
 * A variant of write(2) which handles partial write.
98
 *
99
 * Return the number of bytes transferred.
100
 * Set errno if fewer than `count' bytes are written.
101
 *
102
 * This function don't work with non-blocking fd's.
103
 * Any of the possibilities with non-bloking fd's is bad:
104
 *   - return a short write (then name is wrong)
105
 *   - busy wait adding (errno == EAGAIN) to the loop
106
 */
107
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
108
{
109
    ssize_t ret = 0;
110
    ssize_t total = 0;
111

    
112
    while (count) {
113
        ret = write(fd, buf, count);
114
        if (ret < 0) {
115
            if (errno == EINTR)
116
                continue;
117
            break;
118
        }
119

    
120
        count -= ret;
121
        buf += ret;
122
        total += ret;
123
    }
124

    
125
    return total;
126
}
127

    
128
/*
129
 * Opens a socket with FD_CLOEXEC set
130
 */
131
int qemu_socket(int domain, int type, int protocol)
132
{
133
    int ret;
134

    
135
#ifdef SOCK_CLOEXEC
136
    ret = socket(domain, type | SOCK_CLOEXEC, protocol);
137
    if (ret != -1 || errno != EINVAL) {
138
        return ret;
139
    }
140
#endif
141
    ret = socket(domain, type, protocol);
142
    if (ret >= 0) {
143
        qemu_set_cloexec(ret);
144
    }
145

    
146
    return ret;
147
}
148

    
149
/*
150
 * Accept a connection and set FD_CLOEXEC
151
 */
152
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
153
{
154
    int ret;
155

    
156
#ifdef CONFIG_ACCEPT4
157
    ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
158
    if (ret != -1 || errno != ENOSYS) {
159
        return ret;
160
    }
161
#endif
162
    ret = accept(s, addr, addrlen);
163
    if (ret >= 0) {
164
        qemu_set_cloexec(ret);
165
    }
166

    
167
    return ret;
168
}