1/*** 2 This file is part of eudev, forked from systemd. 3 4 Copyright 2010 Lennart Poettering 5 6 systemd is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as published by 8 the Free Software Foundation; either version 2.1 of the License, or 9 (at your option) any later version. 10 11 systemd is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public License 17 along with systemd; If not, see <http://www.gnu.org/licenses/>. 18***/ 19 20#include <unistd.h> 21#include <sys/sendfile.h> 22#include "fileio.h" 23#include "util.h" 24#include "strv.h" 25#include "utf8.h" 26#include "ctype.h" 27 28int write_string_stream(FILE *f, const char *line) { 29 assert(f); 30 assert(line); 31 32 errno = 0; 33 34 fputs(line, f); 35 if (!endswith(line, "\n")) 36 fputc('\n', f); 37 38 fflush(f); 39 40 if (ferror(f)) 41 return errno ? -errno : -EIO; 42 43 return 0; 44} 45 46int write_string_file(const char *fn, const char *line) { 47 _cleanup_fclose_ FILE *f = NULL; 48 49 assert(fn); 50 assert(line); 51 52 f = fopen(fn, "we"); 53 if (!f) 54 return -errno; 55 56 return write_string_stream(f, line); 57} 58int read_one_line_file(const char *fn, char **line) { 59 _cleanup_fclose_ FILE *f = NULL; 60 char t[LINE_MAX], *c; 61 62 assert(fn); 63 assert(line); 64 65 f = fopen(fn, "re"); 66 if (!f) 67 return -errno; 68 69 if (!fgets(t, sizeof(t), f)) { 70 71 if (ferror(f)) 72 return errno ? -errno : -EIO; 73 74 t[0] = 0; 75 } 76 77 c = strdup(t); 78 if (!c) 79 return -ENOMEM; 80 truncate_nl(c); 81 82 *line = c; 83 return 0; 84} 85 86int read_full_stream(FILE *f, char **contents, size_t *size) { 87 size_t n, l; 88 _cleanup_free_ char *buf = NULL; 89 struct stat st; 90 91 assert(f); 92 assert(contents); 93 94 if (fstat(fileno(f), &st) < 0) 95 return -errno; 96 97 n = LINE_MAX; 98 99 if (S_ISREG(st.st_mode)) { 100 101 /* Safety check */ 102 if (st.st_size > 4*1024*1024) 103 return -E2BIG; 104 105 /* Start with the right file size, but be prepared for 106 * files from /proc which generally report a file size 107 * of 0 */ 108 if (st.st_size > 0) 109 n = st.st_size; 110 } 111 112 l = 0; 113 for (;;) { 114 char *t; 115 size_t k; 116 117 t = realloc(buf, n+1); 118 if (!t) 119 return -ENOMEM; 120 121 buf = t; 122 k = fread(buf + l, 1, n - l, f); 123 124 if (k <= 0) { 125 if (ferror(f)) 126 return -errno; 127 128 break; 129 } 130 131 l += k; 132 n *= 2; 133 134 /* Safety check */ 135 if (n > 4*1024*1024) 136 return -E2BIG; 137 } 138 139 buf[l] = 0; 140 *contents = buf; 141 buf = NULL; /* do not free */ 142 143 if (size) 144 *size = l; 145 146 return 0; 147} 148 149int read_full_file(const char *fn, char **contents, size_t *size) { 150 _cleanup_fclose_ FILE *f = NULL; 151 152 assert(fn); 153 assert(contents); 154 155 f = fopen(fn, "re"); 156 if (!f) 157 return -errno; 158 159 return read_full_stream(f, contents, size); 160} 161