root / osdep.c @ 0834c9ea
History | View | Annotate | Download (8.8 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 | 0f66998f | Paul Moore | #include <stdbool.h> |
28 | ea88812f | bellard | #include <string.h> |
29 | ea88812f | bellard | #include <errno.h> |
30 | ea88812f | bellard | #include <unistd.h> |
31 | aa26bb2d | ths | #include <fcntl.h> |
32 | f582af58 | Paolo Bonzini | |
33 | f582af58 | Paolo Bonzini | /* Needed early for CONFIG_BSD etc. */
|
34 | f582af58 | Paolo Bonzini | #include "config-host.h" |
35 | f582af58 | Paolo Bonzini | |
36 | e78815a5 | Andreas Färber | #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
|
37 | e78815a5 | Andreas Färber | #include <sys/mman.h> |
38 | e78815a5 | Andreas Färber | #endif
|
39 | e78815a5 | Andreas Färber | |
40 | dfe5fff3 | Juan Quintela | #ifdef CONFIG_SOLARIS
|
41 | 605686cd | ths | #include <sys/types.h> |
42 | 605686cd | ths | #include <sys/statvfs.h> |
43 | e78815a5 | Andreas Färber | /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
|
44 | e78815a5 | Andreas Färber | discussion about Solaris header problems */
|
45 | e78815a5 | Andreas Färber | extern int madvise(caddr_t, size_t, int); |
46 | 605686cd | ths | #endif
|
47 | ea88812f | bellard | |
48 | 511d2b14 | blueswir1 | #include "qemu-common.h" |
49 | cd245a19 | Stefan Hajnoczi | #include "trace.h" |
50 | 03ff3ca3 | aliguori | #include "qemu_socket.h" |
51 | adb696f3 | Corey Bryant | #include "monitor.h" |
52 | 03ff3ca3 | aliguori | |
53 | 0f66998f | Paul Moore | static bool fips_enabled = false; |
54 | 0f66998f | Paul Moore | |
55 | 93bfef4c | Crístian Viana | static const char *qemu_version = QEMU_VERSION; |
56 | 93bfef4c | Crístian Viana | |
57 | 128aa589 | Paolo Bonzini | int socket_set_cork(int fd, int v) |
58 | 128aa589 | Paolo Bonzini | { |
59 | 128aa589 | Paolo Bonzini | #if defined(SOL_TCP) && defined(TCP_CORK)
|
60 | 128aa589 | Paolo Bonzini | return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v)); |
61 | 128aa589 | Paolo Bonzini | #else
|
62 | 128aa589 | Paolo Bonzini | return 0; |
63 | 128aa589 | Paolo Bonzini | #endif
|
64 | 128aa589 | Paolo Bonzini | } |
65 | 128aa589 | Paolo Bonzini | |
66 | e78815a5 | Andreas Färber | int qemu_madvise(void *addr, size_t len, int advice) |
67 | e78815a5 | Andreas Färber | { |
68 | e78815a5 | Andreas Färber | if (advice == QEMU_MADV_INVALID) {
|
69 | e78815a5 | Andreas Färber | errno = EINVAL; |
70 | e78815a5 | Andreas Färber | return -1; |
71 | e78815a5 | Andreas Färber | } |
72 | e78815a5 | Andreas Färber | #if defined(CONFIG_MADVISE)
|
73 | e78815a5 | Andreas Färber | return madvise(addr, len, advice);
|
74 | e78815a5 | Andreas Färber | #elif defined(CONFIG_POSIX_MADVISE)
|
75 | e78815a5 | Andreas Färber | return posix_madvise(addr, len, advice);
|
76 | e78815a5 | Andreas Färber | #else
|
77 | e78815a5 | Andreas Färber | errno = EINVAL; |
78 | e78815a5 | Andreas Färber | return -1; |
79 | e78815a5 | Andreas Färber | #endif
|
80 | e78815a5 | Andreas Färber | } |
81 | e78815a5 | Andreas Färber | |
82 | adb696f3 | Corey Bryant | #ifndef _WIN32
|
83 | adb696f3 | Corey Bryant | /*
|
84 | adb696f3 | Corey Bryant | * Dups an fd and sets the flags
|
85 | adb696f3 | Corey Bryant | */
|
86 | adb696f3 | Corey Bryant | static int qemu_dup_flags(int fd, int flags) |
87 | adb696f3 | Corey Bryant | { |
88 | adb696f3 | Corey Bryant | int ret;
|
89 | adb696f3 | Corey Bryant | int serrno;
|
90 | adb696f3 | Corey Bryant | int dup_flags;
|
91 | adb696f3 | Corey Bryant | int setfl_flags;
|
92 | adb696f3 | Corey Bryant | |
93 | adb696f3 | Corey Bryant | #ifdef F_DUPFD_CLOEXEC
|
94 | adb696f3 | Corey Bryant | ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
|
95 | adb696f3 | Corey Bryant | #else
|
96 | adb696f3 | Corey Bryant | ret = dup(fd); |
97 | adb696f3 | Corey Bryant | if (ret != -1) { |
98 | adb696f3 | Corey Bryant | qemu_set_cloexec(ret); |
99 | adb696f3 | Corey Bryant | } |
100 | adb696f3 | Corey Bryant | #endif
|
101 | adb696f3 | Corey Bryant | if (ret == -1) { |
102 | adb696f3 | Corey Bryant | goto fail;
|
103 | adb696f3 | Corey Bryant | } |
104 | adb696f3 | Corey Bryant | |
105 | adb696f3 | Corey Bryant | dup_flags = fcntl(ret, F_GETFL); |
106 | adb696f3 | Corey Bryant | if (dup_flags == -1) { |
107 | adb696f3 | Corey Bryant | goto fail;
|
108 | adb696f3 | Corey Bryant | } |
109 | adb696f3 | Corey Bryant | |
110 | adb696f3 | Corey Bryant | if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
|
111 | adb696f3 | Corey Bryant | errno = EINVAL; |
112 | adb696f3 | Corey Bryant | goto fail;
|
113 | adb696f3 | Corey Bryant | } |
114 | adb696f3 | Corey Bryant | |
115 | adb696f3 | Corey Bryant | /* Set/unset flags that we can with fcntl */
|
116 | d973ba18 | Peter Maydell | setfl_flags = O_APPEND | O_ASYNC | O_NONBLOCK; |
117 | d973ba18 | Peter Maydell | #ifdef O_NOATIME
|
118 | d973ba18 | Peter Maydell | setfl_flags |= O_NOATIME; |
119 | d973ba18 | Peter Maydell | #endif
|
120 | d973ba18 | Peter Maydell | #ifdef O_DIRECT
|
121 | d973ba18 | Peter Maydell | setfl_flags |= O_DIRECT; |
122 | d973ba18 | Peter Maydell | #endif
|
123 | adb696f3 | Corey Bryant | dup_flags &= ~setfl_flags; |
124 | adb696f3 | Corey Bryant | dup_flags |= (flags & setfl_flags); |
125 | adb696f3 | Corey Bryant | if (fcntl(ret, F_SETFL, dup_flags) == -1) { |
126 | adb696f3 | Corey Bryant | goto fail;
|
127 | adb696f3 | Corey Bryant | } |
128 | adb696f3 | Corey Bryant | |
129 | adb696f3 | Corey Bryant | /* Truncate the file in the cases that open() would truncate it */
|
130 | adb696f3 | Corey Bryant | if (flags & O_TRUNC ||
|
131 | adb696f3 | Corey Bryant | ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) { |
132 | adb696f3 | Corey Bryant | if (ftruncate(ret, 0) == -1) { |
133 | adb696f3 | Corey Bryant | goto fail;
|
134 | adb696f3 | Corey Bryant | } |
135 | adb696f3 | Corey Bryant | } |
136 | adb696f3 | Corey Bryant | |
137 | adb696f3 | Corey Bryant | return ret;
|
138 | adb696f3 | Corey Bryant | |
139 | adb696f3 | Corey Bryant | fail:
|
140 | adb696f3 | Corey Bryant | serrno = errno; |
141 | adb696f3 | Corey Bryant | if (ret != -1) { |
142 | adb696f3 | Corey Bryant | close(ret); |
143 | adb696f3 | Corey Bryant | } |
144 | adb696f3 | Corey Bryant | errno = serrno; |
145 | adb696f3 | Corey Bryant | return -1; |
146 | adb696f3 | Corey Bryant | } |
147 | adb696f3 | Corey Bryant | #endif
|
148 | 03ff3ca3 | aliguori | |
149 | 40ff6d7e | Kevin Wolf | /*
|
150 | 40ff6d7e | Kevin Wolf | * Opens a file with FD_CLOEXEC set
|
151 | 40ff6d7e | Kevin Wolf | */
|
152 | 40ff6d7e | Kevin Wolf | int qemu_open(const char *name, int flags, ...) |
153 | 40ff6d7e | Kevin Wolf | { |
154 | 40ff6d7e | Kevin Wolf | int ret;
|
155 | 40ff6d7e | Kevin Wolf | int mode = 0; |
156 | 40ff6d7e | Kevin Wolf | |
157 | adb696f3 | Corey Bryant | #ifndef _WIN32
|
158 | adb696f3 | Corey Bryant | const char *fdset_id_str; |
159 | adb696f3 | Corey Bryant | |
160 | adb696f3 | Corey Bryant | /* Attempt dup of fd from fd set */
|
161 | adb696f3 | Corey Bryant | if (strstart(name, "/dev/fdset/", &fdset_id_str)) { |
162 | adb696f3 | Corey Bryant | int64_t fdset_id; |
163 | adb696f3 | Corey Bryant | int fd, dupfd;
|
164 | adb696f3 | Corey Bryant | |
165 | adb696f3 | Corey Bryant | fdset_id = qemu_parse_fdset(fdset_id_str); |
166 | adb696f3 | Corey Bryant | if (fdset_id == -1) { |
167 | adb696f3 | Corey Bryant | errno = EINVAL; |
168 | adb696f3 | Corey Bryant | return -1; |
169 | adb696f3 | Corey Bryant | } |
170 | adb696f3 | Corey Bryant | |
171 | adb696f3 | Corey Bryant | fd = monitor_fdset_get_fd(fdset_id, flags); |
172 | adb696f3 | Corey Bryant | if (fd == -1) { |
173 | adb696f3 | Corey Bryant | return -1; |
174 | adb696f3 | Corey Bryant | } |
175 | adb696f3 | Corey Bryant | |
176 | adb696f3 | Corey Bryant | dupfd = qemu_dup_flags(fd, flags); |
177 | adb696f3 | Corey Bryant | if (dupfd == -1) { |
178 | adb696f3 | Corey Bryant | return -1; |
179 | adb696f3 | Corey Bryant | } |
180 | adb696f3 | Corey Bryant | |
181 | adb696f3 | Corey Bryant | ret = monitor_fdset_dup_fd_add(fdset_id, dupfd); |
182 | adb696f3 | Corey Bryant | if (ret == -1) { |
183 | adb696f3 | Corey Bryant | close(dupfd); |
184 | adb696f3 | Corey Bryant | errno = EINVAL; |
185 | adb696f3 | Corey Bryant | return -1; |
186 | adb696f3 | Corey Bryant | } |
187 | adb696f3 | Corey Bryant | |
188 | adb696f3 | Corey Bryant | return dupfd;
|
189 | adb696f3 | Corey Bryant | } |
190 | adb696f3 | Corey Bryant | #endif
|
191 | adb696f3 | Corey Bryant | |
192 | 40ff6d7e | Kevin Wolf | if (flags & O_CREAT) {
|
193 | 40ff6d7e | Kevin Wolf | va_list ap; |
194 | 40ff6d7e | Kevin Wolf | |
195 | 40ff6d7e | Kevin Wolf | va_start(ap, flags); |
196 | 40ff6d7e | Kevin Wolf | mode = va_arg(ap, int);
|
197 | 40ff6d7e | Kevin Wolf | va_end(ap); |
198 | 40ff6d7e | Kevin Wolf | } |
199 | 40ff6d7e | Kevin Wolf | |
200 | 40ff6d7e | Kevin Wolf | #ifdef O_CLOEXEC
|
201 | 40ff6d7e | Kevin Wolf | ret = open(name, flags | O_CLOEXEC, mode); |
202 | 40ff6d7e | Kevin Wolf | #else
|
203 | 40ff6d7e | Kevin Wolf | ret = open(name, flags, mode); |
204 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
205 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
206 | 40ff6d7e | Kevin Wolf | } |
207 | 03ff3ca3 | aliguori | #endif
|
208 | 40ff6d7e | Kevin Wolf | |
209 | 40ff6d7e | Kevin Wolf | return ret;
|
210 | 40ff6d7e | Kevin Wolf | } |
211 | 40ff6d7e | Kevin Wolf | |
212 | 2e1e79da | Corey Bryant | int qemu_close(int fd) |
213 | 2e1e79da | Corey Bryant | { |
214 | adb696f3 | Corey Bryant | int64_t fdset_id; |
215 | adb696f3 | Corey Bryant | |
216 | adb696f3 | Corey Bryant | /* Close fd that was dup'd from an fdset */
|
217 | adb696f3 | Corey Bryant | fdset_id = monitor_fdset_dup_fd_find(fd); |
218 | adb696f3 | Corey Bryant | if (fdset_id != -1) { |
219 | adb696f3 | Corey Bryant | int ret;
|
220 | adb696f3 | Corey Bryant | |
221 | adb696f3 | Corey Bryant | ret = close(fd); |
222 | adb696f3 | Corey Bryant | if (ret == 0) { |
223 | adb696f3 | Corey Bryant | monitor_fdset_dup_fd_remove(fd); |
224 | adb696f3 | Corey Bryant | } |
225 | adb696f3 | Corey Bryant | |
226 | adb696f3 | Corey Bryant | return ret;
|
227 | adb696f3 | Corey Bryant | } |
228 | adb696f3 | Corey Bryant | |
229 | 2e1e79da | Corey Bryant | return close(fd);
|
230 | 2e1e79da | Corey Bryant | } |
231 | 2e1e79da | Corey Bryant | |
232 | 7b5f699d | Kirill A. Shutemov | /*
|
233 | 7b5f699d | Kirill A. Shutemov | * A variant of write(2) which handles partial write.
|
234 | 7b5f699d | Kirill A. Shutemov | *
|
235 | 7b5f699d | Kirill A. Shutemov | * Return the number of bytes transferred.
|
236 | 7b5f699d | Kirill A. Shutemov | * Set errno if fewer than `count' bytes are written.
|
237 | 1298cb68 | Juan Quintela | *
|
238 | 1298cb68 | Juan Quintela | * This function don't work with non-blocking fd's.
|
239 | 1298cb68 | Juan Quintela | * Any of the possibilities with non-bloking fd's is bad:
|
240 | 1298cb68 | Juan Quintela | * - return a short write (then name is wrong)
|
241 | 1298cb68 | Juan Quintela | * - busy wait adding (errno == EAGAIN) to the loop
|
242 | 7b5f699d | Kirill A. Shutemov | */
|
243 | 7b5f699d | Kirill A. Shutemov | ssize_t qemu_write_full(int fd, const void *buf, size_t count) |
244 | 7b5f699d | Kirill A. Shutemov | { |
245 | 7b5f699d | Kirill A. Shutemov | ssize_t ret = 0;
|
246 | 7b5f699d | Kirill A. Shutemov | ssize_t total = 0;
|
247 | 7b5f699d | Kirill A. Shutemov | |
248 | 7b5f699d | Kirill A. Shutemov | while (count) {
|
249 | 7b5f699d | Kirill A. Shutemov | ret = write(fd, buf, count); |
250 | 7b5f699d | Kirill A. Shutemov | if (ret < 0) { |
251 | 7b5f699d | Kirill A. Shutemov | if (errno == EINTR)
|
252 | 7b5f699d | Kirill A. Shutemov | continue;
|
253 | 7b5f699d | Kirill A. Shutemov | break;
|
254 | 7b5f699d | Kirill A. Shutemov | } |
255 | 7b5f699d | Kirill A. Shutemov | |
256 | 7b5f699d | Kirill A. Shutemov | count -= ret; |
257 | 7b5f699d | Kirill A. Shutemov | buf += ret; |
258 | 7b5f699d | Kirill A. Shutemov | total += ret; |
259 | 7b5f699d | Kirill A. Shutemov | } |
260 | 7b5f699d | Kirill A. Shutemov | |
261 | 7b5f699d | Kirill A. Shutemov | return total;
|
262 | 7b5f699d | Kirill A. Shutemov | } |
263 | 7b5f699d | Kirill A. Shutemov | |
264 | 40ff6d7e | Kevin Wolf | /*
|
265 | 40ff6d7e | Kevin Wolf | * Opens a socket with FD_CLOEXEC set
|
266 | 40ff6d7e | Kevin Wolf | */
|
267 | 40ff6d7e | Kevin Wolf | int qemu_socket(int domain, int type, int protocol) |
268 | 40ff6d7e | Kevin Wolf | { |
269 | 40ff6d7e | Kevin Wolf | int ret;
|
270 | 40ff6d7e | Kevin Wolf | |
271 | 40ff6d7e | Kevin Wolf | #ifdef SOCK_CLOEXEC
|
272 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type | SOCK_CLOEXEC, protocol); |
273 | 3a03bfa5 | Andre Przywara | if (ret != -1 || errno != EINVAL) { |
274 | 3a03bfa5 | Andre Przywara | return ret;
|
275 | 3a03bfa5 | Andre Przywara | } |
276 | 3a03bfa5 | Andre Przywara | #endif
|
277 | 40ff6d7e | Kevin Wolf | ret = socket(domain, type, protocol); |
278 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
279 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
280 | 40ff6d7e | Kevin Wolf | } |
281 | 40ff6d7e | Kevin Wolf | |
282 | 40ff6d7e | Kevin Wolf | return ret;
|
283 | 40ff6d7e | Kevin Wolf | } |
284 | 40ff6d7e | Kevin Wolf | |
285 | 40ff6d7e | Kevin Wolf | /*
|
286 | 40ff6d7e | Kevin Wolf | * Accept a connection and set FD_CLOEXEC
|
287 | 40ff6d7e | Kevin Wolf | */
|
288 | 40ff6d7e | Kevin Wolf | int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) |
289 | 40ff6d7e | Kevin Wolf | { |
290 | 40ff6d7e | Kevin Wolf | int ret;
|
291 | 40ff6d7e | Kevin Wolf | |
292 | 40ff6d7e | Kevin Wolf | #ifdef CONFIG_ACCEPT4
|
293 | 40ff6d7e | Kevin Wolf | ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); |
294 | 347ed55c | Kevin Wolf | if (ret != -1 || errno != ENOSYS) { |
295 | 3a03bfa5 | Andre Przywara | return ret;
|
296 | 3a03bfa5 | Andre Przywara | } |
297 | 3a03bfa5 | Andre Przywara | #endif
|
298 | 40ff6d7e | Kevin Wolf | ret = accept(s, addr, addrlen); |
299 | 40ff6d7e | Kevin Wolf | if (ret >= 0) { |
300 | 40ff6d7e | Kevin Wolf | qemu_set_cloexec(ret); |
301 | 40ff6d7e | Kevin Wolf | } |
302 | 40ff6d7e | Kevin Wolf | |
303 | 40ff6d7e | Kevin Wolf | return ret;
|
304 | 40ff6d7e | Kevin Wolf | } |
305 | 993295fe | Paolo Bonzini | |
306 | 993295fe | Paolo Bonzini | /*
|
307 | 993295fe | Paolo Bonzini | * A variant of send(2) which handles partial write.
|
308 | 993295fe | Paolo Bonzini | *
|
309 | 993295fe | Paolo Bonzini | * Return the number of bytes transferred, which is only
|
310 | 993295fe | Paolo Bonzini | * smaller than `count' if there is an error.
|
311 | 993295fe | Paolo Bonzini | *
|
312 | 993295fe | Paolo Bonzini | * This function won't work with non-blocking fd's.
|
313 | 993295fe | Paolo Bonzini | * Any of the possibilities with non-bloking fd's is bad:
|
314 | 993295fe | Paolo Bonzini | * - return a short write (then name is wrong)
|
315 | 993295fe | Paolo Bonzini | * - busy wait adding (errno == EAGAIN) to the loop
|
316 | 993295fe | Paolo Bonzini | */
|
317 | 993295fe | Paolo Bonzini | ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags) |
318 | 993295fe | Paolo Bonzini | { |
319 | 993295fe | Paolo Bonzini | ssize_t ret = 0;
|
320 | 993295fe | Paolo Bonzini | ssize_t total = 0;
|
321 | 993295fe | Paolo Bonzini | |
322 | 993295fe | Paolo Bonzini | while (count) {
|
323 | 993295fe | Paolo Bonzini | ret = send(fd, buf, count, flags); |
324 | 993295fe | Paolo Bonzini | if (ret < 0) { |
325 | 993295fe | Paolo Bonzini | if (errno == EINTR) {
|
326 | 993295fe | Paolo Bonzini | continue;
|
327 | 993295fe | Paolo Bonzini | } |
328 | 993295fe | Paolo Bonzini | break;
|
329 | 993295fe | Paolo Bonzini | } |
330 | 993295fe | Paolo Bonzini | |
331 | 993295fe | Paolo Bonzini | count -= ret; |
332 | 993295fe | Paolo Bonzini | buf += ret; |
333 | 993295fe | Paolo Bonzini | total += ret; |
334 | 993295fe | Paolo Bonzini | } |
335 | 993295fe | Paolo Bonzini | |
336 | 993295fe | Paolo Bonzini | return total;
|
337 | 993295fe | Paolo Bonzini | } |
338 | 993295fe | Paolo Bonzini | |
339 | 993295fe | Paolo Bonzini | /*
|
340 | 993295fe | Paolo Bonzini | * A variant of recv(2) which handles partial write.
|
341 | 993295fe | Paolo Bonzini | *
|
342 | 993295fe | Paolo Bonzini | * Return the number of bytes transferred, which is only
|
343 | 993295fe | Paolo Bonzini | * smaller than `count' if there is an error.
|
344 | 993295fe | Paolo Bonzini | *
|
345 | 993295fe | Paolo Bonzini | * This function won't work with non-blocking fd's.
|
346 | 993295fe | Paolo Bonzini | * Any of the possibilities with non-bloking fd's is bad:
|
347 | 993295fe | Paolo Bonzini | * - return a short write (then name is wrong)
|
348 | 993295fe | Paolo Bonzini | * - busy wait adding (errno == EAGAIN) to the loop
|
349 | 993295fe | Paolo Bonzini | */
|
350 | 993295fe | Paolo Bonzini | ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags) |
351 | 993295fe | Paolo Bonzini | { |
352 | 993295fe | Paolo Bonzini | ssize_t ret = 0;
|
353 | 993295fe | Paolo Bonzini | ssize_t total = 0;
|
354 | 993295fe | Paolo Bonzini | |
355 | 993295fe | Paolo Bonzini | while (count) {
|
356 | 993295fe | Paolo Bonzini | ret = qemu_recv(fd, buf, count, flags); |
357 | 993295fe | Paolo Bonzini | if (ret <= 0) { |
358 | 993295fe | Paolo Bonzini | if (ret < 0 && errno == EINTR) { |
359 | 993295fe | Paolo Bonzini | continue;
|
360 | 993295fe | Paolo Bonzini | } |
361 | 993295fe | Paolo Bonzini | break;
|
362 | 993295fe | Paolo Bonzini | } |
363 | 993295fe | Paolo Bonzini | |
364 | 993295fe | Paolo Bonzini | count -= ret; |
365 | 993295fe | Paolo Bonzini | buf += ret; |
366 | 993295fe | Paolo Bonzini | total += ret; |
367 | 993295fe | Paolo Bonzini | } |
368 | 993295fe | Paolo Bonzini | |
369 | 993295fe | Paolo Bonzini | return total;
|
370 | 993295fe | Paolo Bonzini | } |
371 | 993295fe | Paolo Bonzini | |
372 | 93bfef4c | Crístian Viana | void qemu_set_version(const char *version) |
373 | 93bfef4c | Crístian Viana | { |
374 | 93bfef4c | Crístian Viana | qemu_version = version; |
375 | 93bfef4c | Crístian Viana | } |
376 | 93bfef4c | Crístian Viana | |
377 | 93bfef4c | Crístian Viana | const char *qemu_get_version(void) |
378 | 93bfef4c | Crístian Viana | { |
379 | 93bfef4c | Crístian Viana | return qemu_version;
|
380 | 93bfef4c | Crístian Viana | } |
381 | 0f66998f | Paul Moore | |
382 | 0f66998f | Paul Moore | void fips_set_state(bool requested) |
383 | 0f66998f | Paul Moore | { |
384 | 0f66998f | Paul Moore | #ifdef __linux__
|
385 | 0f66998f | Paul Moore | if (requested) {
|
386 | 0f66998f | Paul Moore | FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r"); |
387 | 0f66998f | Paul Moore | if (fds != NULL) { |
388 | 0f66998f | Paul Moore | fips_enabled = (fgetc(fds) == '1');
|
389 | 0f66998f | Paul Moore | fclose(fds); |
390 | 0f66998f | Paul Moore | } |
391 | 0f66998f | Paul Moore | } |
392 | 0f66998f | Paul Moore | #else
|
393 | 0f66998f | Paul Moore | fips_enabled = false;
|
394 | 0f66998f | Paul Moore | #endif /* __linux__ */ |
395 | 0f66998f | Paul Moore | |
396 | 0f66998f | Paul Moore | #ifdef _FIPS_DEBUG
|
397 | 0f66998f | Paul Moore | fprintf(stderr, "FIPS mode %s (requested %s)\n",
|
398 | 0f66998f | Paul Moore | (fips_enabled ? "enabled" : "disabled"), |
399 | 0f66998f | Paul Moore | (requested ? "enabled" : "disabled")); |
400 | 0f66998f | Paul Moore | #endif
|
401 | 0f66998f | Paul Moore | } |
402 | 0f66998f | Paul Moore | |
403 | 0f66998f | Paul Moore | bool fips_get_state(void) |
404 | 0f66998f | Paul Moore | { |
405 | 0f66998f | Paul Moore | return fips_enabled;
|
406 | 0f66998f | Paul Moore | } |