[ghex/support-block-devices: 5/5] hex-buffer-mmap: Initial support for block devices.




commit 95fcb10562be2a176ecf1b6947ef9b8548157dd7
Author: Logan Rathbone <poprocks gmail com>
Date:   Thu Apr 28 03:49:19 2022 -0400

    hex-buffer-mmap: Initial support for block devices.
    
    This makes this backend explicitly Linux-only (let's face it:
    realistically it probably was before as well), so adjust meson.build
    accordingly.

 meson.build           |  3 +++
 src/hex-buffer-mmap.c | 32 +++++++++++++++++++-------------
 src/hex-buffer-mmap.h |  2 ++
 3 files changed, 24 insertions(+), 13 deletions(-)
---
diff --git a/meson.build b/meson.build
index ed846da..995342a 100644
--- a/meson.build
+++ b/meson.build
@@ -112,6 +112,8 @@ if mmap_backend
     'fcntl.h',
     'sys/stat.h',
     'sys/mman.h',
+    'sys/ioctl.h',
+    'linux/fs.h',
     ]
   foreach h : check_headers_mmap
     cc.has_header(h, required: true)
@@ -120,6 +122,7 @@ if mmap_backend
   check_functions_mmap = [
     'mmap',
     'mremap',
+    'ioctl',
   ]
   foreach f : check_functions_mmap
     if cc.has_function(f) == false
diff --git a/src/hex-buffer-mmap.c b/src/hex-buffer-mmap.c
index 9526c16..afad6a0 100644
--- a/src/hex-buffer-mmap.c
+++ b/src/hex-buffer-mmap.c
@@ -10,7 +10,7 @@
  * permission from Peter Klausler dated December 13, 2021 (see
  * associated git log).
  *
- * Copyright © 2021 Logan Rathbone
+ * Copyright © 2021-2022 Logan Rathbone
  *
  * GHex is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -578,7 +578,7 @@ create_fd_from_path (HexBufferMmap *self, const char *path)
 
        errno = 0;
 
-       if (stat (path, &statbuf))
+       if (stat (path, &statbuf) != 0)
        {
                if (errno != ENOENT) {
                        set_error (self,
@@ -597,11 +597,10 @@ create_fd_from_path (HexBufferMmap *self, const char *path)
        } 
        else
        {
-               /* FIXME - this is probably overkill - hex editor users may wish to
-                * open a 'non-regular' file.
-                */
-               if (!S_ISREG(statbuf.st_mode)) {
-                       set_error (self, _("Not a regular file"));
+               /*      We only support regular files and block devices. */
+               if (! S_ISREG(statbuf.st_mode) && ! S_ISBLK(statbuf.st_mode))
+               {
+                       set_error (self, _("Not a regular file or block device"));
                        return -1;
                }
 
@@ -669,7 +668,6 @@ hex_buffer_mmap_read (HexBuffer *buf)
        }
 
        bytes = hex_buffer_util_get_file_size (self->file);
-       pages = (bytes + self->pagesize - 1) / self->pagesize;
 
        /* Set up a clean buffer (read-only memory mapped version of O.G. file)
         */
@@ -679,15 +677,23 @@ hex_buffer_mmap_read (HexBuffer *buf)
        self->clean_bytes = bytes;
        self->clean = NULL;
 
-       if (! pages)
+       tmp_clean_fd = create_fd_from_path (self, file_path);
+       if (tmp_clean_fd < 0)
        {
-               set_error (self, _("Error reading file"));
                return FALSE;
        }
+       else if (! self->clean_bytes)   /* block device */
+       {
+               gint64 block_file_size;
 
-       tmp_clean_fd = create_fd_from_path (self, file_path);
-       if (tmp_clean_fd < 0)
-               return FALSE;
+               if (ioctl (tmp_clean_fd, BLKGETSIZE64, &block_file_size) != 0)
+               {
+                       set_error (self, _("Error attempting to read block device"));
+                       return FALSE;
+               }
+               self->clean_bytes = block_file_size;
+       }
+       pages = (self->clean_bytes + self->pagesize - 1) / self->pagesize;
 
        self->clean_fd = tmp_clean_fd;
 
diff --git a/src/hex-buffer-mmap.h b/src/hex-buffer-mmap.h
index af2a8cb..119880a 100644
--- a/src/hex-buffer-mmap.h
+++ b/src/hex-buffer-mmap.h
@@ -40,6 +40,8 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
 
 G_BEGIN_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]