1258945Sroberto/*
2280849Scy * Copyright (C) 2004, 2007, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3258945Sroberto * Copyright (C) 2000, 2001  Internet Software Consortium.
4258945Sroberto *
5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any
6258945Sroberto * purpose with or without fee is hereby granted, provided that the above
7258945Sroberto * copyright notice and this permission notice appear in all copies.
8258945Sroberto *
9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11258945Sroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15258945Sroberto * PERFORMANCE OF THIS SOFTWARE.
16258945Sroberto */
17258945Sroberto
18280849Scy/* $Id$ */
19258945Sroberto
20258945Sroberto#include <config.h>
21258945Sroberto
22258945Sroberto#include <errno.h>
23258945Sroberto#include <unistd.h>
24258945Sroberto
25258945Sroberto#include <isc/stdio.h>
26280849Scy#include <isc/stat.h>
27258945Sroberto
28258945Sroberto#include "errno2result.h"
29258945Sroberto
30258945Srobertoisc_result_t
31258945Srobertoisc_stdio_open(const char *filename, const char *mode, FILE **fp) {
32258945Sroberto	FILE *f;
33258945Sroberto
34258945Sroberto	f = fopen(filename, mode);
35258945Sroberto	if (f == NULL)
36258945Sroberto		return (isc__errno2result(errno));
37258945Sroberto	*fp = f;
38258945Sroberto	return (ISC_R_SUCCESS);
39258945Sroberto}
40258945Sroberto
41258945Srobertoisc_result_t
42258945Srobertoisc_stdio_close(FILE *f) {
43258945Sroberto	int r;
44258945Sroberto
45258945Sroberto	r = fclose(f);
46258945Sroberto	if (r == 0)
47258945Sroberto		return (ISC_R_SUCCESS);
48258945Sroberto	else
49258945Sroberto		return (isc__errno2result(errno));
50258945Sroberto}
51258945Sroberto
52258945Srobertoisc_result_t
53258945Srobertoisc_stdio_seek(FILE *f, long offset, int whence) {
54258945Sroberto	int r;
55258945Sroberto
56258945Sroberto	r = fseek(f, offset, whence);
57258945Sroberto	if (r == 0)
58258945Sroberto		return (ISC_R_SUCCESS);
59258945Sroberto	else
60258945Sroberto		return (isc__errno2result(errno));
61258945Sroberto}
62258945Sroberto
63258945Srobertoisc_result_t
64258945Srobertoisc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
65258945Sroberto	isc_result_t result = ISC_R_SUCCESS;
66258945Sroberto	size_t r;
67258945Sroberto
68258945Sroberto	clearerr(f);
69258945Sroberto	r = fread(ptr, size, nmemb, f);
70258945Sroberto	if (r != nmemb) {
71258945Sroberto		if (feof(f))
72258945Sroberto			result = ISC_R_EOF;
73258945Sroberto		else
74258945Sroberto			result = isc__errno2result(errno);
75258945Sroberto	}
76258945Sroberto	if (nret != NULL)
77258945Sroberto		*nret = r;
78258945Sroberto	return (result);
79258945Sroberto}
80258945Sroberto
81258945Srobertoisc_result_t
82258945Srobertoisc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
83258945Sroberto	       size_t *nret)
84258945Sroberto{
85258945Sroberto	isc_result_t result = ISC_R_SUCCESS;
86258945Sroberto	size_t r;
87258945Sroberto
88258945Sroberto	clearerr(f);
89258945Sroberto	r = fwrite(ptr, size, nmemb, f);
90258945Sroberto	if (r != nmemb)
91258945Sroberto		result = isc__errno2result(errno);
92258945Sroberto	if (nret != NULL)
93258945Sroberto		*nret = r;
94258945Sroberto	return (result);
95258945Sroberto}
96258945Sroberto
97258945Srobertoisc_result_t
98258945Srobertoisc_stdio_flush(FILE *f) {
99258945Sroberto	int r;
100258945Sroberto
101258945Sroberto	r = fflush(f);
102258945Sroberto	if (r == 0)
103258945Sroberto		return (ISC_R_SUCCESS);
104258945Sroberto	else
105258945Sroberto		return (isc__errno2result(errno));
106258945Sroberto}
107258945Sroberto
108280849Scy/*
109280849Scy * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP.
110280849Scy */
111280849Scy#if defined(EOPNOTSUPP) && !defined(ENOTSUP)
112280849Scy#define ENOTSUP EOPNOTSUPP
113280849Scy#endif
114280849Scy
115258945Srobertoisc_result_t
116258945Srobertoisc_stdio_sync(FILE *f) {
117258945Sroberto	int r;
118258945Sroberto
119258945Sroberto	r = fsync(fileno(f));
120280849Scy	/*
121280849Scy	 * fsync is not supported on sockets and pipes which
122280849Scy	 * result in EINVAL / ENOTSUP.
123280849Scy	 */
124280849Scy	if (r == 0 || errno == EINVAL || errno == ENOTSUP)
125258945Sroberto		return (ISC_R_SUCCESS);
126258945Sroberto	else
127258945Sroberto		return (isc__errno2result(errno));
128258945Sroberto}
129258945Sroberto
130