nbd: fixes to read-only handling
[qemu/opensuse.git] / osdep.c
blob2f7a49159a65e9da08c37c82f071e880100ed2cd
1 /*
2 * QEMU low level functions
4 * Copyright (c) 2003 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <stdbool.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <fcntl.h>
33 /* Needed early for CONFIG_BSD etc. */
34 #include "config-host.h"
36 #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
37 #include <sys/mman.h>
38 #endif
40 #ifdef CONFIG_SOLARIS
41 #include <sys/types.h>
42 #include <sys/statvfs.h>
43 /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
44 discussion about Solaris header problems */
45 extern int madvise(caddr_t, size_t, int);
46 #endif
48 #include "qemu-common.h"
49 #include "trace.h"
50 #include "qemu_socket.h"
51 #include "monitor.h"
53 static bool fips_enabled = false;
55 static const char *qemu_version = QEMU_VERSION;
57 static int default_fdset_get_fd(int64_t fdset_id, int flags)
59 return -1;
61 QEMU_WEAK_ALIAS(monitor_fdset_get_fd, default_fdset_get_fd);
62 #define monitor_fdset_get_fd \
63 QEMU_WEAK_REF(monitor_fdset_get_fd, default_fdset_get_fd)
65 static int default_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
67 return -1;
69 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add);
70 #define monitor_fdset_dup_fd_add \
71 QEMU_WEAK_REF(monitor_fdset_dup_fd_add, default_fdset_dup_fd_add)
73 static int default_fdset_dup_fd_remove(int dup_fd)
75 return -1;
77 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove);
78 #define monitor_fdset_dup_fd_remove \
79 QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_remove)
81 static int default_fdset_dup_fd_find(int dup_fd)
83 return -1;
85 QEMU_WEAK_ALIAS(monitor_fdset_dup_fd_find, default_fdset_dup_fd_find);
86 #define monitor_fdset_dup_fd_find \
87 QEMU_WEAK_REF(monitor_fdset_dup_fd_remove, default_fdset_dup_fd_find)
89 int socket_set_cork(int fd, int v)
91 #if defined(SOL_TCP) && defined(TCP_CORK)
92 return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
93 #else
94 return 0;
95 #endif
98 int qemu_madvise(void *addr, size_t len, int advice)
100 if (advice == QEMU_MADV_INVALID) {
101 errno = EINVAL;
102 return -1;
104 #if defined(CONFIG_MADVISE)
105 return madvise(addr, len, advice);
106 #elif defined(CONFIG_POSIX_MADVISE)
107 return posix_madvise(addr, len, advice);
108 #else
109 errno = EINVAL;
110 return -1;
111 #endif
114 #ifndef _WIN32
116 * Dups an fd and sets the flags
118 static int qemu_dup_flags(int fd, int flags)
120 int ret;
121 int serrno;
122 int dup_flags;
124 #ifdef F_DUPFD_CLOEXEC
125 ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
126 #else
127 ret = dup(fd);
128 if (ret != -1) {
129 qemu_set_cloexec(ret);
131 #endif
132 if (ret == -1) {
133 goto fail;
136 dup_flags = fcntl(ret, F_GETFL);
137 if (dup_flags == -1) {
138 goto fail;
141 if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
142 errno = EINVAL;
143 goto fail;
146 /* Set/unset flags that we can with fcntl */
147 if (fcntl(ret, F_SETFL, flags) == -1) {
148 goto fail;
151 /* Truncate the file in the cases that open() would truncate it */
152 if (flags & O_TRUNC ||
153 ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
154 if (ftruncate(ret, 0) == -1) {
155 goto fail;
159 return ret;
161 fail:
162 serrno = errno;
163 if (ret != -1) {
164 close(ret);
166 errno = serrno;
167 return -1;
170 static int qemu_parse_fdset(const char *param)
172 return qemu_parse_fd(param);
174 #endif
177 * Opens a file with FD_CLOEXEC set
179 int qemu_open(const char *name, int flags, ...)
181 int ret;
182 int mode = 0;
184 #ifndef _WIN32
185 const char *fdset_id_str;
187 /* Attempt dup of fd from fd set */
188 if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
189 int64_t fdset_id;
190 int fd, dupfd;
192 fdset_id = qemu_parse_fdset(fdset_id_str);
193 if (fdset_id == -1) {
194 errno = EINVAL;
195 return -1;
198 fd = monitor_fdset_get_fd(fdset_id, flags);
199 if (fd == -1) {
200 return -1;
203 dupfd = qemu_dup_flags(fd, flags);
204 if (dupfd == -1) {
205 return -1;
208 ret = monitor_fdset_dup_fd_add(fdset_id, dupfd);
209 if (ret == -1) {
210 close(dupfd);
211 errno = EINVAL;
212 return -1;
215 return dupfd;
217 #endif
219 if (flags & O_CREAT) {
220 va_list ap;
222 va_start(ap, flags);
223 mode = va_arg(ap, int);
224 va_end(ap);
227 #ifdef O_CLOEXEC
228 ret = open(name, flags | O_CLOEXEC, mode);
229 #else
230 ret = open(name, flags, mode);
231 if (ret >= 0) {
232 qemu_set_cloexec(ret);
234 #endif
236 return ret;
239 int qemu_close(int fd)
241 int64_t fdset_id;
243 /* Close fd that was dup'd from an fdset */
244 fdset_id = monitor_fdset_dup_fd_find(fd);
245 if (fdset_id != -1) {
246 int ret;
248 ret = close(fd);
249 if (ret == 0) {
250 monitor_fdset_dup_fd_remove(fd);
253 return ret;
256 return close(fd);
260 * A variant of write(2) which handles partial write.
262 * Return the number of bytes transferred.
263 * Set errno if fewer than `count' bytes are written.
265 * This function don't work with non-blocking fd's.
266 * Any of the possibilities with non-bloking fd's is bad:
267 * - return a short write (then name is wrong)
268 * - busy wait adding (errno == EAGAIN) to the loop
270 ssize_t qemu_write_full(int fd, const void *buf, size_t count)
272 ssize_t ret = 0;
273 ssize_t total = 0;
275 while (count) {
276 ret = write(fd, buf, count);
277 if (ret < 0) {
278 if (errno == EINTR)
279 continue;
280 break;
283 count -= ret;
284 buf += ret;
285 total += ret;
288 return total;
292 * Opens a socket with FD_CLOEXEC set
294 int qemu_socket(int domain, int type, int protocol)
296 int ret;
298 #ifdef SOCK_CLOEXEC
299 ret = socket(domain, type | SOCK_CLOEXEC, protocol);
300 if (ret != -1 || errno != EINVAL) {
301 return ret;
303 #endif
304 ret = socket(domain, type, protocol);
305 if (ret >= 0) {
306 qemu_set_cloexec(ret);
309 return ret;
313 * Accept a connection and set FD_CLOEXEC
315 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
317 int ret;
319 #ifdef CONFIG_ACCEPT4
320 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
321 if (ret != -1 || errno != ENOSYS) {
322 return ret;
324 #endif
325 ret = accept(s, addr, addrlen);
326 if (ret >= 0) {
327 qemu_set_cloexec(ret);
330 return ret;
334 * A variant of send(2) which handles partial write.
336 * Return the number of bytes transferred, which is only
337 * smaller than `count' if there is an error.
339 * This function won't work with non-blocking fd's.
340 * Any of the possibilities with non-bloking fd's is bad:
341 * - return a short write (then name is wrong)
342 * - busy wait adding (errno == EAGAIN) to the loop
344 ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
346 ssize_t ret = 0;
347 ssize_t total = 0;
349 while (count) {
350 ret = send(fd, buf, count, flags);
351 if (ret < 0) {
352 if (errno == EINTR) {
353 continue;
355 break;
358 count -= ret;
359 buf += ret;
360 total += ret;
363 return total;
367 * A variant of recv(2) which handles partial write.
369 * Return the number of bytes transferred, which is only
370 * smaller than `count' if there is an error.
372 * This function won't work with non-blocking fd's.
373 * Any of the possibilities with non-bloking fd's is bad:
374 * - return a short write (then name is wrong)
375 * - busy wait adding (errno == EAGAIN) to the loop
377 ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
379 ssize_t ret = 0;
380 ssize_t total = 0;
382 while (count) {
383 ret = qemu_recv(fd, buf, count, flags);
384 if (ret <= 0) {
385 if (ret < 0 && errno == EINTR) {
386 continue;
388 break;
391 count -= ret;
392 buf += ret;
393 total += ret;
396 return total;
399 void qemu_set_version(const char *version)
401 qemu_version = version;
404 const char *qemu_get_version(void)
406 return qemu_version;
409 void fips_set_state(bool requested)
411 #ifdef __linux__
412 if (requested) {
413 FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
414 if (fds != NULL) {
415 fips_enabled = (fgetc(fds) == '1');
416 fclose(fds);
419 #else
420 fips_enabled = false;
421 #endif /* __linux__ */
423 #ifdef _FIPS_DEBUG
424 fprintf(stderr, "FIPS mode %s (requested %s)\n",
425 (fips_enabled ? "enabled" : "disabled"),
426 (requested ? "enabled" : "disabled"));
427 #endif
430 bool fips_get_state(void)
432 return fips_enabled;