fs-util.c revision ee735086f8670be1591fa9593e80dd60163a7a2f
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering This file is part of systemd.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering Copyright 2010 Lennart Poettering
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering systemd is free software; you can redistribute it and/or modify it
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering under the terms of the GNU Lesser General Public License as published by
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering (at your option) any later version.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering systemd is distributed in the hope that it will be useful, but
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering Lesser General Public License for more details.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering You should have received a copy of the GNU Lesser General Public License
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringint rmdir_parents(const char *path, const char *stop) {
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* Skip trailing slashes */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering while (l > 0) {
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* Skip last component */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* Skip trailing slashes */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringint rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* renameat2() exists since Linux 3.15, btrfs added support for it later.
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * If it is not implemented, fallback to another method. */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* The link()/unlink() fallback does not work on directories. But
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * renameat() without RENAME_NOREPLACE gives the same semantics on
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * directories, except when newpath is an *empty* directory. This is
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering * good enough. */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering ret = renameat(olddirfd, oldpath, newdirfd, newpath);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* If it is not a directory, use the link()/unlink() fallback. */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering /* backup errno before the following unlinkat() alters it */
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringint readlinkat_malloc(int fd, const char *p, char **ret) {
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringint readlink_malloc(const char *p, char **ret) {
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poettering return readlinkat_malloc(AT_FDCWD, p, ret);
dc83f27a7cf03757dec11a69ec18504ad4ea8f89Lennart Poetteringint readlink_value(const char *p, char **ret) {
char *value;
if (!value)
return -ENOENT;
if (!value)
return -ENOMEM;
int readlink_and_make_absolute(const char *p, char **r) {
assert(p);
assert(r);
return -ENOMEM;
int readlink_and_canonicalize(const char *p, char **r) {
assert(p);
assert(r);
j = readlink_and_make_absolute(p, &t);
s = canonicalize_file_name(t);
free(t);
path_kill_slashes(*r);
return -errno;
return -errno;
return -errno;
return -errno;
mode_t u;
umask(u);
return -errno;
log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
if (parents)
if (fd < 0)
return -errno;
return -errno;
return -errno;
return -errno;
return -errno;
return -EINVAL;
return -errno;
unlink_noerrno(t);
return -errno;
return -errno;
unlink_noerrno(t);
return -errno;
return -errno;
unlink_noerrno(t);
return -errno;
return -errno;
errno = 0;
return -errno;
if (!de)
if (list) {
return -ENOMEM;
return -ENOMEM;
l[++n] = NULL;
if (list) {
*list = l;