return verify_stat_at(fd, /* path= */ NULL, /* follow= */ false, stat_verify_block, /* verify= */ true);
}
+int stat_verify_char(const struct stat *st) {
+ assert(st);
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISCHR(st->st_mode))
+ return -EBADFD;
+
+ return 0;
+}
+
int stat_verify_device_node(const struct stat *st) {
assert(st);
int stat_verify_block(const struct stat *st);
int fd_verify_block(int fd);
+int stat_verify_char(const struct stat *st);
+
int stat_verify_device_node(const struct stat *st);
int is_device_node(const char *path);
}
static int terminal_verify_same(int input_fd, int output_fd) {
+ int r;
+
assert(input_fd >= 0);
assert(output_fd >= 0);
if (fstat(input_fd, &sti) < 0)
return -errno;
- if (!S_ISCHR(sti.st_mode)) /* TTYs are character devices */
- return -ENOTTY;
+ r = stat_verify_char(&sti); /* TTYs are character devices */
+ if (r < 0)
+ return r;
struct stat sto;
if (fstat(output_fd, &sto) < 0)
return -errno;
- if (!S_ISCHR(sto.st_mode))
- return -ENOTTY;
+ r = stat_verify_char(&sto);
+ if (r < 0)
+ return r;
if (sti.st_rdev != sto.st_rdev)
return -ENOLINK;
goto fail;
}
- if (!S_ISCHR(st.st_mode)) {
- r = -ENOTTY;
+ r = stat_verify_char(&st);
+ if (r < 0)
goto fail;
- }
last_errno = 0;
return m->confirm_spawn;
#include "log.h"
#include "path-util.h"
#include "ratelimit.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
static int watchdog_get_sysfs_path(const char *filename, char **ret_path) {
struct stat st;
+ int r;
if (watchdog_fd < 0)
return -EBADF;
if (fstat(watchdog_fd, &st))
return -errno;
- if (!S_ISCHR(st.st_mode))
- return -EBADF;
+ r = stat_verify_char(&st);
+ if (r < 0)
+ return r;
if (asprintf(ret_path, "/sys/dev/char/"DEVNUM_FORMAT_STR"/%s", DEVNUM_FORMAT_VAL(st.st_rdev), filename) < 0)
return -ENOMEM;