root / osdep.c @ a74cdab4
History | View | Annotate | Download (4 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 | e78815a5 | Andreas Färber | #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
|
36 | e78815a5 | Andreas Färber | #include <sys/mman.h> |
37 | e78815a5 | Andreas Färber | #endif
|
38 | e78815a5 | Andreas Färber | |
39 | dfe5fff3 | Juan Quintela | #ifdef CONFIG_SOLARIS
|
40 | 605686cd | ths | #include <sys/types.h> |
41 | 605686cd | ths | #include <sys/statvfs.h> |
42 | e78815a5 | Andreas Färber | /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
|
43 | e78815a5 | Andreas Färber | discussion about Solaris header problems */
|
44 | e78815a5 | Andreas Färber | extern int madvise(caddr_t, size_t, int); |
45 | 605686cd | ths | #endif
|
46 | ea88812f | bellard | |
47 | 511d2b14 | blueswir1 | #include "qemu-common.h" |
48 | cd245a19 | Stefan Hajnoczi | #include "trace.h" |
49 | 03ff3ca3 | aliguori | #include "qemu_socket.h" |
50 | 03ff3ca3 | aliguori | |
51 | e78815a5 | Andreas Färber | int qemu_madvise(void *addr, size_t len, int advice) |
52 | e78815a5 | Andreas Färber | { |
53 | e78815a5 | Andreas Färber | if (advice == QEMU_MADV_INVALID) {
|
54 | e78815a5 | Andreas Färber | errno = EINVAL; |
55 | e78815a5 | Andreas Färber | return -1; |
56 | e78815a5 | Andreas Färber | } |
57 | e78815a5 | Andreas Färber | #if defined(CONFIG_MADVISE)
|
58 | e78815a5 | Andreas Färber | return madvise(addr, len, advice);
|
59 | e78815a5 | Andreas Färber | #elif defined(CONFIG_POSIX_MADVISE)
|
60 | e78815a5 | Andreas Färber | return posix_madvise(addr, len, advice);
|
61 | e78815a5 | Andreas Färber | #else
|
62 | e78815a5 | Andreas Färber | errno = EINVAL; |
63 | e78815a5 | Andreas Färber | return -1; |
64 | e78815a5 | Andreas Färber | #endif
|
65 | e78815a5 | Andreas Färber | } |
66 | e78815a5 | Andreas Färber | |
67 | 03ff3ca3 | aliguori | |
68 | 40ff6d7e | Kevin Wolf | /*
|
69 | 40ff6d7e | Kevin Wolf | * Opens a file with FD_CLOEXEC set
|
70 | 40ff6d7e | Kevin Wolf | */
|
71 | 40ff6d7e | Kevin Wolf | int qemu_open(const char *name, int flags, ...) |
72 | 40ff6d7e | Kevin Wolf | { |
73 | 40ff6d7e | Kevin Wolf | int ret;
|
74 | 40ff6d7e | Kevin Wolf | int mode = 0; |
75 | 40ff6d7e | Kevin Wolf | |
76 | 40ff6d7e | Kevin Wolf | if (flags & O_CREAT) {
|
77 | 40ff6d7e | Kevin Wolf | va_list ap; |
78 | 40ff6d7e | Kevin Wolf | |
79 | 40ff6d7e | Kevin Wolf | va_start(ap, flags); |
80 | 40ff6d7e | Kevin Wolf | mode = va_arg(ap, int);
|
81 | 40ff6d7e | Kevin Wolf | va_end(ap); |
82 | 40ff6d7e | Kevin Wolf | } |
83 | 40ff6d7e | Kevin Wolf | |
84 | 40ff6d7e | Kevin Wolf | #ifdef O_CLOEXEC
|
85 | 40ff6d7e | Kevin Wolf | ret = open(name, flags | O_CLOEXEC, mode); |
86 | 40ff6d7e | Kevin Wolf | #else
|
87 | 40ff6d7e | Kevin Wolf | ret = open(name, flags, mode); |
88 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
89 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
90 | 40ff6d7e | Kevin Wolf | } |
91 | 03ff3ca3 | aliguori | #endif
|
92 | 40ff6d7e | Kevin Wolf | |
93 | 40ff6d7e | Kevin Wolf | return ret;
|
94 | 40ff6d7e | Kevin Wolf | } |
95 | 40ff6d7e | Kevin Wolf | |
96 | 7b5f699d | Kirill A. Shutemov | /*
|
97 | 7b5f699d | Kirill A. Shutemov | * A variant of write(2) which handles partial write.
|
98 | 7b5f699d | Kirill A. Shutemov | *
|
99 | 7b5f699d | Kirill A. Shutemov | * Return the number of bytes transferred.
|
100 | 7b5f699d | Kirill A. Shutemov | * Set errno if fewer than `count' bytes are written.
|
101 | 1298cb68 | Juan Quintela | *
|
102 | 1298cb68 | Juan Quintela | * This function don't work with non-blocking fd's.
|
103 | 1298cb68 | Juan Quintela | * Any of the possibilities with non-bloking fd's is bad:
|
104 | 1298cb68 | Juan Quintela | * - return a short write (then name is wrong)
|
105 | 1298cb68 | Juan Quintela | * - busy wait adding (errno == EAGAIN) to the loop
|
106 | 7b5f699d | Kirill A. Shutemov | */
|
107 | 7b5f699d | Kirill A. Shutemov | ssize_t qemu_write_full(int fd, const void *buf, size_t count) |
108 | 7b5f699d | Kirill A. Shutemov | { |
109 | 7b5f699d | Kirill A. Shutemov | ssize_t ret = 0;
|
110 | 7b5f699d | Kirill A. Shutemov | ssize_t total = 0;
|
111 | 7b5f699d | Kirill A. Shutemov | |
112 | 7b5f699d | Kirill A. Shutemov | while (count) {
|
113 | 7b5f699d | Kirill A. Shutemov | ret = write(fd, buf, count); |
114 | 7b5f699d | Kirill A. Shutemov | if (ret < 0) { |
115 | 7b5f699d | Kirill A. Shutemov | if (errno == EINTR)
|
116 | 7b5f699d | Kirill A. Shutemov | continue;
|
117 | 7b5f699d | Kirill A. Shutemov | break;
|
118 | 7b5f699d | Kirill A. Shutemov | } |
119 | 7b5f699d | Kirill A. Shutemov | |
120 | 7b5f699d | Kirill A. Shutemov | count -= ret; |
121 | 7b5f699d | Kirill A. Shutemov | buf += ret; |
122 | 7b5f699d | Kirill A. Shutemov | total += ret; |
123 | 7b5f699d | Kirill A. Shutemov | } |
124 | 7b5f699d | Kirill A. Shutemov | |
125 | 7b5f699d | Kirill A. Shutemov | return total;
|
126 | 7b5f699d | Kirill A. Shutemov | } |
127 | 7b5f699d | Kirill A. Shutemov | |
128 | 40ff6d7e | Kevin Wolf | /*
|
129 | 40ff6d7e | Kevin Wolf | * Opens a socket with FD_CLOEXEC set
|
130 | 40ff6d7e | Kevin Wolf | */
|
131 | 40ff6d7e | Kevin Wolf | int qemu_socket(int domain, int type, int protocol) |
132 | 40ff6d7e | Kevin Wolf | { |
133 | 40ff6d7e | Kevin Wolf | int ret;
|
134 | 40ff6d7e | Kevin Wolf | |
135 | 40ff6d7e | Kevin Wolf | #ifdef SOCK_CLOEXEC
|
136 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type | SOCK_CLOEXEC, protocol); |
137 | 3a03bfa5 | Andre Przywara | if (ret != -1 || errno != EINVAL) { |
138 | 3a03bfa5 | Andre Przywara | return ret;
|
139 | 3a03bfa5 | Andre Przywara | } |
140 | 3a03bfa5 | Andre Przywara | #endif
|
141 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type, protocol); |
142 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
143 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
144 | 40ff6d7e | Kevin Wolf | } |
145 | 40ff6d7e | Kevin Wolf | |
146 | 40ff6d7e | Kevin Wolf | return ret;
|
147 | 40ff6d7e | Kevin Wolf | } |
148 | 40ff6d7e | Kevin Wolf | |
149 | 40ff6d7e | Kevin Wolf | /*
|
150 | 40ff6d7e | Kevin Wolf | * Accept a connection and set FD_CLOEXEC
|
151 | 40ff6d7e | Kevin Wolf | */
|
152 | 40ff6d7e | Kevin Wolf | int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) |
153 | 40ff6d7e | Kevin Wolf | { |
154 | 40ff6d7e | Kevin Wolf | int ret;
|
155 | 40ff6d7e | Kevin Wolf | |
156 | 40ff6d7e | Kevin Wolf | #ifdef CONFIG_ACCEPT4
|
157 | 40ff6d7e | Kevin Wolf | ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); |
158 | 347ed55c | Kevin Wolf | if (ret != -1 || errno != ENOSYS) { |
159 | 3a03bfa5 | Andre Przywara | return ret;
|
160 | 3a03bfa5 | Andre Przywara | } |
161 | 3a03bfa5 | Andre Przywara | #endif
|
162 | 40ff6d7e | Kevin Wolf | ret = accept(s, addr, addrlen); |
163 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
164 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
165 | 40ff6d7e | Kevin Wolf | } |
166 | 40ff6d7e | Kevin Wolf | |
167 | 40ff6d7e | Kevin Wolf | return ret;
|
168 | 40ff6d7e | Kevin Wolf | } |