stat-util: introduce a common (stat|fd)_verify_regular_or_block() helper
We already had one in repart.c, let's generalize it, and use it everywhere.
This commit is contained in:
@@ -220,6 +220,28 @@ int is_device_node(const char *path) {
|
||||
return verify_stat_at(AT_FDCWD, path, false, stat_verify_device_node, false);
|
||||
}
|
||||
|
||||
int stat_verify_regular_or_block(const struct stat *st) {
|
||||
assert(st);
|
||||
|
||||
if (S_ISDIR(st->st_mode))
|
||||
return -EISDIR;
|
||||
|
||||
if (S_ISLNK(st->st_mode))
|
||||
return -ELOOP;
|
||||
|
||||
if (!S_ISREG(st->st_mode) && !S_ISBLK(st->st_mode))
|
||||
return -EBADFD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd_verify_regular_or_block(int fd) {
|
||||
if (IN_SET(fd, AT_FDCWD, XAT_FDROOT))
|
||||
return -EISDIR;
|
||||
|
||||
return verify_stat_at(fd, /* path= */ NULL, /* follow= */ false, stat_verify_regular_or_block, /* verify= */ true);
|
||||
}
|
||||
|
||||
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct dirent *buf;
|
||||
|
||||
@@ -31,6 +31,9 @@ int fd_verify_linked(int fd);
|
||||
int stat_verify_device_node(const struct stat *st);
|
||||
int is_device_node(const char *path);
|
||||
|
||||
int stat_verify_regular_or_block(const struct stat *st);
|
||||
int fd_verify_regular_or_block(int fd);
|
||||
|
||||
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup);
|
||||
static inline int dir_is_empty(const char *path, bool ignore_hidden_or_backup) {
|
||||
return dir_is_empty_at(AT_FDCWD, path, ignore_hidden_or_backup);
|
||||
|
||||
@@ -1250,10 +1250,9 @@ static int open_image_file(
|
||||
|
||||
if (fstat(image_fd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to fstat() image file: %m");
|
||||
if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
|
||||
return log_error_errno(
|
||||
S_ISDIR(st.st_mode) ? SYNTHETIC_ERRNO(EISDIR) : SYNTHETIC_ERRNO(EBADFD),
|
||||
"Image file %s is not a regular file or block device.", ip);
|
||||
r = stat_verify_regular_or_block(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Image file '%s' is not a regular file or block device.", ip);
|
||||
|
||||
/* Locking block devices doesn't really make sense, as this might interfere with
|
||||
* udev's workings, and these locks aren't network propagated anyway, hence not what
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "pretty-print.h"
|
||||
#include "qcow2-util.h"
|
||||
#include "ratelimit.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "time-util.h"
|
||||
@@ -309,9 +310,9 @@ static int raw_import_open_disk(RawImport *i) {
|
||||
if (fstat(i->output_fd, &i->output_stat) < 0)
|
||||
return log_error_errno(errno, "Failed to stat() output file: %m");
|
||||
|
||||
if (!S_ISREG(i->output_stat.st_mode) && !S_ISBLK(i->output_stat.st_mode))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADFD),
|
||||
"Target file is not a regular file or block device");
|
||||
r = stat_verify_regular_or_block(&i->output_stat);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Target file is not a regular file or block device.");
|
||||
|
||||
if (i->offset != UINT64_MAX) {
|
||||
if (lseek(i->output_fd, i->offset, SEEK_SET) < 0)
|
||||
|
||||
@@ -158,16 +158,10 @@ static int validate_image_fd(int fd, MountImageParameters *p) {
|
||||
assert(fd >= 0);
|
||||
assert(p);
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
/* Only support regular files and block devices. Let's use stat_verify_regular() here for the nice
|
||||
* error numbers it generates. */
|
||||
if (!S_ISBLK(st.st_mode)) {
|
||||
r = stat_verify_regular(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
/* Only support regular files and block devices. */
|
||||
r = fd_verify_regular_or_block(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fl = fd_verify_safe_flags_full(fd, O_NONBLOCK);
|
||||
if (fl < 0)
|
||||
|
||||
+2
-22
@@ -3226,26 +3226,6 @@ static int determine_current_padding(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_regular_or_block(int fd) {
|
||||
struct stat st;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (S_ISDIR(st.st_mode))
|
||||
return -EISDIR;
|
||||
|
||||
if (S_ISLNK(st.st_mode))
|
||||
return -ELOOP;
|
||||
|
||||
if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
|
||||
return -EBADFD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int context_copy_from_one(Context *context, const char *src) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
|
||||
@@ -3261,9 +3241,9 @@ static int context_copy_from_one(Context *context, const char *src) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = verify_regular_or_block(fd);
|
||||
r = fd_verify_regular_or_block(fd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "%s is not a file nor a block device: %m", src);
|
||||
return log_error_errno(r, "'%s' is not a file nor a block device: %m", src);
|
||||
|
||||
r = fdisk_new_context_at(fd, /* path= */ NULL, /* read_only= */ true, /* sector_size= */ UINT32_MAX, &c);
|
||||
if (r < 0)
|
||||
|
||||
@@ -820,7 +820,6 @@ int loop_device_make_by_path_memory(
|
||||
|
||||
_cleanup_close_ int fd = -EBADF, mfd = -EBADF;
|
||||
_cleanup_free_ char *fn = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
@@ -837,11 +836,9 @@ int loop_device_make_by_path_memory(
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
|
||||
return -EBADF;
|
||||
r = fd_verify_regular_or_block(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = path_extract_filename(path, &fn);
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user