Statistics
| Branch: | Revision:

root / util / osdep.c @ cb77d192

History | View | Annotate | Download (10.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 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 1de7afc9 Paolo Bonzini
#include "qemu/sockets.h"
51 83c9089e Paolo Bonzini
#include "monitor/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 4bd1afbd Lei Li
    return qemu_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 bf1c852a MORITA Kazutaka
int socket_set_nodelay(int fd)
67 bf1c852a MORITA Kazutaka
{
68 bf1c852a MORITA Kazutaka
    int v = 1;
69 4bd1afbd Lei Li
    return qemu_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
70 bf1c852a MORITA Kazutaka
}
71 bf1c852a MORITA Kazutaka
72 e78815a5 Andreas Färber
int qemu_madvise(void *addr, size_t len, int advice)
73 e78815a5 Andreas Färber
{
74 e78815a5 Andreas Färber
    if (advice == QEMU_MADV_INVALID) {
75 e78815a5 Andreas Färber
        errno = EINVAL;
76 e78815a5 Andreas Färber
        return -1;
77 e78815a5 Andreas Färber
    }
78 e78815a5 Andreas Färber
#if defined(CONFIG_MADVISE)
79 e78815a5 Andreas Färber
    return madvise(addr, len, advice);
80 e78815a5 Andreas Färber
#elif defined(CONFIG_POSIX_MADVISE)
81 e78815a5 Andreas Färber
    return posix_madvise(addr, len, advice);
82 e78815a5 Andreas Färber
#else
83 e78815a5 Andreas Färber
    errno = EINVAL;
84 e78815a5 Andreas Färber
    return -1;
85 e78815a5 Andreas Färber
#endif
86 e78815a5 Andreas Färber
}
87 e78815a5 Andreas Färber
88 adb696f3 Corey Bryant
#ifndef _WIN32
89 adb696f3 Corey Bryant
/*
90 adb696f3 Corey Bryant
 * Dups an fd and sets the flags
91 adb696f3 Corey Bryant
 */
92 adb696f3 Corey Bryant
static int qemu_dup_flags(int fd, int flags)
93 adb696f3 Corey Bryant
{
94 adb696f3 Corey Bryant
    int ret;
95 adb696f3 Corey Bryant
    int serrno;
96 adb696f3 Corey Bryant
    int dup_flags;
97 adb696f3 Corey Bryant
98 adb696f3 Corey Bryant
#ifdef F_DUPFD_CLOEXEC
99 adb696f3 Corey Bryant
    ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
100 adb696f3 Corey Bryant
#else
101 adb696f3 Corey Bryant
    ret = dup(fd);
102 adb696f3 Corey Bryant
    if (ret != -1) {
103 adb696f3 Corey Bryant
        qemu_set_cloexec(ret);
104 adb696f3 Corey Bryant
    }
105 adb696f3 Corey Bryant
#endif
106 adb696f3 Corey Bryant
    if (ret == -1) {
107 adb696f3 Corey Bryant
        goto fail;
108 adb696f3 Corey Bryant
    }
109 adb696f3 Corey Bryant
110 adb696f3 Corey Bryant
    dup_flags = fcntl(ret, F_GETFL);
111 adb696f3 Corey Bryant
    if (dup_flags == -1) {
112 adb696f3 Corey Bryant
        goto fail;
113 adb696f3 Corey Bryant
    }
114 adb696f3 Corey Bryant
115 adb696f3 Corey Bryant
    if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
116 adb696f3 Corey Bryant
        errno = EINVAL;
117 adb696f3 Corey Bryant
        goto fail;
118 adb696f3 Corey Bryant
    }
119 adb696f3 Corey Bryant
120 adb696f3 Corey Bryant
    /* Set/unset flags that we can with fcntl */
121 3b6eda2f Corey Bryant
    if (fcntl(ret, F_SETFL, flags) == -1) {
122 adb696f3 Corey Bryant
        goto fail;
123 adb696f3 Corey Bryant
    }
124 adb696f3 Corey Bryant
125 adb696f3 Corey Bryant
    /* Truncate the file in the cases that open() would truncate it */
126 adb696f3 Corey Bryant
    if (flags & O_TRUNC ||
127 adb696f3 Corey Bryant
            ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
128 adb696f3 Corey Bryant
        if (ftruncate(ret, 0) == -1) {
129 adb696f3 Corey Bryant
            goto fail;
130 adb696f3 Corey Bryant
        }
131 adb696f3 Corey Bryant
    }
132 adb696f3 Corey Bryant
133 adb696f3 Corey Bryant
    return ret;
134 adb696f3 Corey Bryant
135 adb696f3 Corey Bryant
fail:
136 adb696f3 Corey Bryant
    serrno = errno;
137 adb696f3 Corey Bryant
    if (ret != -1) {
138 adb696f3 Corey Bryant
        close(ret);
139 adb696f3 Corey Bryant
    }
140 adb696f3 Corey Bryant
    errno = serrno;
141 adb696f3 Corey Bryant
    return -1;
142 adb696f3 Corey Bryant
}
143 0100fbbe Paolo Bonzini
144 0100fbbe Paolo Bonzini
static int qemu_parse_fdset(const char *param)
145 0100fbbe Paolo Bonzini
{
146 0100fbbe Paolo Bonzini
    return qemu_parse_fd(param);
147 0100fbbe Paolo Bonzini
}
148 adb696f3 Corey Bryant
#endif
149 03ff3ca3 aliguori
150 40ff6d7e Kevin Wolf
/*
151 40ff6d7e Kevin Wolf
 * Opens a file with FD_CLOEXEC set
152 40ff6d7e Kevin Wolf
 */
