fileio.c revision 550a40eceb7d1917152fc9317bf2696708d52bc2
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder This file is part of systemd.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder Copyright 2010 Lennart Poettering
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder systemd is free software; you can redistribute it and/or modify it
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder under the terms of the GNU Lesser General Public License as published by
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder the Free Software Foundation; either version 2.1 of the License, or
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder (at your option) any later version.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder systemd is distributed in the hope that it will be useful, but
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder WITHOUT ANY WARRANTY; without even the implied warranty of
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder Lesser General Public License for more details.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder You should have received a copy of the GNU Lesser General Public License
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder along with systemd; If not, see <http://www.gnu.org/licenses/>.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroederint write_string_to_file(FILE *f, const char *line) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroederint write_string_file(const char *fn, const char *line) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroederint write_string_file_atomic(const char *fn, const char *line) {
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maederint read_one_line_file(const char *fn, char **line) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (!fgets(t, sizeof(t), f)) {
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maederssize_t sendfile_full(int out_fd, const char *fn) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder s = sendfile(out_fd, fileno(f), NULL, st.st_size);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* continue below */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* sendfile() failed, fall back to read/write */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* Safety check */
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder n = st.st_size > 0 ? st.st_size : LINE_MAX;
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder while (true) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* Safety check */
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maederint read_full_file(const char *fn, char **contents, size_t *size) {
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder /* Safety check */
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder n = st.st_size > 0 ? st.st_size : LINE_MAX;
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder if (k <= 0) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* Safety check */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder int (*push) (const char *filename, unsigned line,
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder const char *key, char *value, void *userdata),
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder _cleanup_free_ char *contents = NULL, *key = NULL;
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder r = read_full_file(fname, &contents, NULL);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder for (p = contents; *p; p++) {
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder } else if (c == '=') {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder else if (last_key_whitespace == (size_t) -1)
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* strip trailing whitespace from key */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (last_key_whitespace != (size_t) -1)
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder r = push(fname, line, key, value, userdata);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder } else if (c == '\'')
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder else if (c == '\"')
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder else if (c == '\\')
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
line ++;
if (value)
goto fail;
n_key = 0;
r = -ENOMEM;
goto fail;
case VALUE_ESCAPE:
r = -ENOMEM;
goto fail;
case SINGLE_QUOTE_VALUE:
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
case DOUBLE_QUOTE_VALUE:
r = -ENOMEM;
goto fail;
r = -ENOMEM;
goto fail;
case COMMENT:
line ++;
case COMMENT_ESCAPE:
if (value)
goto fail;
fail:
return -EINVAL;
return -EINVAL;
free(*v);
*v = value;
int parse_env_file(
const char *fname,
const char *newline, ...) {
if (!newline)
char ***m = userdata;
return -EINVAL;
return -EINVAL;
return -ENOMEM;
r = strv_push(m, p);
free(p);
char **m = NULL;
if (!newline)
strv_free(m);
*rl = m;
fputs(v, f);
fputc(*p, f);
fputs(p, f);
errno = 0;
STRV_FOREACH(i, l)
write_env_var(f, *i);
fflush(f);
if (ferror(f))
r = -errno;
unlink(p);
int len;
char *ans;
if (len == 0)
if (!ans)
return -ENOMEM;
return -ENOENT;
if (!*t || isspace(*t))
if (!*field)
return -ENOMEM;