void watcher_destroy_monitors(const watcher_t *watcher) { GFileMonitor *monitor; gchar *path; GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, watcher->monitors); while (g_hash_table_iter_next(&iter, &key, &value)) { path = (gchar *) key; monitor = (GFileMonitor *) value; if (!g_file_monitor_is_cancelled(monitor)) { g_file_monitor_cancel(monitor); LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor cancelled"), path); } else { LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor already cancelled"), path); } g_free(path); g_object_unref(monitor); } g_hash_table_remove_all(watcher->monitors); }
static void ide_git_vcs_dispose (GObject *object) { IdeGitVcs *self = (IdeGitVcs *)object; IDE_ENTRY; if (self->changed_timeout) { g_source_remove (self->changed_timeout); self->changed_timeout = 0; } if (self->monitor) { if (!g_file_monitor_is_cancelled (self->monitor)) g_file_monitor_cancel (self->monitor); g_clear_object (&self->monitor); } g_clear_object (&self->change_monitor_repository); g_clear_object (&self->repository); g_clear_object (&self->working_directory); G_OBJECT_CLASS (ide_git_vcs_parent_class)->dispose (object); IDE_EXIT; }
void handle_signal(int signum) { struct slist_t *current, *next; /* Notify user */ #ifndef NDEBUG if (signum) { fprintf(stderr, "[WARNING] '%s' signal caught (code %i)\n", strsignal(signum), signum); } #endif /* Stop the main loop */ if (main_loop) { if (g_main_loop_is_running(main_loop)) { g_main_loop_quit(main_loop); } g_main_loop_unref(main_loop); } notify_uninit(); /* Cleanup the list */ current = list.tail; while (current) { #ifndef NDEBUG char *uri = g_file_get_uri(current->head->file), *state; if (!current->head->file_monitor) { state = "unknowned"; } else if (g_file_monitor_is_cancelled(current->head->file_monitor)) { state = "cancelled"; } else { state = "monitored"; } fprintf(stderr, "[ENTRY %p] '%s' (%s)\n", (void *)(current->head), uri, state); g_free(uri); #endif destroy(current->head); next = current->tail; free(current); current = next; } /* Re-throw termination signals */ if (sigismember(&signal_action.sa_mask, signum)) { sigemptyset(&signal_action.sa_mask); signal_action.sa_handler = SIG_DFL; sigaction(signum, &signal_action, NULL); raise(signum); } }
void watcher_remove_monitor_for_recursive_path(const watcher_t *watcher, const gchar *path) { GFile *w_file, *file; GFileMonitor *w_monitor; gchar *w_path; GHashTableIter iter; gpointer key, value; LOG_DEBUG("%s: %s (path=%s)", watcher->name, N_("removing file monitors for recursive path"), path); file = g_file_new_for_path(path); g_hash_table_iter_init(&iter, watcher->monitors); while (g_hash_table_iter_next(&iter, &key, &value)) { w_path = (gchar *) key; w_monitor = (GFileMonitor *) value; if (g_strcmp0(w_path, watcher->path) == 0) continue; w_file = g_file_new_for_path(w_path); if (g_file_equal(w_file, file) || g_file_has_prefix(w_file, file)) { if (!g_file_monitor_is_cancelled(w_monitor)) { g_file_monitor_cancel(w_monitor); LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor cancelled"), w_path); } else { LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor already cancelled"), w_path); } g_hash_table_iter_remove(&iter); g_object_unref(w_file); g_free(w_path); g_object_unref(w_monitor); } } g_object_unref(file); }
void watcher_remove_monitor_for_path(const watcher_t *watcher, const gchar *path) { GFileMonitor *w_monitor; gchar *w_path; GHashTableIter iter; gpointer key, value; LOG_DEBUG("%s: %s (path=%s)", watcher->name, N_("removing file monitor for path"), path); g_hash_table_iter_init(&iter, watcher->monitors); while (g_hash_table_iter_next(&iter, &key, &value)) { w_path = (gchar *) key; w_monitor = (GFileMonitor *) value; if (g_strcmp0(w_path, path) == 0) { if (!g_file_monitor_is_cancelled(w_monitor)) { g_file_monitor_cancel(w_monitor); LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor cancelled"), w_path); } else { LOG_DEBUG("%s: %s (%s)", watcher->name, N_("file monitor already cancelled"), w_path); } g_hash_table_iter_remove(&iter); g_free(w_path); g_object_unref(w_path); break; } } }
static void CALLBACK g_win32_directory_monitor_callback (DWORD error, DWORD nBytes, LPOVERLAPPED lpOverlapped) { gulong offset; PFILE_NOTIFY_INFORMATION pfile_notify_walker; glong file_name_len; gchar *file_name; gchar *path; GFile *file; GWin32DirectoryMonitorPrivate *priv = (GWin32DirectoryMonitorPrivate *) lpOverlapped; static GFileMonitorEvent events[] = { 0, G_FILE_MONITOR_EVENT_CREATED, /* FILE_ACTION_ADDED */ G_FILE_MONITOR_EVENT_DELETED, /* FILE_ACTION_REMOVED */ G_FILE_MONITOR_EVENT_CHANGED, /* FILE_ACTION_MODIFIED */ G_FILE_MONITOR_EVENT_DELETED, /* FILE_ACTION_RENAMED_OLD_NAME */ G_FILE_MONITOR_EVENT_CREATED, /* FILE_ACTION_RENAMED_NEW_NAME */ }; /* If priv->self is NULL the GWin32DirectoryMonitor object has been destroyed. */ if (priv->self == NULL || g_file_monitor_is_cancelled (priv->self) || priv->file_notify_buffer == NULL) { g_free (priv->file_notify_buffer); g_free (priv); return; } offset = 0; do { pfile_notify_walker = (PFILE_NOTIFY_INFORMATION)(priv->file_notify_buffer + offset); if (pfile_notify_walker->Action > 0) { file_name = g_utf16_to_utf8 (pfile_notify_walker->FileName, pfile_notify_walker->FileNameLength / sizeof(WCHAR), NULL, &file_name_len, NULL); path = g_build_filename(G_LOCAL_DIRECTORY_MONITOR (priv->self)->dirname, file_name, NULL); file = g_file_new_for_path (path); g_file_monitor_emit_event (priv->self, file, NULL, events [pfile_notify_walker->Action]); g_object_unref (file); g_free (path); g_free (file_name); } offset += pfile_notify_walker->NextEntryOffset; } while (pfile_notify_walker->NextEntryOffset); ReadDirectoryChangesW (priv->hDirectory, (gpointer)priv->file_notify_buffer, priv->buffer_allocated_bytes, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE, &priv->buffer_filled_bytes, &priv->overlapped, g_win32_directory_monitor_callback); }
/* This is the callback function for arriving signals from g_file_monitor. It shall create a Lisp event, and put it into Emacs input queue. */ static gboolean dir_monitor_callback (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { Lisp_Object symbol, monitor_object, watch_object, flags; char *name = g_file_get_parse_name (file); char *oname = other_file ? g_file_get_parse_name (other_file) : NULL; /* Determine event symbol. */ switch (event_type) { case G_FILE_MONITOR_EVENT_CHANGED: symbol = Qchanged; break; case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: symbol = Qchanges_done_hint; break; case G_FILE_MONITOR_EVENT_DELETED: symbol = Qdeleted; break; case G_FILE_MONITOR_EVENT_CREATED: symbol = Qcreated; break; case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: symbol = Qattribute_changed; break; case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: symbol = Qpre_unmount; break; case G_FILE_MONITOR_EVENT_UNMOUNTED: symbol = Qunmounted; break; case G_FILE_MONITOR_EVENT_MOVED: symbol = Qmoved; break; default: goto cleanup; } /* Determine callback function. */ monitor_object = make_pointer_integer (monitor); eassert (INTEGERP (monitor_object)); watch_object = assq_no_quit (monitor_object, watch_list); if (CONSP (watch_object)) { struct input_event event; Lisp_Object otail = oname ? list1 (build_string (oname)) : Qnil; /* Check, whether event_type is expected. */ flags = XCAR (XCDR (XCDR (watch_object))); if ((!NILP (Fmember (Qchange, flags)) && !NILP (Fmember (symbol, list5 (Qchanged, Qchanges_done_hint, Qdeleted, Qcreated, Qmoved)))) || (!NILP (Fmember (Qattribute_change, flags)) && ((EQ (symbol, Qattribute_changed))))) { /* Construct an event. */ EVENT_INIT (event); event.kind = FILE_NOTIFY_EVENT; event.frame_or_window = Qnil; event.arg = list2 (Fcons (monitor_object, Fcons (symbol, Fcons (build_string (name), otail))), XCAR (XCDR (XCDR (XCDR (watch_object))))); /* Store it into the input event queue. */ kbd_buffer_store_event (&event); // XD_DEBUG_MESSAGE ("%s", XD_OBJECT_TO_STRING (event.arg)); } /* Cancel monitor if file or directory is deleted. */ if (!NILP (Fmember (symbol, list2 (Qdeleted, Qmoved))) && !g_file_monitor_is_cancelled (monitor)) g_file_monitor_cancel (monitor); } /* Cleanup. */ cleanup: g_free (name); g_free (oname); return TRUE; }