153 40ff6d7e Kevin Wolf
int qemu_open(const char *name, int flags, ...)
154 40ff6d7e Kevin Wolf
{
155 40ff6d7e Kevin Wolf
    int ret;
156 40ff6d7e Kevin Wolf
    int mode = 0;
157 40ff6d7e Kevin Wolf
158 adb696f3 Corey Bryant
#ifndef _WIN32
159 adb696f3 Corey Bryant
    const char *fdset_id_str;
160 adb696f3 Corey Bryant
161 adb696f3 Corey Bryant
    /* Attempt dup of fd from fd set */
162 adb696f3 Corey Bryant
    if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
163 adb696f3 Corey Bryant
        int64_t fdset_id;
164 adb696f3 Corey Bryant
        int fd, dupfd;
165 adb696f3 Corey Bryant
166 adb696f3 Corey Bryant
        fdset_id = qemu_parse_fdset(fdset_id_str);
167 adb696f3 Corey Bryant
        if (fdset_id == -1) {
168 adb696f3 Corey Bryant
            errno = EINVAL;
169 adb696f3 Corey Bryant
            return -1;
170 adb696f3 Corey Bryant
        }
171 adb696f3 Corey Bryant
172 adb696f3 Corey Bryant
        fd = monitor_fdset_get_fd(fdset_id, flags);
173 adb696f3 Corey Bryant
        if (fd == -1) {
174 adb696f3 Corey Bryant
            return -1;
175 adb696f3 Corey Bryant
        }
176 adb696f3 Corey Bryant
177 adb696f3 Corey Bryant
        dupfd = qemu_dup_flags(fd, flags);
178 adb696f3 Corey Bryant
        if (dupfd == -1) {
179 adb696f3 Corey Bryant
            return -1;
180 adb696f3 Corey Bryant
        }
181 adb696f3 Corey Bryant
182 adb696f3 Corey Bryant
        ret = monitor_fdset_dup_fd_add(fdset_id, dupfd);
183 adb696f3 Corey Bryant
        if (ret == -1) {
184 adb696f3 Corey Bryant
            close(dupfd);
185 adb696f3 Corey Bryant
            errno = EINVAL;
186 adb696f3 Corey Bryant
            return -1;
187 adb696f3 Corey Bryant
        }
188 adb696f3 Corey Bryant
189 adb696f3 Corey Bryant
        return dupfd;
190 adb696f3 Corey Bryant
    }
191 adb696f3 Corey Bryant
#endif
192 adb696f3 Corey Bryant
193 40ff6d7e Kevin Wolf
    if (flags & O_CREAT) {
194 40ff6d7e Kevin Wolf
        va_list ap;
195 40ff6d7e Kevin Wolf
196 40ff6d7e Kevin Wolf
        va_start(ap, flags);
197 40ff6d7e Kevin Wolf
        mode = va_arg(ap, int);
198 40ff6d7e Kevin Wolf
        va_end(ap);
199 40ff6d7e Kevin Wolf
    }
200 40ff6d7e Kevin Wolf
201 40ff6d7e Kevin Wolf
#ifdef O_CLOEXEC
202 40ff6d7e Kevin Wolf
    ret = open(name, flags | O_CLOEXEC, mode);
