2 This file is part of systemd.
4 Copyright 2010-2012 Lennart Poettering
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.
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.
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/>.
24 #include <sys/types.h>
25 #include <linux/magic.h>
26 #include <sys/statvfs.h>
29 #include "dirent-util.h"
33 #include "stat-util.h"
34 #include "string-util.h"
36 int is_symlink(const char *path
) {
41 if (lstat(path
, &info
) < 0)
44 return !!S_ISLNK(info
.st_mode
);
47 int is_dir(const char* path
, bool follow
) {
60 return !!S_ISDIR(st
.st_mode
);
63 int is_device_node(const char *path
) {
68 if (lstat(path
, &info
) < 0)
71 return !!(S_ISBLK(info
.st_mode
) || S_ISCHR(info
.st_mode
));
74 int dir_is_empty(const char *path
) {
75 _cleanup_closedir_
DIR *d
;
82 FOREACH_DIRENT(de
, d
, return -errno
)
88 bool null_or_empty(struct stat
*st
) {
91 if (S_ISREG(st
->st_mode
) && st
->st_size
<= 0)
94 /* We don't want to hardcode the major/minor of /dev/null,
95 * hence we do a simpler "is this a device node?" check. */
97 if (S_ISCHR(st
->st_mode
) || S_ISBLK(st
->st_mode
))
103 int null_or_empty_path(const char *fn
) {
108 if (stat(fn
, &st
) < 0)
111 return null_or_empty(&st
);
114 int null_or_empty_fd(int fd
) {
119 if (fstat(fd
, &st
) < 0)
122 return null_or_empty(&st
);
125 int path_is_read_only_fs(const char *path
) {
130 if (statvfs(path
, &st
) < 0)
133 if (st
.f_flag
& ST_RDONLY
)
136 /* On NFS, statvfs() might not reflect whether we can actually
137 * write to the remote share. Let's try again with
138 * access(W_OK) which is more reliable, at least sometimes. */
139 if (access(path
, W_OK
) < 0 && errno
== EROFS
)
145 int path_is_os_tree(const char *path
) {
151 /* We use /usr/lib/os-release as flag file if something is an OS */
152 p
= strjoina(path
, "/usr/lib/os-release");
157 /* Also check for the old location in /etc, just in case. */
158 p
= strjoina(path
, "/etc/os-release");
164 int files_same(const char *filea
, const char *fileb
) {
170 if (stat(filea
, &a
) < 0)
173 if (stat(fileb
, &b
) < 0)
176 return a
.st_dev
== b
.st_dev
&&
177 a
.st_ino
== b
.st_ino
;
180 bool is_fs_type(const struct statfs
*s
, statfs_f_type_t magic_value
) {
182 assert_cc(sizeof(statfs_f_type_t
) >= sizeof(s
->f_type
));
184 return F_TYPE_EQUAL(s
->f_type
, magic_value
);
187 int fd_check_fstype(int fd
, statfs_f_type_t magic_value
) {
190 if (fstatfs(fd
, &s
) < 0)
193 return is_fs_type(&s
, magic_value
);
196 int path_check_fstype(const char *path
, statfs_f_type_t magic_value
) {
197 _cleanup_close_
int fd
= -1;
199 fd
= open(path
, O_RDONLY
);
203 return fd_check_fstype(fd
, magic_value
);
206 bool is_temporary_fs(const struct statfs
*s
) {
207 return is_fs_type(s
, TMPFS_MAGIC
) ||
208 is_fs_type(s
, RAMFS_MAGIC
);
211 int fd_is_temporary_fs(int fd
) {
214 if (fstatfs(fd
, &s
) < 0)
217 return is_temporary_fs(&s
);