}
int btrfs_reflink(int infd, int outfd) {
- struct stat st;
int r;
assert(infd >= 0);
assert(outfd >= 0);
- /* Make sure we invoke the ioctl on a regular file, so that no
- * device driver accidentally gets it. */
-
- if (fstat(outfd, &st) < 0)
- return -errno;
+ /* Make sure we invoke the ioctl on a regular file, so that no device driver accidentally gets it. */
- if (!S_ISREG(st.st_mode))
- return -EINVAL;
-
- r = ioctl(outfd, BTRFS_IOC_CLONE, infd);
+ r = fd_verify_regular(outfd);
if (r < 0)
+ return r;
+
+ if (ioctl(outfd, BTRFS_IOC_CLONE, infd) < 0)
return -errno;
return 0;
.src_length = sz,
.dest_offset = out_offset,
};
- struct stat st;
int r;
assert(infd >= 0);
assert(outfd >= 0);
assert(sz > 0);
- if (fstat(outfd, &st) < 0)
- return -errno;
-
- if (!S_ISREG(st.st_mode))
- return -EINVAL;
-
- r = ioctl(outfd, BTRFS_IOC_CLONE_RANGE, &args);
+ r = fd_verify_regular(outfd);
if (r < 0)
+ return r;
+
+ if (ioctl(outfd, BTRFS_IOC_CLONE_RANGE, &args) < 0)
return -errno;
return 0;
}
int btrfs_defrag_fd(int fd) {
- struct stat st;
+ int r;
assert(fd >= 0);
- if (fstat(fd, &st) < 0)
- return -errno;
-
- if (!S_ISREG(st.st_mode))
- return -EINVAL;
+ r = fd_verify_regular(fd);
+ if (r < 0)
+ return r;
if (ioctl(fd, BTRFS_IOC_DEFRAG, NULL) < 0)
return -errno;
return fd_is_temporary_fs(fd);
}
+
+int stat_verify_regular(const struct stat *st) {
+ assert(st);
+
+ /* Checks whether the specified stat() structure refers to a regular file. If not returns an appropriate error
+ * code. */
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISREG(st->st_mode))
+ return -EBADFD;
+
+ return 0;
+}
+
+int fd_verify_regular(int fd) {
+ struct stat st;
+
+ assert(fd >= 0);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ return stat_verify_regular(&st);
+}
* signed/unsigned comparison, because the magic can be 32 bit unsigned.
*/
#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
+
+int stat_verify_regular(const struct stat *st);
+int fd_verify_regular(int fd);
#include "import-common.h"
#include "missing.h"
#include "ratelimit.h"
+#include "stat-util.h"
#include "string-util.h"
#include "util.h"
if (fstat(sfd, &e->st) < 0)
return -errno;
- if (!S_ISREG(e->st.st_mode))
- return -ENOTTY;
+ r = stat_verify_regular(&e->st);
+ if (r < 0)
+ return r;
/* Try to take a reflink snapshot of the file, if we can t make the export atomic */
tfd = reflink_snapshot(sfd, path);
#include "random-util.h"
#include "sd-event.h"
#include "set.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "xattr-util.h"
}
static int journal_file_fstat(JournalFile *f) {
+ int r;
+
assert(f);
assert(f->fd >= 0);
f->last_stat_usec = now(CLOCK_MONOTONIC);
/* Refuse dealing with with files that aren't regular */
- if (S_ISDIR(f->last_stat.st_mode))
- return -EISDIR;
- if (!S_ISREG(f->last_stat.st_mode))
- return -EBADFD;
+ r = stat_verify_regular(&f->last_stat);
+ if (r < 0)
+ return r;
/* Refuse appending to files that are already deleted */
if (f->last_stat.st_nlink <= 0)
r = log_debug_errno(errno, "Failed to fstat file '%s': %m", path);
goto finish;
}
- if (S_ISDIR(st.st_mode)) {
- log_debug("Uh, file '%s' is a directory? Refusing.", path);
- r = -EISDIR;
- goto finish;
- }
- if (!S_ISREG(st.st_mode)) {
- log_debug("Uh, file '%s' is not a regular file? Refusing.", path);
- r = -EBADFD;
+
+ r = stat_verify_regular(&st);
+ if (r < 0) {
+ log_debug_errno(r, "Refusing to open '%s', as it is not a regular file.", path);
goto finish;
}
goto fail;
}
- if (S_ISDIR(st.st_mode)) {
- r = -EISDIR;
- goto fail;
- }
- if (!S_ISREG(st.st_mode)) {
- r = -EBADFD;
+ r = stat_verify_regular(&st);
+ if (r < 0)
goto fail;
- }
r = add_any_file(j, fds[i], NULL);
if (r < 0)
info->type = UNIT_FILE_TYPE_MASKED;
return 0;
}
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
+
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
f = fdopen(fd, "re");
if (!f)
if (lstat(full, &st) < 0)
return -errno;
- if (S_ISLNK(st.st_mode))
- return -ELOOP;
- if (S_ISDIR(st.st_mode))
- return -EISDIR;
- if (!S_ISREG(st.st_mode))
- return -ENOTTY;
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
q = in_search_path(&paths, *i);
if (q < 0)
#include "alloc-util.h"
#include "fd-util.h"
#include "loop-util.h"
+#include "stat-util.h"
int loop_device_make(int fd, int open_flags, LoopDevice **ret) {
const struct loop_info64 info = {
_cleanup_free_ char *loopdev = NULL;
struct stat st;
LoopDevice *d;
- int nr;
+ int nr, r;
assert(fd >= 0);
assert(ret);
return 0;
}
- if (!S_ISREG(st.st_mode))
- return -EINVAL;
+ r = stat_verify_regular(&st);
+ if (r < 0)
+ return r;
control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (control < 0)