203 40ff6d7e Kevin Wolf
#else
204 40ff6d7e Kevin Wolf
    ret = open(name, flags, mode);
205 40ff6d7e Kevin Wolf
    if (ret >= 0) {
206 40ff6d7e Kevin Wolf
        qemu_set_cloexec(ret);
207 40ff6d7e Kevin Wolf
    }
208 03ff3ca3 aliguori
#endif
209 40ff6d7e Kevin Wolf
210 40ff6d7e Kevin Wolf
    return ret;
211 40ff6d7e Kevin Wolf
}
212 40ff6d7e Kevin Wolf
213 2e1e79da Corey Bryant
int qemu_close(int fd)
214 2e1e79da Corey Bryant
{
215 adb696f3 Corey Bryant
    int64_t fdset_id;
216 adb696f3 Corey Bryant
217 adb696f3 Corey Bryant
    /* Close fd that was dup'd from an fdset */
218 adb696f3 Corey Bryant
    fdset_id = monitor_fdset_dup_fd_find(fd);
219 adb696f3 Corey Bryant
    if (fdset_id != -1) {
220 adb696f3 Corey Bryant
        int ret;
221 adb696f3 Corey Bryant
222 adb696f3 Corey Bryant
        ret = close(fd);
223 adb696f3 Corey Bryant
        if (ret == 0) {
224 adb696f3 Corey Bryant
            monitor_fdset_dup_fd_remove(fd);
225 adb696f3 Corey Bryant
        }
226 adb696f3 Corey Bryant
227 adb696f3 Corey Bryant
        return ret;
228 adb696f3 Corey Bryant
    }
229 adb696f3 Corey Bryant
230 2e1e79da Corey Bryant
    return close(fd);
231 2e1e79da Corey Bryant
}
232 2e1e79da Corey Bryant
233 7b5f699d Kirill A. Shutemov
/*
234 7b5f699d Kirill A. Shutemov
 * A variant of write(2) which handles partial write.
235 7b5f699d Kirill A. Shutemov
 *
236 7b5f699d Kirill A. Shutemov
 * Return the number of bytes transferred.
237 7b5f699d Kirill A. Shutemov
 * Set errno if fewer than `count' bytes are written.
238 1298cb68 Juan Quintela
 *
239 1298cb68 Juan Quintela
 * This function don't work with non-blocking fd's.
240 1298cb68 Juan Quintela
 * Any of the possibilities with non-bloking fd's is bad:
241 1298cb68 Juan Quintela
 *   - return a short write (then name is wrong)
242 1298cb68 Juan Quintela
 *   - busy wait adding (errno == EAGAIN) to the loop
243 7b5f699d Kirill A. Shutemov
 */
244 7b5f699d Kirill A. Shutemov
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
245 7b5f699d Kirill A. Shutemov
{
246 7b5f699d Kirill A. Shutemov
    ssize_t ret = 0;
247 7b5f699d Kirill A. Shutemov
    ssize_t total = 0;
248 7b5f699d Kirill A. Shutemov
249 7b5f699d Kirill A. Shutemov
    while (count) {
250 7b5f699d Kirill A. Shutemov
        ret = write(fd, buf, count);
251 7b5f699d Kirill A. Shutemov
        if (ret < 0) {
252 7b5f699d Kirill A. Shutemov
            if (errno == EINTR)
253 7b5f699d Kirill A. Shutemov
                continue;
254 7b5f699d Kirill A. Shutemov
            break;
255 7b5f699d Kirill A. Shutemov
        }
256 7b5f699d Kirill A. Shutemov
257 7b5f699d Kirill A. Shutemov
        count -= ret;
258 7b5f699d Kirill A. Shutemov
        buf += ret;
259 7b5f699d Kirill A. Shutemov
        total += ret;
260 7b5f699d Kirill A. Shutemov
    }
261 7b5f699d Kirill A. Shutemov
262 7b5f699d Kirill A. Shutemov
    return total;
263 7b5f699d Kirill A. Shutemov
}
264 7b5f699d Kirill A. Shutemov
265 40ff6d7e Kevin Wolf
/*
266 40ff6d7e Kevin Wolf
 * Opens a socket with FD_CLOEXEC set
267 40ff6d7e Kevin Wolf
 */
