/src/libexpat/expat/lib/random_dev_urandom.c
Line | Count | Source |
1 | | /* |
2 | | __ __ _ |
3 | | ___\ \/ /_ __ __ _| |_ |
4 | | / _ \\ /| '_ \ / _` | __| |
5 | | | __// \| |_) | (_| | |_ |
6 | | \___/_/\_\ .__/ \__,_|\__| |
7 | | |_| XML parser |
8 | | |
9 | | Copyright (c) 2017-2026 Sebastian Pipping <sebastian@pipping.org> |
10 | | Copyright (c) 2026 Matthew Fernandez <matthew.fernandez@gmail.com> |
11 | | Licensed under the MIT license: |
12 | | |
13 | | Permission is hereby granted, free of charge, to any person obtaining |
14 | | a copy of this software and associated documentation files (the |
15 | | "Software"), to deal in the Software without restriction, including |
16 | | without limitation the rights to use, copy, modify, merge, publish, |
17 | | distribute, sublicense, and/or sell copies of the Software, and to permit |
18 | | persons to whom the Software is furnished to do so, subject to the |
19 | | following conditions: |
20 | | |
21 | | The above copyright notice and this permission notice shall be included |
22 | | in all copies or substantial portions of the Software. |
23 | | |
24 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
25 | | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
26 | | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
27 | | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
28 | | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
29 | | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
30 | | USE OR OTHER DEALINGS IN THE SOFTWARE. |
31 | | */ |
32 | | |
33 | | #include "random_dev_urandom.h" |
34 | | |
35 | | #if ! defined(_POSIX_C_SOURCE) \ |
36 | | || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 200809L)) |
37 | | # define _POSIX_C_SOURCE 200809L // for O_CLOEXEC |
38 | | #endif |
39 | | |
40 | | #include <errno.h> |
41 | | #include <fcntl.h> // open |
42 | | #include <unistd.h> // close |
43 | | |
44 | | /* Extract entropy from /dev/urandom */ |
45 | | bool |
46 | 0 | writeRandomBytes_dev_urandom(void *target, size_t count) { |
47 | 0 | int success = false; /* full count bytes written? */ |
48 | 0 | size_t bytesWrittenTotal = 0; |
49 | |
|
50 | 0 | const int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); |
51 | 0 | if (fd < 0) { |
52 | 0 | return 0; |
53 | 0 | } |
54 | | |
55 | 0 | do { |
56 | 0 | void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); |
57 | 0 | const size_t bytesToWrite = count - bytesWrittenTotal; |
58 | |
|
59 | 0 | errno = 0; |
60 | |
|
61 | 0 | const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); |
62 | |
|
63 | 0 | if (bytesWrittenMore > 0) { |
64 | 0 | bytesWrittenTotal += bytesWrittenMore; |
65 | 0 | if (bytesWrittenTotal >= count) |
66 | 0 | success = true; |
67 | 0 | } |
68 | 0 | } while (! success && (errno == EINTR)); |
69 | |
|
70 | 0 | close(fd); |
71 | 0 | return success; |
72 | 0 | } |