[ghex] Optimizations for large files and mmap tweaks



commit 968c4e8d9bc0d449d74c48ad3cc010f467af1a93
Author: Logan Rathbone <poprocks gmail com>
Date:   Mon Dec 20 01:09:51 2021 -0500

    Optimizations for large files and mmap tweaks
    
    There were still many examples of 32-bit datatypes being used when
    larger datatypes were needed. Review code and ensure consistency. It is
    possible there are still a few bugs but it seems to be in working order
    now.
    
    For gtk_hex_update_all_autohighlights, limit the rendering to the
    previous and next 10 screens. This speeds things up *immensely* (read:
    makes it actually usable) with large files. This `10` number is
    arbitrary and can be changed if it feels unnaturally low.
    
    Unlink tmpfile name pre-emptively (mmap)

 src/findreplace.c     |  23 +++---
 src/gtkhex.c          | 208 +++++++++++++++++++++++++++++---------------------
 src/gtkhex.h          |   2 +-
 src/hex-buffer-mmap.c |  18 ++++-
 4 files changed, 152 insertions(+), 99 deletions(-)
---
diff --git a/src/findreplace.c b/src/findreplace.c
index cd3f26a..69a4c36 100644
--- a/src/findreplace.c
+++ b/src/findreplace.c
@@ -210,15 +210,6 @@ find_common (FindDialog *self, enum FindDirection direction,
                return;
        }
 
