1/* 2 * Copyright (C) 2004, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20#include <config.h> 21 22#include <errno.h> 23#include <unistd.h> 24 25#include <isc/stdio.h> 26#include <isc/stat.h> 27#include <isc/util.h> 28 29#include "errno2result.h" 30 31isc_result_t 32isc_stdio_open(const char *filename, const char *mode, FILE **fp) { 33 FILE *f; 34 35 f = fopen(filename, mode); 36 if (f == NULL) 37 return (isc__errno2result(errno)); 38 *fp = f; 39 return (ISC_R_SUCCESS); 40} 41 42isc_result_t 43isc_stdio_close(FILE *f) { 44 int r; 45 46 r = fclose(f); 47 if (r == 0) 48 return (ISC_R_SUCCESS); 49 else 50 return (isc__errno2result(errno)); 51} 52 53isc_result_t 54isc_stdio_seek(FILE *f, off_t offset, int whence) { 55 int r; 56 57 r = fseeko(f, offset, whence); 58 if (r == 0) 59 return (ISC_R_SUCCESS); 60 else 61 return (isc__errno2result(errno)); 62} 63 64isc_result_t 65isc_stdio_tell(FILE *f, off_t *offsetp) { 66 off_t r; 67 68 REQUIRE(offsetp != NULL); 69 70 r = ftello(f); 71 if (r >= 0) { 72 *offsetp = r; 73 return (ISC_R_SUCCESS); 74 } else 75 return (isc__errno2result(errno)); 76} 77 78isc_result_t 79isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) { 80 isc_result_t result = ISC_R_SUCCESS; 81 size_t r; 82 83 clearerr(f); 84 r = fread(ptr, size, nmemb, f); 85 if (r != nmemb) { 86 if (feof(f)) 87 result = ISC_R_EOF; 88 else 89 result = isc__errno2result(errno); 90 } 91 if (nret != NULL) 92 *nret = r; 93 return (result); 94} 95 96isc_result_t 97isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f, 98 size_t *nret) 99{ 100 isc_result_t result = ISC_R_SUCCESS; 101 size_t r; 102 103 clearerr(f); 104 r = fwrite(ptr, size, nmemb, f); 105 if (r != nmemb) 106 result = isc__errno2result(errno); 107 if (nret != NULL) 108 *nret = r; 109 return (result); 110} 111 112isc_result_t 113isc_stdio_flush(FILE *f) { 114 int r; 115 116 r = fflush(f); 117 if (r == 0) 118 return (ISC_R_SUCCESS); 119 else 120 return (isc__errno2result(errno)); 121} 122 123/* 124 * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP. 125 */ 126#if defined(EOPNOTSUPP) && !defined(ENOTSUP) 127#define ENOTSUP EOPNOTSUPP 128#endif 129 130isc_result_t 131isc_stdio_sync(FILE *f) { 132 int r; 133 134 r = fsync(fileno(f)); 135 /* 136 * fsync is not supported on sockets and pipes which 137 * result in EINVAL / ENOTSUP. 138 */ 139 if (r == 0 || errno == EINVAL || errno == ENOTSUP) 140 return (ISC_R_SUCCESS); 141 else 142 return (isc__errno2result(errno)); 143} 144 145