inotify: fix segfault on watching hard links

The call to _start() fills in the dirname, basename, and filename
arguments according to the following rules:

  dir watches: dirname filled

  file watches: dirname and basename filled

  hardlink: filename filled

This doesn't map to how the current inotify backend works very nicely,
so we need to adjust things a bit when creating our "sub" objects.

https://bugzilla.gnome.org/show_bug.cgi?id=755721
This commit is contained in:
Ryan Lortie 2015-09-29 16:48:29 -04:00 committed by Philip Withnall
parent ad50fdbd50
commit cc5cd5e8ea
3 changed files with 17 additions and 6 deletions

View File

@ -61,7 +61,7 @@ g_inotify_file_monitor_start (GLocalFileMonitor *local_monitor,
success = _ih_startup (); success = _ih_startup ();
g_assert (success); g_assert (success);
inotify_monitor->sub = _ih_sub_new (dirname, basename, filename != NULL, source); inotify_monitor->sub = _ih_sub_new (dirname, basename, filename, source);
_ih_sub_add (inotify_monitor->sub); _ih_sub_add (inotify_monitor->sub);
} }

View File

@ -44,16 +44,27 @@ dup_dirname (const gchar *dirname)
inotify_sub* inotify_sub*
_ih_sub_new (const gchar *dirname, _ih_sub_new (const gchar *dirname,
const gchar *basename,
const gchar *filename, const gchar *filename,
gboolean watch_hardlinks,
gpointer user_data) gpointer user_data)
{ {
inotify_sub *sub = NULL; inotify_sub *sub = NULL;
sub = g_new0 (inotify_sub, 1); sub = g_new0 (inotify_sub, 1);
sub->dirname = dup_dirname (dirname);
sub->filename = g_strdup (filename); if (filename)
sub->hardlinks = watch_hardlinks; {
sub->dirname = g_path_get_dirname (filename);
sub->filename = g_path_get_basename (filename);
sub->hardlinks = TRUE;
}
else
{
sub->dirname = dup_dirname (dirname);
sub->filename = g_strdup (basename);
sub->hardlinks = FALSE;
}
sub->user_data = user_data; sub->user_data = user_data;
IS_W ("new subscription for %s being setup\n", sub->dirname); IS_W ("new subscription for %s being setup\n", sub->dirname);

View File

@ -33,8 +33,8 @@ typedef struct
} inotify_sub; } inotify_sub;
inotify_sub *_ih_sub_new (const gchar *dirname, inotify_sub *_ih_sub_new (const gchar *dirname,
const gchar *basename,
const gchar *filename, const gchar *filename,
gboolean watch_hardlinks,
gpointer user_data); gpointer user_data);
void _ih_sub_free (inotify_sub *sub); void _ih_sub_free (inotify_sub *sub);