From dff5596f969ef4c46dc943c094642934c54bb179 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 25 Feb 2016 20:43:38 +0200 Subject: [PATCH] Automatically refresh the device list in manager mode --- main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/main.c b/main.c index 59bf305..5413548 100644 --- a/main.c +++ b/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,10 @@ typedef struct sGuiContext GtkWidget *list; GtkWidget *button; char *post_mount_command; + int inotify_fd; + int dev_wd; + GIOChannel *inotify_channel; + int refresh_pending; } GuiContext; int verbosity = 0; @@ -821,6 +826,19 @@ int refresh_devices(GuiContext *context, int umount) return n_listed; } +/** +Handles an automatic refresh of the device list in response to inotify events. +*/ +gboolean refresh_devices_idle(gpointer data) +{ + GuiContext *context = (GuiContext *)data; + + refresh_devices(context, -1); + context->refresh_pending = 0; + + return FALSE; +} + /** Callback for selection in the device list changing. Updates the action button label according to device status. @@ -945,6 +963,32 @@ gboolean key_press(GtkWidget *widget, GdkEvent *event, gpointer user_data) return FALSE; } +/** +Callback for inotify events. +*/ +gboolean inotify_event_available(GIOChannel *source, GIOCondition condition, gpointer user_data) +{ + GuiContext *context = (GuiContext *)user_data; + int fd; + char eventbuf[sizeof(struct inotify_event)+NAME_MAX+1]; + int len; + + fd = g_io_channel_unix_get_fd(source); + len = read(fd, eventbuf, sizeof(eventbuf)); + if(len>=(int)sizeof(struct inotify_event)) + { + if(!context->refresh_pending) + { + g_timeout_add(500, &refresh_devices_idle, context); + context->refresh_pending = 1; + } + } + + (void)condition; + + return TRUE; +} + void show_help(void) { printf("pmount-gui\n" @@ -974,6 +1018,10 @@ int main(int argc, char **argv) context.manager = 0; context.devices = NULL; context.post_mount_command = NULL; + context.inotify_fd = -1; + context.dev_wd = -1; + context.inotify_channel = NULL; + context.refresh_pending = 0; gtk_init(&argc, &argv); @@ -1034,6 +1082,19 @@ int main(int argc, char **argv) gtk_tree_view_column_add_attribute(mounted_column, mount_point_renderer, "text", 3); gtk_tree_view_insert_column(GTK_TREE_VIEW(context.list), mounted_column, -1); + + context.inotify_fd = inotify_init(); + if(context.inotify_fd>=0) + { + context.dev_wd = inotify_add_watch(context.inotify_fd, "/dev/disk/by-id", IN_CREATE|IN_DELETE); + + context.inotify_channel = g_io_channel_unix_new(context.inotify_fd); + g_io_add_watch(context.inotify_channel, G_IO_IN, &inotify_event_available, &context); + } + else + printf("Warning: Unable to initialize inotify\n"); + + umount = -1; } selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(context.list)); @@ -1061,6 +1122,8 @@ int main(int argc, char **argv) gtk_main(); free_devices(context.devices); + if(context.inotify_fd>=0) + close(context.inotify_fd); return 0; } -- 2.43.0