xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/unix/stdio.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
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