1135446Strhodes/*
2262706Serwin * Copyright (C) 2004, 2007, 2011-2013  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 2000, 2001  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id$ */
19135446Strhodes
20135446Strhodes#include <config.h>
21135446Strhodes
22135446Strhodes#include <errno.h>
23135446Strhodes#include <unistd.h>
24135446Strhodes
25135446Strhodes#include <isc/stdio.h>
26225361Sdougb#include <isc/stat.h>
27262706Serwin#include <isc/util.h>
28135446Strhodes
29135446Strhodes#include "errno2result.h"
30135446Strhodes
31135446Strhodesisc_result_t
32135446Strhodesisc_stdio_open(const char *filename, const char *mode, FILE **fp) {
33135446Strhodes	FILE *f;
34135446Strhodes
35135446Strhodes	f = fopen(filename, mode);
36135446Strhodes	if (f == NULL)
37135446Strhodes		return (isc__errno2result(errno));
38135446Strhodes	*fp = f;
39135446Strhodes	return (ISC_R_SUCCESS);
40135446Strhodes}
41135446Strhodes
42135446Strhodesisc_result_t
43135446Strhodesisc_stdio_close(FILE *f) {
44135446Strhodes	int r;
45135446Strhodes
46135446Strhodes	r = fclose(f);
47135446Strhodes	if (r == 0)
48135446Strhodes		return (ISC_R_SUCCESS);
49135446Strhodes	else
50135446Strhodes		return (isc__errno2result(errno));
51135446Strhodes}
52135446Strhodes
53135446Strhodesisc_result_t
54262706Serwinisc_stdio_seek(FILE *f, off_t offset, int whence) {
55135446Strhodes	int r;
56135446Strhodes
57262706Serwin	r = fseeko(f, offset, whence);
58135446Strhodes	if (r == 0)
59135446Strhodes		return (ISC_R_SUCCESS);
60135446Strhodes	else
61135446Strhodes		return (isc__errno2result(errno));
62135446Strhodes}
63135446Strhodes
64135446Strhodesisc_result_t
65262706Serwinisc_stdio_tell(FILE *f, off_t *offsetp) {
66262706Serwin	off_t r;
67262706Serwin
68262706Serwin	REQUIRE(offsetp != NULL);
69262706Serwin
70262706Serwin	r = ftello(f);
71262706Serwin	if (r >= 0) {
72262706Serwin		*offsetp = r;
73262706Serwin		return (ISC_R_SUCCESS);
74262706Serwin	} else
75262706Serwin		return (isc__errno2result(errno));
76262706Serwin}
77262706Serwin
78262706Serwinisc_result_t
79135446Strhodesisc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
80135446Strhodes	isc_result_t result = ISC_R_SUCCESS;
81135446Strhodes	size_t r;
82135446Strhodes
83135446Strhodes	clearerr(f);
84135446Strhodes	r = fread(ptr, size, nmemb, f);
85135446Strhodes	if (r != nmemb) {
86135446Strhodes		if (feof(f))
87135446Strhodes			result = ISC_R_EOF;
88135446Strhodes		else
89135446Strhodes			result = isc__errno2result(errno);
90135446Strhodes	}
91135446Strhodes	if (nret != NULL)
92135446Strhodes		*nret = r;
93135446Strhodes	return (result);
94135446Strhodes}
95135446Strhodes
96135446Strhodesisc_result_t
97135446Strhodesisc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
98135446Strhodes	       size_t *nret)
99135446Strhodes{
100135446Strhodes	isc_result_t result = ISC_R_SUCCESS;
101135446Strhodes	size_t r;
102135446Strhodes
103135446Strhodes	clearerr(f);
104135446Strhodes	r = fwrite(ptr, size, nmemb, f);
105135446Strhodes	if (r != nmemb)
106135446Strhodes		result = isc__errno2result(errno);
107135446Strhodes	if (nret != NULL)
108135446Strhodes		*nret = r;
109135446Strhodes	return (result);
110135446Strhodes}
111135446Strhodes
112135446Strhodesisc_result_t
113135446Strhodesisc_stdio_flush(FILE *f) {
114135446Strhodes	int r;
115135446Strhodes
116135446Strhodes	r = fflush(f);
117135446Strhodes	if (r == 0)
118135446Strhodes		return (ISC_R_SUCCESS);
119135446Strhodes	else
120135446Strhodes		return (isc__errno2result(errno));
121135446Strhodes}
122135446Strhodes
123234010Sdougb/*
124234010Sdougb * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP.
125234010Sdougb */
126234010Sdougb#if defined(EOPNOTSUPP) && !defined(ENOTSUP)
127234010Sdougb#define ENOTSUP EOPNOTSUPP
128234010Sdougb#endif
129234010Sdougb
130135446Strhodesisc_result_t
131135446Strhodesisc_stdio_sync(FILE *f) {
132135446Strhodes	int r;
133135446Strhodes
134135446Strhodes	r = fsync(fileno(f));
135234010Sdougb	/*
136234010Sdougb	 * fsync is not supported on sockets and pipes which
137234010Sdougb	 * result in EINVAL / ENOTSUP.
138234010Sdougb	 */
139234010Sdougb	if (r == 0 || errno == EINVAL || errno == ENOTSUP)
140135446Strhodes		return (ISC_R_SUCCESS);
141135446Strhodes	else
142135446Strhodes		return (isc__errno2result(errno));
143135446Strhodes}
144135446Strhodes
145