root / osdep.c @ 3329f07b
History | View | Annotate | Download (8.1 kB)
1 | ea88812f | bellard | /*
|
---|---|---|---|
2 | ea88812f | bellard | * QEMU low level functions
|
3 | 5fafdf24 | ths | *
|
4 | ea88812f | bellard | * Copyright (c) 2003 Fabrice Bellard
|
5 | 5fafdf24 | ths | *
|
6 | ea88812f | bellard | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | ea88812f | bellard | * of this software and associated documentation files (the "Software"), to deal
|
8 | ea88812f | bellard | * in the Software without restriction, including without limitation the rights
|
9 | ea88812f | bellard | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | ea88812f | bellard | * copies of the Software, and to permit persons to whom the Software is
|
11 | ea88812f | bellard | * furnished to do so, subject to the following conditions:
|
12 | ea88812f | bellard | *
|
13 | ea88812f | bellard | * The above copyright notice and this permission notice shall be included in
|
14 | ea88812f | bellard | * all copies or substantial portions of the Software.
|
15 | ea88812f | bellard | *
|
16 | ea88812f | bellard | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | ea88812f | bellard | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | ea88812f | bellard | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | ea88812f | bellard | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | ea88812f | bellard | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | ea88812f | bellard | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | ea88812f | bellard | * THE SOFTWARE.
|
23 | ea88812f | bellard | */
|
24 | ea88812f | bellard | #include <stdlib.h> |
25 | ea88812f | bellard | #include <stdio.h> |
26 | ea88812f | bellard | #include <stdarg.h> |
27 | ea88812f | bellard | #include <string.h> |
28 | ea88812f | bellard | #include <errno.h> |
29 | ea88812f | bellard | #include <unistd.h> |
30 | aa26bb2d | ths | #include <fcntl.h> |
31 | f582af58 | Paolo Bonzini | |
32 | f582af58 | Paolo Bonzini | /* Needed early for CONFIG_BSD etc. */
|
33 | f582af58 | Paolo Bonzini | #include "config-host.h" |
34 | f582af58 | Paolo Bonzini | |
35 | dfe5fff3 | Juan Quintela | #ifdef CONFIG_SOLARIS
|
36 | 605686cd | ths | #include <sys/types.h> |
37 | 605686cd | ths | #include <sys/statvfs.h> |
38 | 605686cd | ths | #endif
|
39 | ea88812f | bellard | |
40 | f3dfda61 | Paolo Bonzini | #ifdef CONFIG_EVENTFD
|
41 | f3dfda61 | Paolo Bonzini | #include <sys/eventfd.h> |
42 | f3dfda61 | Paolo Bonzini | #endif
|
43 | f3dfda61 | Paolo Bonzini | |
44 | 6e4255f6 | bellard | #ifdef _WIN32
|
45 | 6e4255f6 | bellard | #include <windows.h> |
46 | 71e72a19 | Juan Quintela | #elif defined(CONFIG_BSD)
|
47 | 194884dd | bellard | #include <stdlib.h> |
48 | 194884dd | bellard | #else
|
49 | 49b470eb | bellard | #include <malloc.h> |
50 | 194884dd | bellard | #endif
|
51 | 49b470eb | bellard | |
52 | 511d2b14 | blueswir1 | #include "qemu-common.h" |
53 | 511d2b14 | blueswir1 | #include "sysemu.h" |
54 | 03ff3ca3 | aliguori | #include "qemu_socket.h" |
55 | 03ff3ca3 | aliguori | |
56 | d741429a | Blue Swirl | #if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__)
|
57 | d644f8be | malc | static void *oom_check(void *ptr) |
58 | d644f8be | malc | { |
59 | d644f8be | malc | if (ptr == NULL) { |
60 | d2d5adcb | Stefan Weil | #if defined(_WIN32)
|
61 | d2d5adcb | Stefan Weil | fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
|
62 | d2d5adcb | Stefan Weil | #else
|
63 | d2d5adcb | Stefan Weil | fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
|
64 | d2d5adcb | Stefan Weil | #endif
|
65 | d644f8be | malc | abort(); |
66 | d644f8be | malc | } |
67 | d644f8be | malc | return ptr;
|
68 | d644f8be | malc | } |
69 | d644f8be | malc | #endif
|
70 | d644f8be | malc | |
71 | 6e4255f6 | bellard | #if defined(_WIN32)
|
72 | 33f00271 | balrog | void *qemu_memalign(size_t alignment, size_t size)
|
73 | 33f00271 | balrog | { |
74 | d644f8be | malc | if (!size) {
|
75 | d644f8be | malc | abort(); |
76 | d644f8be | malc | } |
77 | d644f8be | malc | return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); |
78 | 33f00271 | balrog | } |
79 | 6e4255f6 | bellard | |
80 | 6e4255f6 | bellard | void *qemu_vmalloc(size_t size)
|
81 | 6e4255f6 | bellard | { |
82 | 6e4255f6 | bellard | /* FIXME: this is not exactly optimal solution since VirtualAlloc
|
83 | 6e4255f6 | bellard | has 64Kb granularity, but at least it guarantees us that the
|
84 | 6e4255f6 | bellard | memory is page aligned. */
|
85 | d644f8be | malc | if (!size) {
|
86 | d644f8be | malc | abort(); |
87 | d644f8be | malc | } |
88 | d644f8be | malc | return oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE)); |
89 | 6e4255f6 | bellard | } |
90 | 6e4255f6 | bellard | |
91 | 6e4255f6 | bellard | void qemu_vfree(void *ptr) |
92 | 6e4255f6 | bellard | { |
93 | 6e4255f6 | bellard | VirtualFree(ptr, 0, MEM_RELEASE);
|
94 | 6e4255f6 | bellard | } |
95 | 6e4255f6 | bellard | |
96 | 6cb7ee85 | pbrook | #else
|
97 | 6cb7ee85 | pbrook | |
98 | 33f00271 | balrog | void *qemu_memalign(size_t alignment, size_t size)
|
99 | 33f00271 | balrog | { |
100 | d741429a | Blue Swirl | #if defined(_POSIX_C_SOURCE) && !defined(__sun__)
|
101 | 33f00271 | balrog | int ret;
|
102 | 33f00271 | balrog | void *ptr;
|
103 | 33f00271 | balrog | ret = posix_memalign(&ptr, alignment, size); |
104 | d2d5adcb | Stefan Weil | if (ret != 0) { |
105 | d2d5adcb | Stefan Weil | fprintf(stderr, "Failed to allocate %zu B: %s\n",
|
106 | d2d5adcb | Stefan Weil | size, strerror(ret)); |
107 | d644f8be | malc | abort(); |
108 | d2d5adcb | Stefan Weil | } |
109 | 33f00271 | balrog | return ptr;
|
110 | 71e72a19 | Juan Quintela | #elif defined(CONFIG_BSD)
|
111 | d644f8be | malc | return oom_check(valloc(size));
|
112 | 33f00271 | balrog | #else
|
113 | d644f8be | malc | return oom_check(memalign(alignment, size));
|
114 | 33f00271 | balrog | #endif
|
115 | 33f00271 | balrog | } |
116 | 33f00271 | balrog | |
117 | 49b470eb | bellard | /* alloc shared memory pages */
|
118 | 49b470eb | bellard | void *qemu_vmalloc(size_t size)
|
119 | 49b470eb | bellard | { |
120 | 48253bd8 | malc | return qemu_memalign(getpagesize(), size);
|
121 | 49b470eb | bellard | } |
122 | 49b470eb | bellard | |
123 | 49b470eb | bellard | void qemu_vfree(void *ptr) |
124 | 49b470eb | bellard | { |
125 | 49b470eb | bellard | free(ptr); |
126 | 49b470eb | bellard | } |
127 | 49b470eb | bellard | |
128 | 49b470eb | bellard | #endif
|
129 | 49b470eb | bellard | |
130 | aa26bb2d | ths | int qemu_create_pidfile(const char *filename) |
131 | aa26bb2d | ths | { |
132 | aa26bb2d | ths | char buffer[128]; |
133 | aa26bb2d | ths | int len;
|
134 | aa26bb2d | ths | #ifndef _WIN32
|
135 | aa26bb2d | ths | int fd;
|
136 | aa26bb2d | ths | |
137 | 40ff6d7e | Kevin Wolf | fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
|
138 | aa26bb2d | ths | if (fd == -1) |
139 | aa26bb2d | ths | return -1; |
140 | aa26bb2d | ths | |
141 | aa26bb2d | ths | if (lockf(fd, F_TLOCK, 0) == -1) |
142 | aa26bb2d | ths | return -1; |
143 | aa26bb2d | ths | |
144 | aa26bb2d | ths | len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); |
145 | aa26bb2d | ths | if (write(fd, buffer, len) != len)
|
146 | aa26bb2d | ths | return -1; |
147 | aa26bb2d | ths | #else
|
148 | aa26bb2d | ths | HANDLE file; |
149 | aa26bb2d | ths | OVERLAPPED overlap; |
150 | aa26bb2d | ths | BOOL ret; |
151 | 099fe236 | Juha Riihimรคki | memset(&overlap, 0, sizeof(overlap)); |
152 | aa26bb2d | ths | |
153 | 099fe236 | Juha Riihimรคki | file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
154 | aa26bb2d | ths | OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
155 | aa26bb2d | ths | |
156 | aa26bb2d | ths | if (file == INVALID_HANDLE_VALUE)
|
157 | aa26bb2d | ths | return -1; |
158 | aa26bb2d | ths | |
159 | aa26bb2d | ths | len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); |
160 | 5fafdf24 | ths | ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, |
161 | aa26bb2d | ths | &overlap, NULL);
|
162 | aa26bb2d | ths | if (ret == 0) |
163 | aa26bb2d | ths | return -1; |
164 | aa26bb2d | ths | #endif
|
165 | aa26bb2d | ths | return 0; |
166 | aa26bb2d | ths | } |
167 | 29b3a662 | pbrook | |
168 | 29b3a662 | pbrook | #ifdef _WIN32
|
169 | 29b3a662 | pbrook | |
170 | 4972d592 | Stefan Weil | /* mingw32 needs ffs for compilations without optimization. */
|
171 | 4972d592 | Stefan Weil | int ffs(int i) |
172 | 4972d592 | Stefan Weil | { |
173 | 4972d592 | Stefan Weil | /* Use gcc's builtin ffs. */
|
174 | 4972d592 | Stefan Weil | return __builtin_ffs(i);
|
175 | 4972d592 | Stefan Weil | } |
176 | 4972d592 | Stefan Weil | |
177 | 29b3a662 | pbrook | /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
|
178 | 29b3a662 | pbrook | #define _W32_FT_OFFSET (116444736000000000ULL) |
179 | 29b3a662 | pbrook | |
180 | 29b3a662 | pbrook | int qemu_gettimeofday(qemu_timeval *tp)
|
181 | 29b3a662 | pbrook | { |
182 | 29b3a662 | pbrook | union {
|
183 | 29b3a662 | pbrook | unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ |
184 | 29b3a662 | pbrook | FILETIME ft; |
185 | 29b3a662 | pbrook | } _now; |
186 | 29b3a662 | pbrook | |
187 | 29b3a662 | pbrook | if(tp)
|
188 | 29b3a662 | pbrook | { |
189 | 29b3a662 | pbrook | GetSystemTimeAsFileTime (&_now.ft); |
190 | 29b3a662 | pbrook | tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); |
191 | 29b3a662 | pbrook | tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); |
192 | 29b3a662 | pbrook | } |
193 | 29b3a662 | pbrook | /* Always return 0 as per Open Group Base Specifications Issue 6.
|
194 | 29b3a662 | pbrook | Do not set errno on error. */
|
195 | 29b3a662 | pbrook | return 0; |
196 | 29b3a662 | pbrook | } |
197 | 29b3a662 | pbrook | #endif /* _WIN32 */ |
198 | 03ff3ca3 | aliguori | |
199 | 03ff3ca3 | aliguori | |
200 | 03ff3ca3 | aliguori | #ifdef _WIN32
|
201 | 03ff3ca3 | aliguori | void socket_set_nonblock(int fd) |
202 | 03ff3ca3 | aliguori | { |
203 | 03ff3ca3 | aliguori | unsigned long opt = 1; |
204 | 03ff3ca3 | aliguori | ioctlsocket(fd, FIONBIO, &opt); |
205 | 03ff3ca3 | aliguori | } |
206 | 03ff3ca3 | aliguori | |
207 | 03ff3ca3 | aliguori | int inet_aton(const char *cp, struct in_addr *ia) |
208 | 03ff3ca3 | aliguori | { |
209 | 03ff3ca3 | aliguori | uint32_t addr = inet_addr(cp); |
210 | 03ff3ca3 | aliguori | if (addr == 0xffffffff) |
211 | 03ff3ca3 | aliguori | return 0; |
212 | 03ff3ca3 | aliguori | ia->s_addr = addr; |
213 | 03ff3ca3 | aliguori | return 1; |
214 | 03ff3ca3 | aliguori | } |
215 | 40ff6d7e | Kevin Wolf | |
216 | 40ff6d7e | Kevin Wolf | void qemu_set_cloexec(int fd) |
217 | 40ff6d7e | Kevin Wolf | { |
218 | 40ff6d7e | Kevin Wolf | } |
219 | 40ff6d7e | Kevin Wolf | |
220 | 03ff3ca3 | aliguori | #else
|
221 | 40ff6d7e | Kevin Wolf | |
222 | 03ff3ca3 | aliguori | void socket_set_nonblock(int fd) |
223 | 03ff3ca3 | aliguori | { |
224 | 03ff3ca3 | aliguori | int f;
|
225 | 03ff3ca3 | aliguori | f = fcntl(fd, F_GETFL); |
226 | 03ff3ca3 | aliguori | fcntl(fd, F_SETFL, f | O_NONBLOCK); |
227 | 03ff3ca3 | aliguori | } |
228 | 40ff6d7e | Kevin Wolf | |
229 | 40ff6d7e | Kevin Wolf | void qemu_set_cloexec(int fd) |
230 | 40ff6d7e | Kevin Wolf | { |
231 | 40ff6d7e | Kevin Wolf | int f;
|
232 | 40ff6d7e | Kevin Wolf | f = fcntl(fd, F_GETFD); |
233 | 40ff6d7e | Kevin Wolf | fcntl(fd, F_SETFD, f | FD_CLOEXEC); |
234 | 40ff6d7e | Kevin Wolf | } |
235 | 40ff6d7e | Kevin Wolf | |
236 | 40ff6d7e | Kevin Wolf | #endif
|
237 | 40ff6d7e | Kevin Wolf | |
238 | 40ff6d7e | Kevin Wolf | /*
|
239 | 40ff6d7e | Kevin Wolf | * Opens a file with FD_CLOEXEC set
|
240 | 40ff6d7e | Kevin Wolf | */
|
241 | 40ff6d7e | Kevin Wolf | int qemu_open(const char *name, int flags, ...) |
242 | 40ff6d7e | Kevin Wolf | { |
243 | 40ff6d7e | Kevin Wolf | int ret;
|
244 | 40ff6d7e | Kevin Wolf | int mode = 0; |
245 | 40ff6d7e | Kevin Wolf | |
246 | 40ff6d7e | Kevin Wolf | if (flags & O_CREAT) {
|
247 | 40ff6d7e | Kevin Wolf | va_list ap; |
248 | 40ff6d7e | Kevin Wolf | |
249 | 40ff6d7e | Kevin Wolf | va_start(ap, flags); |
250 | 40ff6d7e | Kevin Wolf | mode = va_arg(ap, int);
|
251 | 40ff6d7e | Kevin Wolf | va_end(ap); |
252 | 40ff6d7e | Kevin Wolf | } |
253 | 40ff6d7e | Kevin Wolf | |
254 | 40ff6d7e | Kevin Wolf | #ifdef O_CLOEXEC
|
255 | 40ff6d7e | Kevin Wolf | ret = open(name, flags | O_CLOEXEC, mode); |
256 | 40ff6d7e | Kevin Wolf | #else
|
257 | 40ff6d7e | Kevin Wolf | ret = open(name, flags, mode); |
258 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
259 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
260 | 40ff6d7e | Kevin Wolf | } |
261 | 03ff3ca3 | aliguori | #endif
|
262 | 40ff6d7e | Kevin Wolf | |
263 | 40ff6d7e | Kevin Wolf | return ret;
|
264 | 40ff6d7e | Kevin Wolf | } |
265 | 40ff6d7e | Kevin Wolf | |
266 | 7b5f699d | Kirill A. Shutemov | /*
|
267 | 7b5f699d | Kirill A. Shutemov | * A variant of write(2) which handles partial write.
|
268 | 7b5f699d | Kirill A. Shutemov | *
|
269 | 7b5f699d | Kirill A. Shutemov | * Return the number of bytes transferred.
|
270 | 7b5f699d | Kirill A. Shutemov | * Set errno if fewer than `count' bytes are written.
|
271 | 1298cb68 | Juan Quintela | *
|
272 | 1298cb68 | Juan Quintela | * This function don't work with non-blocking fd's.
|
273 | 1298cb68 | Juan Quintela | * Any of the possibilities with non-bloking fd's is bad:
|
274 | 1298cb68 | Juan Quintela | * - return a short write (then name is wrong)
|
275 | 1298cb68 | Juan Quintela | * - busy wait adding (errno == EAGAIN) to the loop
|
276 | 7b5f699d | Kirill A. Shutemov | */
|
277 | 7b5f699d | Kirill A. Shutemov | ssize_t qemu_write_full(int fd, const void *buf, size_t count) |
278 | 7b5f699d | Kirill A. Shutemov | { |
279 | 7b5f699d | Kirill A. Shutemov | ssize_t ret = 0;
|
280 | 7b5f699d | Kirill A. Shutemov | ssize_t total = 0;
|
281 | 7b5f699d | Kirill A. Shutemov | |
282 | 7b5f699d | Kirill A. Shutemov | while (count) {
|
283 | 7b5f699d | Kirill A. Shutemov | ret = write(fd, buf, count); |
284 | 7b5f699d | Kirill A. Shutemov | if (ret < 0) { |
285 | 7b5f699d | Kirill A. Shutemov | if (errno == EINTR)
|
286 | 7b5f699d | Kirill A. Shutemov | continue;
|
287 | 7b5f699d | Kirill A. Shutemov | break;
|
288 | 7b5f699d | Kirill A. Shutemov | } |
289 | 7b5f699d | Kirill A. Shutemov | |
290 | 7b5f699d | Kirill A. Shutemov | count -= ret; |
291 | 7b5f699d | Kirill A. Shutemov | buf += ret; |
292 | 7b5f699d | Kirill A. Shutemov | total += ret; |
293 | 7b5f699d | Kirill A. Shutemov | } |
294 | 7b5f699d | Kirill A. Shutemov | |
295 | 7b5f699d | Kirill A. Shutemov | return total;
|
296 | 7b5f699d | Kirill A. Shutemov | } |
297 | 7b5f699d | Kirill A. Shutemov | |
298 | 40ff6d7e | Kevin Wolf | #ifndef _WIN32
|
299 | 40ff6d7e | Kevin Wolf | /*
|
300 | f3dfda61 | Paolo Bonzini | * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
|
301 | f3dfda61 | Paolo Bonzini | */
|
302 | f3dfda61 | Paolo Bonzini | int qemu_eventfd(int fds[2]) |
303 | f3dfda61 | Paolo Bonzini | { |
304 | 153ceefb | Avi Kivity | #ifdef CONFIG_EVENTFD
|
305 | f3dfda61 | Paolo Bonzini | int ret;
|
306 | f3dfda61 | Paolo Bonzini | |
307 | f3dfda61 | Paolo Bonzini | ret = eventfd(0, 0); |
308 | f3dfda61 | Paolo Bonzini | if (ret >= 0) { |
309 | f3dfda61 | Paolo Bonzini | fds[0] = ret;
|
310 | f3dfda61 | Paolo Bonzini | qemu_set_cloexec(ret); |
311 | f3dfda61 | Paolo Bonzini | if ((fds[1] = dup(ret)) == -1) { |
312 | f3dfda61 | Paolo Bonzini | close(ret); |
313 | f3dfda61 | Paolo Bonzini | return -1; |
314 | f3dfda61 | Paolo Bonzini | } |
315 | f3dfda61 | Paolo Bonzini | qemu_set_cloexec(fds[1]);
|
316 | f3dfda61 | Paolo Bonzini | return 0; |
317 | f3dfda61 | Paolo Bonzini | } |
318 | f3dfda61 | Paolo Bonzini | |
319 | f3dfda61 | Paolo Bonzini | if (errno != ENOSYS) {
|
320 | f3dfda61 | Paolo Bonzini | return -1; |
321 | f3dfda61 | Paolo Bonzini | } |
322 | f3dfda61 | Paolo Bonzini | #endif
|
323 | f3dfda61 | Paolo Bonzini | |
324 | f3dfda61 | Paolo Bonzini | return qemu_pipe(fds);
|
325 | f3dfda61 | Paolo Bonzini | } |
326 | f3dfda61 | Paolo Bonzini | |
327 | f3dfda61 | Paolo Bonzini | /*
|
328 | 40ff6d7e | Kevin Wolf | * Creates a pipe with FD_CLOEXEC set on both file descriptors
|
329 | 40ff6d7e | Kevin Wolf | */
|
330 | 40ff6d7e | Kevin Wolf | int qemu_pipe(int pipefd[2]) |
331 | 40ff6d7e | Kevin Wolf | { |
332 | 40ff6d7e | Kevin Wolf | int ret;
|
333 | 40ff6d7e | Kevin Wolf | |
334 | 40ff6d7e | Kevin Wolf | #ifdef CONFIG_PIPE2
|
335 | 40ff6d7e | Kevin Wolf | ret = pipe2(pipefd, O_CLOEXEC); |
336 | 3a03bfa5 | Andre Przywara | if (ret != -1 || errno != ENOSYS) { |
337 | 3a03bfa5 | Andre Przywara | return ret;
|
338 | 3a03bfa5 | Andre Przywara | } |
339 | 3a03bfa5 | Andre Przywara | #endif
|
340 | 40ff6d7e | Kevin Wolf | ret = pipe(pipefd); |
341 | 40ff6d7e | Kevin Wolf | if (ret == 0) { |
342 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(pipefd[0]);
|
343 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(pipefd[1]);
|
344 | 40ff6d7e | Kevin Wolf | } |
345 | 40ff6d7e | Kevin Wolf | |
346 | 40ff6d7e | Kevin Wolf | return ret;
|
347 | 40ff6d7e | Kevin Wolf | } |
348 | 40ff6d7e | Kevin Wolf | #endif
|
349 | 40ff6d7e | Kevin Wolf | |
350 | 40ff6d7e | Kevin Wolf | /*
|
351 | 40ff6d7e | Kevin Wolf | * Opens a socket with FD_CLOEXEC set
|
352 | 40ff6d7e | Kevin Wolf | */
|
353 | 40ff6d7e | Kevin Wolf | int qemu_socket(int domain, int type, int protocol) |
354 | 40ff6d7e | Kevin Wolf | { |
355 | 40ff6d7e | Kevin Wolf | int ret;
|
356 | 40ff6d7e | Kevin Wolf | |
357 | 40ff6d7e | Kevin Wolf | #ifdef SOCK_CLOEXEC
|
358 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type | SOCK_CLOEXEC, protocol); |
359 | 3a03bfa5 | Andre Przywara | if (ret != -1 || errno != EINVAL) { |
360 | 3a03bfa5 | Andre Przywara | return ret;
|
361 | 3a03bfa5 | Andre Przywara | } |
362 | 3a03bfa5 | Andre Przywara | #endif
|
363 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type, protocol); |
364 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
365 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
366 | 40ff6d7e | Kevin Wolf | } |
367 | 40ff6d7e | Kevin Wolf | |
368 | 40ff6d7e | Kevin Wolf | return ret;
|
369 | 40ff6d7e | Kevin Wolf | } |
370 | 40ff6d7e | Kevin Wolf | |
371 | 40ff6d7e | Kevin Wolf | /*
|
372 | 40ff6d7e | Kevin Wolf | * Accept a connection and set FD_CLOEXEC
|
373 | 40ff6d7e | Kevin Wolf | */
|
374 | 40ff6d7e | Kevin Wolf | int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) |
375 | 40ff6d7e | Kevin Wolf | { |
376 | 40ff6d7e | Kevin Wolf | int ret;
|
377 | 40ff6d7e | Kevin Wolf | |
378 | 40ff6d7e | Kevin Wolf | #ifdef CONFIG_ACCEPT4
|
379 | 40ff6d7e | Kevin Wolf | ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); |
380 | 347ed55c | Kevin Wolf | if (ret != -1 || errno != ENOSYS) { |
381 | 3a03bfa5 | Andre Przywara | return ret;
|
382 | 3a03bfa5 | Andre Przywara | } |
383 | 3a03bfa5 | Andre Przywara | #endif
|
384 | 40ff6d7e | Kevin Wolf | ret = accept(s, addr, addrlen); |
385 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
386 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
387 | 40ff6d7e | Kevin Wolf | } |
388 | 40ff6d7e | Kevin Wolf | |
389 | 40ff6d7e | Kevin Wolf | return ret;
|
390 | 40ff6d7e | Kevin Wolf | } |