268 40ff6d7e Kevin Wolf
int qemu_socket(int domain, int type, int protocol)
269 40ff6d7e Kevin Wolf
{
270 40ff6d7e Kevin Wolf
    int ret;
271 40ff6d7e Kevin Wolf
272 40ff6d7e Kevin Wolf
#ifdef SOCK_CLOEXEC
273 40ff6d7e Kevin Wolf
    ret = socket(domain, type | SOCK_CLOEXEC, protocol);
274 3a03bfa5 Andre Przywara
    if (ret != -1 || errno != EINVAL) {
275 3a03bfa5 Andre Przywara
        return ret;
276 3a03bfa5 Andre Przywara
    }
277 3a03bfa5 Andre Przywara
#endif
278 40ff6d7e Kevin Wolf
    ret = socket(domain, type, protocol);
279 40ff6d7e Kevin Wolf
    if (ret >= 0) {
280 40ff6d7e Kevin Wolf
        qemu_set_cloexec(ret);
281 40ff6d7e Kevin Wolf
    }
282 40ff6d7e Kevin Wolf
283 40ff6d7e Kevin Wolf
    return ret;
284 40ff6d7e Kevin Wolf
}
285 40ff6d7e Kevin Wolf
286 40ff6d7e Kevin Wolf
/*
287 40ff6d7e Kevin Wolf
 * Accept a connection and set FD_CLOEXEC
288 40ff6d7e Kevin Wolf
 */
289 40ff6d7e Kevin Wolf
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
290 40ff6d7e Kevin Wolf
{
291 40ff6d7e Kevin Wolf
    int ret;
292 40ff6d7e Kevin Wolf
293 40ff6d7e Kevin Wolf
#ifdef CONFIG_ACCEPT4
294 40ff6d7e Kevin Wolf
    ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
295 347ed55c Kevin Wolf
    if (ret != -1 || errno != ENOSYS) {
296 3a03bfa5 Andre Przywara
        return ret;
297 3a03bfa5 Andre Przywara
    }
298 3a03bfa5 Andre Przywara
#endif
299 40ff6d7e Kevin Wolf
    ret = accept(s, addr, addrlen);
300 40ff6d7e Kevin Wolf
    if (ret >= 0) {
301 40ff6d7e Kevin Wolf
        qemu_set_cloexec(ret);
302 40ff6d7e Kevin Wolf
    }
303 40ff6d7e Kevin Wolf
304 40ff6d7e Kevin Wolf
    return ret;
305 40ff6d7e Kevin Wolf
}
306 993295fe Paolo Bonzini
307 993295fe Paolo Bonzini
/*
308 993295fe Paolo Bonzini
 * A variant of send(2) which handles partial write.
309 993295fe Paolo Bonzini
 *
310 993295fe Paolo Bonzini
 * Return the number of bytes transferred, which is only
311 993295fe Paolo Bonzini
 * smaller than `count' if there is an error.
312 993295fe Paolo Bonzini
 *
313 993295fe Paolo Bonzini
 * This function won't work with non-blocking fd's.
314 993295fe Paolo Bonzini
 * Any of the possibilities with non-bloking fd's is bad:
315 993295fe Paolo Bonzini
 *   - return a short write (then name is wrong)
316 993295fe Paolo Bonzini
 *   - busy wait adding (errno == EAGAIN) to the loop
317 993295fe Paolo Bonzini
 */
318 993295fe Paolo Bonzini
ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
319 993295fe Paolo Bonzini
{
320 993295fe Paolo Bonzini
    ssize_t ret = 0;
321 993295fe Paolo Bonzini
    ssize_t total = 0;
322 993295fe Paolo Bonzini
323 993295fe Paolo Bonzini
    while (count) {
324 993295fe Paolo Bonzini
        ret = send(fd, buf, count, flags);
325 993295fe Paolo Bonzini
        if (ret < 0) {
326 993295fe Paolo Bonzini
            if (errno == EINTR) {
327 993295fe Paolo Bonzini
                continue;
328 993295fe Paolo Bonzini
            }
329 993295fe Paolo Bonzini
            break;
330 993295fe Paolo Bonzini
        }
331 993295fe Paolo Bonzini
332 993295fe Paolo Bonzini
        count -= ret;
333 993295fe Paolo Bonzini
        buf += ret;
334 993295fe Paolo Bonzini
        total += ret;
335 993295fe Paolo Bonzini
    }
336 993295fe Paolo Bonzini
337 993295fe Paolo Bonzini
    return total;
338 993295fe Paolo Bonzini
}
339 993295fe Paolo Bonzini
340 993295fe Paolo Bonzini
/*
341 993295fe Paolo Bonzini
 * A variant of recv(2) which handles partial write.
342 993295fe Paolo Bonzini
 *
343 993295fe Paolo Bonzini
 * Return the number of bytes transferred, which is only
344 993295fe Paolo Bonzini
 * smaller than `count' if there is an error.
345 993295fe Paolo Bonzini
 *
346 993295fe Paolo Bonzini
 * This function won't work with non-blocking fd's.
347 993295fe Paolo Bonzini
 * Any of the possibilities with non-bloking fd's is bad:
348 993295fe Paolo Bonzini
 *   - return a short write (then name is wrong)
349 993295fe Paolo Bonzini
 *   - busy wait adding (errno == EAGAIN) to the loop
350 993295fe Paolo Bonzini
 */
