Statistics
| Branch: | Revision:

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
}