]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/blkdev: add open_blkdev_or_file() function
authorSami Kerola <kerolasa@iki.fi>
Sat, 31 Oct 2015 17:29:02 +0000 (17:29 +0000)
committerSami Kerola <kerolasa@iki.fi>
Sun, 22 Nov 2015 20:56:05 +0000 (20:56 +0000)
Purpose of this function is to open a path that is potentially pointing to a
block device or file without races.  The function also proper open(3) flags
are used to check the device is not busy, and finally warning is been
printed if a block device happens to be misaligned.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
include/blkdev.h
lib/blkdev.c

index c994795a2ac1e2ab4b7eab70b42cf7e85b0b0012..46fb2cef052a67f5a3a77fb52ff8b961706ccfde 100644 (file)
@@ -97,6 +97,9 @@ struct hd_geometry {
 /* are we working with block device? */
 int is_blkdev(int fd);
 
+/* open block device or file */
+int open_blkdev_or_file(const struct stat *st, const char *name, const int oflag);
+
 /* Determine size in bytes */
 off_t blkdev_find_size (int fd);
 
index 5f495822ee42979216a365117f6d36407861655b..a57b3672bf930c25ceecf1b57350a69a8b047e87 100644 (file)
 # include <sys/disk.h>
 #endif
 
+#ifndef EBADFD
+# define EBADFD 77             /* File descriptor in bad state */
+#endif
+
 #include "blkdev.h"
 #include "c.h"
 #include "linux_version.h"
+#include "fileutils.h"
+#include "nls.h"
 
 static long
 blkdev_valid_offset (int fd, off_t offset) {
@@ -254,6 +260,24 @@ int blkdev_is_misaligned(int fd)
 #endif
 }
 
+int open_blkdev_or_file(const struct stat *st, const char *name, const int oflag)
+{
+       int fd;
+
+       if (S_ISBLK(st->st_mode)) {
+               fd = open(name, oflag | O_EXCL);
+       } else
+               fd = open(name, oflag);
+       if (-1 < fd && !is_same_inode(fd, st)) {
+               close(fd);
+               errno = EBADFD;
+               return -1;
+       }
+       if (-1 < fd && S_ISBLK(st->st_mode) && blkdev_is_misaligned(fd))
+               warnx(_("warning: %s is misaligned"), name);
+       return fd;
+}
+
 int blkdev_is_cdrom(int fd)
 {
 #ifdef CDROM_GET_CAPABILITY