351 993295fe Paolo Bonzini
ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
352 993295fe Paolo Bonzini
{
353 993295fe Paolo Bonzini
    ssize_t ret = 0;
354 993295fe Paolo Bonzini
    ssize_t total = 0;
355 993295fe Paolo Bonzini
356 993295fe Paolo Bonzini
    while (count) {
357 993295fe Paolo Bonzini
        ret = qemu_recv(fd, buf, count, flags);
358 993295fe Paolo Bonzini
        if (ret <= 0) {
359 993295fe Paolo Bonzini
            if (ret < 0 && errno == EINTR) {
360 993295fe Paolo Bonzini
                continue;
361 993295fe Paolo Bonzini
            }
362 993295fe Paolo Bonzini
            break;
363 993295fe Paolo Bonzini
        }
364 993295fe Paolo Bonzini
365 993295fe Paolo Bonzini
        count -= ret;
366 993295fe Paolo Bonzini
        buf += ret;
367 993295fe Paolo Bonzini
        total += ret;
368 993295fe Paolo Bonzini
    }
369 993295fe Paolo Bonzini
370 993295fe Paolo Bonzini
    return total;
371 993295fe Paolo Bonzini
}
372 993295fe Paolo Bonzini
373 93bfef4c Crístian Viana
void qemu_set_version(const char *version)
374 93bfef4c Crístian Viana
{
375 93bfef4c Crístian Viana
    qemu_version = version;
376 93bfef4c Crístian Viana
}
377 93bfef4c Crístian Viana
378 93bfef4c Crístian Viana
const char *qemu_get_version(void)
379 93bfef4c Crístian Viana
{
380 93bfef4c Crístian Viana
    return qemu_version;
381 93bfef4c Crístian Viana
}
382 0f66998f Paul Moore
383 0f66998f Paul Moore
void fips_set_state(bool requested)
384 0f66998f Paul Moore
{
385 0f66998f Paul Moore
#ifdef __linux__
386 0f66998f Paul Moore
    if (requested) {
387 0f66998f Paul Moore
        FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
388 0f66998f Paul Moore
        if (fds != NULL) {
389 0f66998f Paul Moore
            fips_enabled = (fgetc(fds) == '1');
390 0f66998f Paul Moore
            fclose(fds);
391 0f66998f Paul Moore
        }
392 0f66998f Paul Moore
    }
393 0f66998f Paul Moore
#else
394 0f66998f Paul Moore
    fips_enabled = false;
395 0f66998f Paul Moore
#endif /* __linux__ */
396 0f66998f Paul Moore
397 0f66998f Paul Moore
#ifdef _FIPS_DEBUG
398 0f66998f Paul Moore
    fprintf(stderr, "FIPS mode %s (requested %s)\n",
399 0f66998f Paul Moore
            (fips_enabled ? "enabled" : "disabled"),
400 0f66998f Paul Moore
            (requested ? "enabled" : "disabled"));
401 0f66998f Paul Moore
#endif
402 0f66998f Paul Moore
}
403 0f66998f Paul Moore
404 0f66998f Paul Moore
bool fips_get_state(void)
405 0f66998f Paul Moore
{
406 0f66998f Paul Moore
    return fips_enabled;
407 0f66998f Paul Moore
}
408 0100fbbe Paolo Bonzini
409 d3bf825e Marc-André Lureau
#ifdef _WIN32
410 d3bf825e Marc-André Lureau
static void socket_cleanup(void)
411 d3bf825e Marc-André Lureau
{
412 d3bf825e Marc-André Lureau
    WSACleanup();
413 d3bf825e Marc-André Lureau
}
414 d3bf825e Marc-André Lureau
#endif
415 d3bf825e Marc-André Lureau
416 d3bf825e Marc-André Lureau
int socket_init(void)
417 d3bf825e Marc-André Lureau
{
418 d3bf825e Marc-André Lureau
#ifdef _WIN32
419 d3bf825e Marc-André Lureau
    WSADATA Data;
420 d3bf825e Marc-André Lureau
    int ret, err;
421 d3bf825e Marc-André Lureau
422 d3bf825e Marc-André Lureau
    ret = WSAStartup(MAKEWORD(2, 2), &Data);
423 d3bf825e Marc-André Lureau
    if (ret != 0) {
424 d3bf825e Marc-André Lureau
        err = WSAGetLastError();
425 d3bf825e Marc-André Lureau
        fprintf(stderr, "WSAStartup: %d\n", err);
426 d3bf825e Marc-André Lureau
        return -1;
427 d3bf825e Marc-André Lureau
    }
428 d3bf825e Marc-André Lureau
    atexit(socket_cleanup);
429 d3bf825e Marc-André Lureau
#endif
430 d3bf825e Marc-André Lureau
    return 0;
431 d3bf825e Marc-André Lureau
}
432 9adea5f7 Paolo Bonzini
433 9adea5f7 Paolo Bonzini
#ifndef CONFIG_IOVEC
434 9adea5f7 Paolo Bonzini
/* helper function for iov_send_recv() */
435 9adea5f7 Paolo Bonzini
static ssize_t
436 9adea5f7 Paolo Bonzini
readv_writev(int fd, const struct iovec *iov, int iov_cnt, bool do_write)
437 9adea5f7 Paolo Bonzini
{
438 9adea5f7 Paolo Bonzini
    unsigned i = 0;
439 9adea5f7 Paolo Bonzini
    ssize_t ret = 0;
440 9adea5f7 Paolo Bonzini
    while (i < iov_cnt) {
441 9adea5f7 Paolo Bonzini
        ssize_t r = do_write
442 9adea5f7 Paolo Bonzini
            ? write(fd, iov[i].iov_base, iov[i].iov_len)
443 9adea5f7 Paolo Bonzini
            : read(fd, iov[i].iov_base, iov[i].iov_len);
444 9adea5f7 Paolo Bonzini
        if (r > 0) {
445 9adea5f7 Paolo Bonzini
            ret += r;
446 9adea5f7 Paolo Bonzini
        } else if (!r) {
447 9adea5f7 Paolo Bonzini
            break;
448 9adea5f7 Paolo Bonzini
        } else if (errno == EINTR) {
449 9adea5f7 Paolo Bonzini
            continue;
450 9adea5f7 Paolo Bonzini
        } else {
451 9adea5f7 Paolo Bonzini
            /* else it is some "other" error,
452 9adea5f7 Paolo Bonzini
             * only return if there was no data processed. */
453 9adea5f7 Paolo Bonzini
            if (ret == 0) {
454 9adea5f7 Paolo Bonzini
                ret = -1;
455 9adea5f7 Paolo Bonzini
            }
456 9adea5f7 Paolo Bonzini
            break;
457 9adea5f7 Paolo Bonzini
        }
458 9adea5f7 Paolo Bonzini
        i++;
459 9adea5f7 Paolo Bonzini
    }
460 9adea5f7 Paolo Bonzini
    return ret;
461 9adea5f7 Paolo Bonzini
}
462 9adea5f7 Paolo Bonzini
463 9adea5f7 Paolo Bonzini
ssize_t
464 9adea5f7 Paolo Bonzini
readv(int fd, const struct iovec *iov, int iov_cnt)
465 9adea5f7 Paolo Bonzini
{
466 9adea5f7 Paolo Bonzini
    return readv_writev(fd, iov, iov_cnt, false);
467 9adea5f7 Paolo Bonzini
}
468 9adea5f7 Paolo Bonzini
469 9adea5f7 Paolo Bonzini
ssize_t
470 9adea5f7 Paolo Bonzini
writev(int fd, const struct iovec *iov, int iov_cnt)
471 9adea5f7 Paolo Bonzini
{
472 9adea5f7 Paolo Bonzini
    return readv_writev(fd, iov, iov_cnt, true);
473 9adea5f7 Paolo Bonzini
}
474 9adea5f7 Paolo Bonzini
#endif