-       /* Insert auto-highlights of search string */
-
-       if (priv->auto_highlight)
-               gtk_hex_delete_autohighlight (priv->gh, priv->auto_highlight);
-
-       priv->auto_highlight = NULL;
-       priv->auto_highlight = gtk_hex_insert_autohighlight (priv->gh,
-                       str, str_len);
-
        /* Search for requested string */
        
        if (direction == FIND_FORWARD 
@@ -234,6 +225,16 @@ find_common (FindDialog *self, enum FindDirection direction,
        {
                found = TRUE;
                gtk_hex_set_cursor (priv->gh, offset);
+
+               /* If string found, insert auto-highlights of search string */
+
+               if (priv->auto_highlight)
+                       gtk_hex_delete_autohighlight (priv->gh, priv->auto_highlight);
+
+               priv->auto_highlight = NULL;
+               priv->auto_highlight = gtk_hex_insert_autohighlight (priv->gh,
+                               str, str_len);
+
                gtk_widget_grab_focus (GTK_WIDGET(priv->gh));
        }
        else
@@ -324,8 +325,8 @@ goto_byte_cb (GtkButton *button, gpointer user_data)
        if (! GTK_IS_WINDOW(parent))
                parent = NULL;
 
-       doc = gtk_hex_get_document(priv->gh);
-       cursor_pos = gtk_hex_get_cursor(priv->gh);
+       doc = gtk_hex_get_document (priv->gh);
+       cursor_pos = gtk_hex_get_cursor (priv->gh);
        payload = hex_buffer_get_payload_size (hex_document_get_buffer (doc));
 
        entry = GTK_ENTRY(self->int_entry);
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 88b702c..d3e6f61 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -104,8 +104,8 @@ struct _GtkHex_AutoHighlight
        char *search_string;
        int search_len;
 
-       int view_min;
-       int view_max;
+       gint64 view_min;
+       gint64 view_max;
 
        GtkHex_Highlight *highlights;
        GtkHex_AutoHighlight *next, *prev;
@@ -204,8 +204,7 @@ static void gtk_hex_validate_highlight (GtkHex *gh, GtkHex_Highlight *hl);
 static void gtk_hex_invalidate_highlight (GtkHex *gh, GtkHex_Highlight *hl);
 static void gtk_hex_invalidate_all_highlights (GtkHex *gh);
 
-static void gtk_hex_update_all_auto_highlights (GtkHex *gh, gboolean delete,
-               gboolean add);
+static void gtk_hex_update_all_auto_highlights (GtkHex *gh);
 
 static GtkHex_Highlight *gtk_hex_insert_highlight (GtkHex *gh,
                GtkHex_AutoHighlight *ahl, gint64 start, gint64 end);
@@ -363,7 +362,7 @@ static void
 hex_to_pointer (GtkHex *gh, int mx, int my)
 {
        int x = 0, cx = 0;
-       int cy;
+       gint64 cy;
        
        cy = gh->top_line + my/gh->char_height;
 
@@ -373,7 +372,7 @@ hex_to_pointer (GtkHex *gh, int mx, int my)
                
                if (x > mx)
                {
-                       gtk_hex_set_cursor_xy (gh, cx/2, cy);
+                       gtk_hex_set_cursor_by_row_and_col (gh, cx/2, cy);
                        gtk_hex_set_nibble (gh, ((cx%2 == 0)?UPPER_NIBBLE:LOWER_NIBBLE));
                        
                        cx = 2*gh->cpl;
@@ -389,11 +388,11 @@ hex_to_pointer (GtkHex *gh, int mx, int my)
 static void
 ascii_to_pointer (GtkHex *gh, int mx, int my)
 {
-       int cy;
+       gint64 cy;
        
        cy = gh->top_line + my/gh->char_height;
        
-       gtk_hex_set_cursor_xy (gh, mx/gh->char_width, cy);
+       gtk_hex_set_cursor_by_row_and_col (gh, mx/gh->char_width, cy);
 }
 
 static int
@@ -487,9 +486,9 @@ format_ablock (GtkHex *gh, char *out, gint64 start, gint64 end)
  * the block into x,y coordinates of the xdisp/adisp, respectively
  */
 static gboolean
-get_xcoords (GtkHex *gh, int pos, int *x, int *y)
+get_xcoords (GtkHex *gh, gint64 pos, int *x, int *y)
 {
-       int cx, cy, spaces;
+       gint64 cx, cy, spaces;
        
        if (gh->cpl == 0)
                return FALSE;
@@ -506,6 +505,13 @@ get_xcoords (GtkHex *gh, int pos, int *x, int *y)
        cx *= gh->char_width;
        cy *= gh->char_height;
        spaces *= gh->char_width;
+
+       /* nb: Having this as an assertion warning is annoying. Happens a lot
+        * in that case if you scroll way up/down in a big file and suddenly start
+        * dragging. */
+       if (cx + spaces < INT_MAX && cy < INT_MAX)
+               return FALSE;
+
        *x = cx + spaces;
        *y = cy;
        
@@ -513,9 +519,9 @@ get_xcoords (GtkHex *gh, int pos, int *x, int *y)
 }
 
 static gboolean
-get_acoords (GtkHex *gh, int pos, int *x, int *y)
+get_acoords (GtkHex *gh, gint64 pos, int *x, int *y)
 {
-       int cx, cy;
+       gint64 cx, cy;
        
        if (gh->cpl == 0)
                return FALSE;
@@ -529,6 +535,12 @@ get_acoords (GtkHex *gh, int pos, int *x, int *y)
        cy *= gh->char_height;
        cx = gh->char_width*(pos % gh->cpl);
        
+       /* nb: Having this as an assertion warning is annoying. Happens a lot
+        * in that case if you scroll way up/down in a big file and suddenly start
+        * dragging. */
+       if (cy < INT_MAX && cx < INT_MAX)
+               return FALSE;
+
        *x = cx;
        *y = cy;
        
@@ -571,7 +583,7 @@ render_cursor (GtkHex *gh,
                GtkHexViewType cursor_type)
 {
        GdkRGBA fg_color;
-       int index;
+       gint64 index;
        int range[2];
        GtkStateFlags state;
        GtkStyleContext *context;
@@ -754,14 +766,14 @@ render_highlights (GtkHex *gh,
 
        while (highlight)
        {
-               int cursor_off = 0;
-               int len;
+               gint64 cursor_off = 0;
+               size_t len;
 
                int range[2];
                double x1, x2, y1, y2;
 
                /* Shorthands for readability of this loop */
-               int start, end, start_line, end_line;
+               gint64 start, end, start_line, end_line;
 
                context = gtk_widget_get_style_context (widget);
                gtk_style_context_save (context);
@@ -908,8 +920,8 @@ invalidate_lines (GtkHex *gh,
 
 static void
 invalidate_hex_lines (GtkHex *gh,
-                      int imin,
-                      int imax)
+                      int imin,                /* FIXME - imin/imax for next few funcs */
+                      int imax)                /* presently ignored. */
 {
     invalidate_lines (gh, gh->xdisp, imin, imax);
 }
@@ -1148,7 +1160,7 @@ recalc_displays (GtkHex *gh)
 {
        GtkWidget *widget = GTK_WIDGET (gh);
        int hex_cpl;
-       size_t payload_size;
+       gint64 payload_size;
 
        hex_cpl = gtk_hex_layout_get_hex_cpl (GTK_HEX_LAYOUT(gh->layout_manager));
        payload_size = HEX_BUFFER_PAYLOAD (gh->document);
@@ -1220,13 +1232,13 @@ static void
 display_scrolled (GtkAdjustment *adj, GtkHex *gh)
 {
        int dx, dy;
-
+       
        g_return_if_fail (gtk_widget_is_drawable (gh->xdisp) &&
                        gtk_widget_is_drawable (gh->adisp));
 
        gh->top_line = gtk_adjustment_get_value (adj);
 
-       gtk_hex_update_all_auto_highlights (gh, TRUE, TRUE);
+       gtk_hex_update_all_auto_highlights (gh);
        gtk_hex_invalidate_all_highlights (gh);
 
        /* FIXME - this works, but feels hackish. The problem is, _snapshot_child
@@ -1248,7 +1260,7 @@ scroll_timeout_handler (GtkHex *gh)
        if (gh->scroll_dir < 0)
        {
                gtk_hex_set_cursor (gh,
-                               MAX (0, (int)(gh->cursor_pos - gh->cpl)));
+                               MAX (0, gh->cursor_pos - gh->cpl));
        }
        else if (gh->scroll_dir > 0)
        {
@@ -1270,10 +1282,10 @@ scroll_cb (GtkEventControllerScroll *controller,
 
        g_return_val_if_fail (GTK_IS_HEX(gh), FALSE);
 
-       old_value = gtk_adjustment_get_value(gh->adj);
+       old_value = gtk_adjustment_get_value (gh->adj);
        new_value = old_value + dy;
 
-       gtk_adjustment_set_value(gh->adj, new_value);
+       gtk_adjustment_set_value (gh->adj, new_value);
 
        /* TFM: returns true if scroll event was handled; false otherwise.
         */
@@ -1766,8 +1778,8 @@ static void
 gtk_hex_real_data_changed (GtkHex *gh, gpointer data)
 {
        HexChangeData *change_data = (HexChangeData *)data;
-       int start_line, end_line;
-       int lines;
+       gint64 start_line, end_line;
+       gint64 lines;
        size_t payload_size;
 
        g_return_if_fail (HEX_IS_DOCUMENT (gh->document));
@@ -1820,10 +1832,10 @@ gtk_hex_real_data_changed (GtkHex *gh, gpointer data)
 }
 
 static void
-bytes_changed (GtkHex *gh, int start, int end)
+bytes_changed (GtkHex *gh, gint64 start, gint64 end)
 {
-       int start_line;
-       int end_line;
+       gint64 start_line;
+       gint64 end_line;
 
        /* check for divide-by-zero issues */
        g_return_if_fail (gh->cpl);
@@ -1871,8 +1883,9 @@ gtk_hex_invalidate_all_highlights (GtkHex *gh)
 
        while (cur)
        {
-               gtk_hex_invalidate_highlight(gh, cur);
+               gtk_hex_invalidate_highlight (gh, cur);
                cur = cur->next;
+
                while (cur == NULL && nextList)
                {
                        cur = nextList->highlights;
@@ -1913,7 +1926,7 @@ static void
 gtk_hex_delete_highlight (GtkHex *gh, GtkHex_AutoHighlight *ahl,
                GtkHex_Highlight *hl)
 {
-       int start, end;
+       gint64 start, end;
        start = hl->start;
        end = hl->end;
        if (hl->prev) hl->prev->next = hl->next;
@@ -1930,12 +1943,12 @@ gtk_hex_delete_highlight (GtkHex *gh, GtkHex_AutoHighlight *ahl,
  * and simply returns a gboolean.
  */
 static gboolean
-gtk_hex_compare_data (GtkHex *gh, guchar *cmp, guint pos, int len)
+gtk_hex_compare_data (GtkHex *gh, guchar *cmp, gint64 pos, int len)
 {
-       int i;
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                guchar c = gtk_hex_get_byte (gh, pos + i);
+
                if (c != *(cmp + i))
                        return FALSE;
        }
@@ -1944,14 +1957,13 @@ gtk_hex_compare_data (GtkHex *gh, guchar *cmp, guint pos, int len)
 
 static gboolean
 gtk_hex_find_limited (GtkHex *gh, char *find, int findlen,
-               int lower, int upper,
-               int *found)
+               gint64 lower, gint64 upper, gint64 *found)
 {
-       int pos = lower;
+       gint64 pos = lower;
 
        while (pos < upper)
        {
-               if (gtk_hex_compare_data(gh, (guchar *)find, pos, findlen))
+               if (gtk_hex_compare_data (gh, (guchar *)find, pos, findlen))
                {
                        *found = pos;
                        return TRUE;
@@ -1961,22 +1973,29 @@ gtk_hex_find_limited (GtkHex *gh, char *find, int findlen,
        return FALSE;
 }
 
-/* removes any highlights that arn't visible
- * adds any new highlights that became visible
+
+/* Helper for the autohighlight functions to set a reasonable default
+ * view_min () and view_max () value.
  */
+static inline void
+ahl_set_view_min_max (GtkHex *gh, GtkHex_AutoHighlight *ahl)
+{
+       ahl->view_min = gh->top_line * gh->cpl;
+       ahl->view_max = (gh->top_line + gh->vis_lines) * gh->cpl;
+}
+
 static void
-gtk_hex_update_auto_highlight(GtkHex *gh, GtkHex_AutoHighlight *ahl,
+gtk_hex_update_auto_highlight (GtkHex *gh, GtkHex_AutoHighlight *ahl,
                gboolean delete, gboolean add)
 {
-       int del_min, del_max;
-       int add_min, add_max;
-       int foundpos = -1;
-       int prev_min = ahl->view_min;
-       int prev_max = ahl->view_max;
+       gint64 del_min, del_max;
+       gint64 add_min, add_max;
+       gint64 foundpos = -1;
+       gint64 prev_min = ahl->view_min;
+       gint64 prev_max = ahl->view_max;
        GtkHex_Highlight *cur;
 
-       ahl->view_min = gh->top_line * gh->cpl;
-       ahl->view_max = (gh->top_line + gh->vis_lines) * gh->cpl;
+       ahl_set_view_min_max (gh, ahl);
 
        if (prev_min < ahl->view_min && prev_max < ahl->view_max)
        {
@@ -2009,29 +2028,45 @@ gtk_hex_update_auto_highlight(GtkHex *gh, GtkHex_AutoHighlight *ahl,
                if (cur->start >= del_min && cur->start <= del_max)
                {
                        GtkHex_Highlight *next = cur->next;
-                       gtk_hex_delete_highlight(gh, ahl, cur);
+
+                       gtk_hex_delete_highlight (gh, ahl, cur);
                        cur = next;
                }
                else cur = cur->next;
        }
+
        while (add &&
-                  gtk_hex_find_limited(gh, ahl->search_string, ahl->search_len,
-                                                               MAX(add_min, foundpos+1), add_max, &foundpos))
+                  gtk_hex_find_limited (gh, ahl->search_string, ahl->search_len,
+                          /* lower */ MAX(add_min, foundpos+1), add_max, &foundpos))
        {
-               gtk_hex_insert_highlight(gh, ahl,
+               gtk_hex_insert_highlight (gh, ahl,
                                foundpos, foundpos+(ahl->search_len)-1);
        }
 }
 
 static void
-gtk_hex_update_all_auto_highlights (GtkHex *gh,
-               gboolean delete, gboolean add)
+gtk_hex_update_all_auto_highlights (GtkHex *gh)
 {
        GtkHex_AutoHighlight *cur = gh->auto_highlight;
 
+       int mult = 10;
+
+       gint64 top_line_pos = gh->top_line * gh->cpl;
+       gint64 bot_line_pos = (gh->top_line + gh->vis_lines) * gh->cpl;
+
        while (cur)
        {
-               gtk_hex_update_auto_highlight(gh, cur, delete, add);
+               /* only refresh possibilities within a certain number of line numbers
+                */
+               if (top_line_pos - mult * gh->vis_lines * gh->cpl > cur->view_min ||
+                       bot_line_pos + mult * gh->vis_lines * gh->cpl < cur->view_max)
+               {
+                       /* do nothing */
+               }
+               else
+               {
+                       gtk_hex_update_auto_highlight (gh, cur, TRUE, TRUE);
+               }
                cur = cur->next;
        }
 }
@@ -2044,7 +2079,8 @@ gtk_hex_real_copy_to_clipboard (GtkHex *gh)
        GtkHexPasteData *paste;
        GdkContentProvider *provider_union;
        GdkContentProvider *provider_array[2];
-       int start_pos, end_pos, len;
+       gint64 start_pos, end_pos;
+       size_t len;
        char *doc_data;
        char *string;
 
@@ -2118,7 +2154,7 @@ plaintext_paste_received_cb (GObject *source_object,
                                text,
                                TRUE);
 
-               gtk_hex_set_cursor(gh, gh->cursor_pos + strlen(text));
+               gtk_hex_set_cursor (gh, gh->cursor_pos + strlen(text));
                
                g_free(text);
        }
@@ -2759,8 +2795,8 @@ gtk_hex_init (GtkHex *gh)
 
        /* Connect signal for adjustment */
 
-       g_signal_connect(G_OBJECT(gh->adj), "value-changed",
-                                        G_CALLBACK(display_scrolled), gh);
+       g_signal_connect (gh->adj, "value-changed",
+                                        G_CALLBACK (display_scrolled), gh);
 
        /* ACTIONS - Undo / Redo should start out disabled. */
 
@@ -2884,13 +2920,14 @@ gtk_hex_clear_selection (GtkHex *gh)
 void
 gtk_hex_delete_selection (GtkHex *gh)
 {
-       int start, end, len;
+       gint64 start, end;
+       size_t len;
 
        start = MIN(gh->selection.start, gh->selection.end);
        end = MAX(gh->selection.start, gh->selection.end);
 
        len = end - start + 1;
-       g_assert (len);
+       g_return_if_fail (len);
 
        gtk_hex_clear_selection (gh);
 
@@ -2932,7 +2969,7 @@ gtk_hex_set_nibble (GtkHex *gh, gboolean lower_nibble)
 void
 gtk_hex_set_cursor (GtkHex *gh, gint64 index)
 {
-       int y;
+       gint64 y;
        gint64 old_pos;
        size_t payload_size;
 
@@ -2982,8 +3019,8 @@ gtk_hex_set_cursor (GtkHex *gh, gint64 index)
                }
                else
                {
-                       guint start = MIN (gh->selection.start, gh->selection.end);
-                       guint end = MAX (gh->selection.start, gh->selection.end);
+                       gint64 start = MIN (gh->selection.start, gh->selection.end);
+                       gint64 end = MAX (gh->selection.start, gh->selection.end);
 
                        bytes_changed (gh, start, end);
                        gh->selection.end = gh->selection.start = gh->cursor_pos;
@@ -3001,38 +3038,38 @@ gtk_hex_set_cursor (GtkHex *gh, gint64 index)
  * currently visible part)
  */
 void
-gtk_hex_set_cursor_xy (GtkHex *gh, int x, int y)
+gtk_hex_set_cursor_by_row_and_col (GtkHex *gh, int col_x, gint64 line_y)
 {
-       int cp;
-       int old_pos;
-       size_t payload_size;
+       gint64 tmp_cursor_pos;
+       gint64 old_pos;
+       gint64 payload_size;
 
        g_return_if_fail (GTK_IS_HEX(gh));
 
        old_pos = gh->cursor_pos;
-       cp = y*gh->cpl + x;
+       tmp_cursor_pos = line_y * gh->cpl + col_x;
        payload_size = HEX_BUFFER_PAYLOAD (gh->document);
 
-       if ((y >= 0) && (y < gh->lines) && (x >= 0) &&
-          (x < gh->cpl) && (cp <= payload_size))
+       if ((line_y >= 0) && (line_y < gh->lines) && (col_x >= 0) &&
+          (col_x < gh->cpl) && (tmp_cursor_pos <= payload_size))
        {
-               if (!gh->insert && cp == payload_size)
-                       cp--;
+               if (!gh->insert && tmp_cursor_pos == payload_size)
+                       tmp_cursor_pos--;
 
-               cp = MAX(cp, 0);
+               tmp_cursor_pos = MAX(tmp_cursor_pos, 0);
 
                show_cursor (gh, FALSE);
                
-               gh->cursor_pos = cp;
+               gh->cursor_pos = tmp_cursor_pos;
                
-               if (y >= gh->top_line + gh->vis_lines) {
+               if (line_y >= gh->top_line + gh->vis_lines) {
                        gtk_adjustment_set_value (gh->adj,
-                                       MIN(y - gh->vis_lines + 1, gh->lines - gh->vis_lines));
+                                       MIN(line_y - gh->vis_lines + 1, gh->lines - gh->vis_lines));
                        gtk_adjustment_set_value (gh->adj,
                                        MAX(0, gtk_adjustment_get_value(gh->adj)));
                }
-               else if (y < gh->top_line) {
-                       gtk_adjustment_set_value(gh->adj, y);
+               else if (line_y < gh->top_line) {
+                       gtk_adjustment_set_value(gh->adj, line_y);
                }      
        
                g_signal_emit_by_name(G_OBJECT(gh), "cursor-moved");
@@ -3044,8 +3081,8 @@ gtk_hex_set_cursor_xy (GtkHex *gh, int x, int y)
                                                old_pos));
                }
                else if (gh->selection.end != gh->selection.start) {
-                       guint start = MIN(gh->selection.start, gh->selection.end);
-                       guint end = MAX(gh->selection.start, gh->selection.end);
+                       gint64 start = MIN(gh->selection.start, gh->selection.end);
+                       gint64 end = MAX(gh->selection.start, gh->selection.end);
                        gh->selection.end = gh->selection.start = 0;
                        bytes_changed(gh, start, end);
                }
@@ -3060,8 +3097,8 @@ gtk_hex_set_cursor_xy (GtkHex *gh, int x, int y)
 gint64
 gtk_hex_get_cursor (GtkHex *gh)
 {
-       g_return_val_if_fail(gh != NULL, -1);
-       g_return_val_if_fail(GTK_IS_HEX(gh), -1);
+       g_return_val_if_fail (gh != NULL, -1);
+       g_return_val_if_fail (GTK_IS_HEX(gh), -1);
 
        return gh->cursor_pos;
 }
@@ -3142,8 +3179,7 @@ gtk_hex_insert_autohighlight (GtkHex *gh,
        if (new->next) new->next->prev = new;
        gh->auto_highlight = new;
 
-       new->view_min = 0;
-       new->view_max = 0;
+       ahl_set_view_min_max (gh, new);
 
        gtk_hex_update_auto_highlight (gh, new, FALSE, TRUE);
 
@@ -3192,7 +3228,7 @@ gtk_hex_get_document (GtkHex *gh)
 gboolean
 gtk_hex_get_insert_mode (GtkHex *gh)
 {
-       g_assert (GTK_IS_HEX (gh));
+       g_return_val_if_fail (GTK_IS_HEX (gh), FALSE);
 
        return gh->insert;
 }
diff --git a/src/gtkhex.h b/src/gtkhex.h
index e6bc6c8..d719154 100644
--- a/src/gtkhex.h
+++ b/src/gtkhex.h
@@ -63,7 +63,7 @@ typedef struct _GtkHex_AutoHighlight GtkHex_AutoHighlight;
 GtkWidget *gtk_hex_new (HexDocument *owner);
 
 void gtk_hex_set_cursor (GtkHex *gh, gint64 index);
-void gtk_hex_set_cursor_xy (GtkHex *gh, int x, int y);
+void gtk_hex_set_cursor_by_row_and_col (GtkHex *gh, int col_x, gint64 line_y);
 void gtk_hex_set_nibble (GtkHex *gh, gboolean lower_nibble);
 
 gint64 gtk_hex_get_cursor (GtkHex *gh);
diff --git a/src/hex-buffer-mmap.c b/src/hex-buffer-mmap.c
index d6c6fc0..fd37449 100644
--- a/src/hex-buffer-mmap.c
+++ b/src/hex-buffer-mmap.c
@@ -54,6 +54,16 @@ G_DEFINE_TYPE_WITH_CODE (HexBufferMmap, hex_buffer_mmap, G_TYPE_OBJECT,
 
 /* PRIVATE FUNCTIONS */
 
+static void
+clear_tmpfile_path (HexBufferMmap *self)
+{
+       if (! self->tmpfile_path)
+               return;
+
+       unlink (self->tmpfile_path);
+       g_clear_pointer (&self->tmpfile_path, g_free);
+}
+
 /* Helper wrapper for g_set_error and to cache errno */
 static void
 set_error (HexBufferMmap *self, const char *blurb)
@@ -117,9 +127,14 @@ hex_buffer_mmap_finalize (GObject *gobject)
        if (self->fd >= 0)
        {
                close (self->fd);
-               unlink (self->tmpfile_path);
+               /* this should happen previously, but it's harmless to run it again
+                * in finalize in case it didn't happen for some reason
+                */
+               clear_tmpfile_path (self);
        }
 
+       /* This will either be spuriously still allocated and non-null (highly
+        * unlikely or null, so safe to call this in any event. */
        g_free (self->tmpfile_path);
 
        /* chain up */
@@ -497,6 +512,7 @@ create_buffer (HexBufferMmap *self)
        self->tmpfile_path = g_strdup ("hexmmapbufXXXXXX");
        errno = 0;
        self->fd = mkstemp (self->tmpfile_path);
+       clear_tmpfile_path (self);
 
        if (self->fd < 0) {
                set_error (self, _("Failed to open temporary file."));


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