⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fam-helper.c

📁 this is a glib for c language
💻 C
字号:
/* GIO - GLib Input, Output and Streaming Library *  * Copyright (C) 2006-2007 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Alexander Larsson <alexl@redhat.com> *          John McCutchan <john@johnmccutchan.com>  *          Sebastian Dröge <slomo@circular-chaos.org> */#include "config.h"#include <fam.h>#include <gio/gfilemonitor.h>#include "gfile.h"#include "fam-helper.h"static FAMConnection* fam_connection = NULL;static gint fam_watch_id = 0;G_LOCK_DEFINE_STATIC(fam_connection);struct _fam_sub{  gchar *pathname;  gboolean directory;  gpointer user_data;  gboolean cancelled;  FAMRequest request;};/* This uses int as the argument type because the   real type differs between implementations:   gamin has "typedef enum FAMCodes {....} FAMCodes;"   fam has "enum FAMCodes { ... }".*/static GFileMonitorEvent  fam_event_to_file_monitor_event (int code){  switch (code)    {    case FAMChanged:      return G_FILE_MONITOR_EVENT_CHANGED;      break;    case FAMDeleted:      return G_FILE_MONITOR_EVENT_DELETED;      break;    case FAMCreated:      return G_FILE_MONITOR_EVENT_CREATED;      break;    default:      return -1;      break;    }}static gbooleanfam_do_iter_unlocked (void){  while (fam_connection != NULL && FAMPending (fam_connection)) {    FAMEvent ev;    fam_sub* sub = NULL;    gboolean cancelled;        if (FAMNextEvent (fam_connection, &ev) != 1) {      FAMClose (fam_connection);      g_free (fam_connection);      g_source_remove (fam_watch_id);      fam_watch_id = 0;      fam_connection = NULL;      return FALSE;    }        sub = (fam_sub*)ev.userdata;    cancelled = sub->cancelled;    if (ev.code == FAMAcknowledge && cancelled)      {	_fam_sub_free (sub);	continue;      }        if (cancelled)      continue;        if (sub->directory)      {	GFileMonitor* monitor = G_FILE_MONITOR (sub->user_data);	GFileMonitorEvent eflags = fam_event_to_file_monitor_event (ev.code);	gchar* path = NULL;	GFile *child, *parent;		/* unsupported event */	if (eflags == -1)	  continue;		if (ev.filename[0] == '/')	  path = g_strdup (ev.filename);	else	  path = g_strdup_printf ("%s/%s", sub->pathname, ev.filename);	child = g_file_new_for_path (path);	parent = g_file_get_parent (child);	g_file_monitor_emit_event (monitor, child, NULL, eflags);	g_free (path);	g_object_unref (child);	g_object_unref (parent);      } else {	GFile *child;	GFileMonitor* monitor = G_FILE_MONITOR (sub->user_data);	GFileMonitorEvent eflags = fam_event_to_file_monitor_event (ev.code);	gchar* path = NULL;      	if (eflags == -1)	  continue;	path = g_strdup (ev.filename);	child = g_file_new_for_path (path);	g_file_monitor_emit_event (monitor, child, NULL, eflags);	g_free (path);	g_object_unref (child);      }  }    return TRUE;}static gbooleanfam_callback (GIOChannel *source,              GIOCondition condition,              gpointer data){  gboolean res;  G_LOCK (fam_connection);    res = fam_do_iter_unlocked ();    G_UNLOCK (fam_connection);  return res;}gboolean_fam_sub_startup (void){  GIOChannel *ioc;    G_LOCK (fam_connection);    if (fam_connection == NULL) {    fam_connection = g_new0 (FAMConnection, 1);    if (FAMOpen2 (fam_connection, "gvfs user") != 0) {      g_warning ("FAMOpen failed, FAMErrno=%d\n", FAMErrno);      g_free (fam_connection);      fam_connection = NULL;      G_UNLOCK (fam_connection);      return FALSE;    }#ifdef HAVE_FAM_NO_EXISTS    /* This is a gamin extension that avoids sending all the Exists event for dir monitors */    FAMNoExists (fam_connection);#endif    ioc = g_io_channel_unix_new (FAMCONNECTION_GETFD(fam_connection));    fam_watch_id = g_io_add_watch (ioc,				   G_IO_IN | G_IO_HUP | G_IO_ERR,				   fam_callback, fam_connection);    g_io_channel_unref (ioc);  }    G_UNLOCK (fam_connection);    return TRUE;}void_fam_sub_shutdown (void){  G_LOCK (fam_connection);  if (fam_connection != NULL) {    FAMClose (fam_connection);    g_free (fam_connection);    g_source_remove (fam_watch_id);    fam_watch_id = 0;    fam_connection = NULL;  }  G_UNLOCK (fam_connection);}fam_sub*_fam_sub_add (const gchar* pathname,	      gboolean directory,	      gpointer user_data){  fam_sub *sub;  if (!_fam_sub_startup ())    return NULL;    G_LOCK (fam_connection);  /* We need to queue up incoming messages to avoid blocking on write   *  if there are many monitors being canceled */  fam_do_iter_unlocked ();    if (fam_connection == NULL) {    G_UNLOCK (fam_connection);    return NULL;  }    sub = g_new0 (fam_sub, 1);  sub->pathname = g_strdup (pathname);  sub->directory = directory;  sub->user_data = user_data;    if (directory)    FAMMonitorDirectory (fam_connection, pathname, &sub->request, sub);  else    FAMMonitorFile (fam_connection, pathname, &sub->request, sub);    G_UNLOCK (fam_connection);  return sub;}gboolean_fam_sub_cancel (fam_sub* sub){  if (sub->cancelled)    return TRUE;    sub->cancelled = TRUE;    G_LOCK (fam_connection);  /* We need to queue up incoming messages to avoid blocking on write   *  if there are many monitors being canceled */  fam_do_iter_unlocked ();    if (fam_connection == NULL) {    G_UNLOCK (fam_connection);    return FALSE;  }    FAMCancelMonitor (fam_connection, &sub->request);    G_UNLOCK (fam_connection);    return TRUE;}void_fam_sub_free (fam_sub* sub){  g_free (sub->pathname);  g_free (sub);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -