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