/src/bind9/lib/isc/stdio.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) Internet Systems Consortium, Inc. ("ISC") |
3 | | * |
4 | | * SPDX-License-Identifier: MPL-2.0 |
5 | | * |
6 | | * This Source Code Form is subject to the terms of the Mozilla Public |
7 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 | | * file, you can obtain one at https://mozilla.org/MPL/2.0/. |
9 | | * |
10 | | * See the COPYRIGHT file distributed with this work for additional |
11 | | * information regarding copyright ownership. |
12 | | */ |
13 | | |
14 | | #include <errno.h> |
15 | | #include <sys/stat.h> |
16 | | #include <unistd.h> |
17 | | |
18 | | #include <isc/stdio.h> |
19 | | #include <isc/util.h> |
20 | | |
21 | | #include "errno2result.h" |
22 | | |
23 | | isc_result_t |
24 | 21 | isc_stdio_open(const char *filename, const char *mode, FILE **fp) { |
25 | 21 | FILE *f; |
26 | | |
27 | 21 | f = fopen(filename, mode); |
28 | 21 | if (f == NULL) { |
29 | 17 | return isc__errno2result(errno); |
30 | 17 | } |
31 | 4 | *fp = f; |
32 | 4 | return ISC_R_SUCCESS; |
33 | 21 | } |
34 | | |
35 | | isc_result_t |
36 | 0 | isc_stdio_close(FILE *f) { |
37 | 0 | int r; |
38 | |
|
39 | 0 | r = fclose(f); |
40 | 0 | if (r == 0) { |
41 | 0 | return ISC_R_SUCCESS; |
42 | 0 | } else { |
43 | 0 | return isc__errno2result(errno); |
44 | 0 | } |
45 | 0 | } |
46 | | |
47 | | isc_result_t |
48 | 0 | isc_stdio_seek(FILE *f, off_t offset, int whence) { |
49 | 0 | int r; |
50 | |
|
51 | 0 | r = fseeko(f, offset, whence); |
52 | 0 | if (r == 0) { |
53 | 0 | return ISC_R_SUCCESS; |
54 | 0 | } else { |
55 | 0 | return isc__errno2result(errno); |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | isc_result_t |
60 | 0 | isc_stdio_tell(FILE *f, off_t *offsetp) { |
61 | 0 | off_t r; |
62 | |
|
63 | 0 | REQUIRE(offsetp != NULL); |
64 | |
|
65 | 0 | r = ftello(f); |
66 | 0 | if (r >= 0) { |
67 | 0 | *offsetp = r; |
68 | 0 | return ISC_R_SUCCESS; |
69 | 0 | } else { |
70 | 0 | return isc__errno2result(errno); |
71 | 0 | } |
72 | 0 | } |
73 | | |
74 | | isc_result_t |
75 | 0 | isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { |
76 | 0 | isc_result_t result = ISC_R_SUCCESS; |
77 | 0 | size_t r; |
78 | |
|
79 | 0 | clearerr(f); |
80 | 0 | r = fread(ptr, size, nmemb, f); |
81 | 0 | if (r != nmemb) { |
82 | 0 | if (feof(f)) { |
83 | 0 | result = ISC_R_EOF; |
84 | 0 | } else { |
85 | 0 | result = isc__errno2result(errno); |
86 | 0 | } |
87 | 0 | } |
88 | 0 | SET_IF_NOT_NULL(nret, r); |
89 | 0 | return result; |
90 | 0 | } |
91 | | |
92 | | isc_result_t |
93 | | isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, |
94 | 0 | size_t *nret) { |
95 | 0 | isc_result_t result = ISC_R_SUCCESS; |
96 | 0 | size_t r; |
97 | |
|
98 | 0 | clearerr(f); |
99 | 0 | r = fwrite(ptr, size, nmemb, f); |
100 | 0 | if (r != nmemb) { |
101 | 0 | result = isc__errno2result(errno); |
102 | 0 | } |
103 | 0 | SET_IF_NOT_NULL(nret, r); |
104 | 0 | return result; |
105 | 0 | } |
106 | | |
107 | | isc_result_t |
108 | 0 | isc_stdio_flush(FILE *f) { |
109 | 0 | int r; |
110 | |
|
111 | 0 | r = fflush(f); |
112 | 0 | if (r == 0) { |
113 | 0 | return ISC_R_SUCCESS; |
114 | 0 | } else { |
115 | 0 | return isc__errno2result(errno); |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | | /* |
120 | | * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP. |
121 | | */ |
122 | | #if defined(EOPNOTSUPP) && !defined(ENOTSUP) |
123 | | #define ENOTSUP EOPNOTSUPP |
124 | | #endif /* if defined(EOPNOTSUPP) && !defined(ENOTSUP) */ |
125 | | |
126 | | isc_result_t |
127 | 0 | isc_stdio_sync(FILE *f) { |
128 | 0 | struct stat buf; |
129 | 0 | int r; |
130 | |
|
131 | 0 | if (fstat(fileno(f), &buf) != 0) { |
132 | 0 | return isc__errno2result(errno); |
133 | 0 | } |
134 | | |
135 | | /* |
136 | | * Only call fsync() on regular files. |
137 | | */ |
138 | 0 | if ((buf.st_mode & S_IFMT) != S_IFREG) { |
139 | 0 | return ISC_R_SUCCESS; |
140 | 0 | } |
141 | | |
142 | 0 | r = fsync(fileno(f)); |
143 | 0 | if (r == 0) { |
144 | 0 | return ISC_R_SUCCESS; |
145 | 0 | } else { |
146 | 0 | return isc__errno2result(errno); |
147 | 0 | } |
148 | 0 | } |