Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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);
	}
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #7
0
/* 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;
}