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

📄 inotify-kernel.c

📁 this is a glib for c language
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Copyright (C) 2005 John McCutchan   The Gnome Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public License as   published by the Free Software Foundation; either version 2 of the   License, or (at your option) any later version.   The Gnome 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   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with the Gnome Library; see the file COPYING.LIB.  If not,   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.   Authors:.		John McCutchan <john@johnmccutchan.com>*/#include "config.h"#include <stdio.h>#include <sys/ioctl.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <glib.h>#include "inotify-kernel.h"#include <sys/inotify.h>/* Timings for pairing MOVED_TO / MOVED_FROM events */#define PROCESS_EVENTS_TIME 1000 /* milliseconds (1 hz) */#define DEFAULT_HOLD_UNTIL_TIME 0 /* 0 millisecond */#define MOVE_HOLD_UNTIL_TIME 0 /* 0 milliseconds */static int inotify_instance_fd = -1;static GQueue *events_to_process = NULL;static GQueue *event_queue = NULL;static GHashTable * cookie_hash = NULL;static GIOChannel *inotify_read_ioc;static GPollFD ik_poll_fd;static gboolean ik_poll_fd_enabled = TRUE;static void (*user_cb)(ik_event_t *event);static gboolean ik_read_callback (gpointer user_data);static gboolean ik_process_eq_callback (gpointer user_data);static guint32 ik_move_matches = 0;static guint32 ik_move_misses = 0;static gboolean process_eq_running = FALSE;/* We use the lock from inotify-helper.c * * There are two places that we take this lock * * 1) In ik_read_callback * * 2) ik_process_eq_callback. * * * The rest of locking is taken care of in inotify-helper.c */G_LOCK_EXTERN (inotify_lock);typedef struct ik_event_internal {  ik_event_t *event;  gboolean seen;  gboolean sent;  GTimeVal hold_until;  struct ik_event_internal *pair;} ik_event_internal_t;/* In order to perform non-sleeping inotify event chunking we need * a custom GSource */static gbooleanik_source_prepare (GSource *source,		   gint    *timeout){  return FALSE;}static gbooleanik_source_timeout (gpointer data){  GSource *source = (GSource *)data;    /* Re-active the PollFD */  g_source_add_poll (source, &ik_poll_fd);  g_source_unref (source);  ik_poll_fd_enabled = TRUE;    return FALSE;}#define MAX_PENDING_COUNT 2#define PENDING_THRESHOLD(qsize) ((qsize) >> 1)#define PENDING_MARGINAL_COST(p) ((unsigned int)(1 << (p)))#define MAX_QUEUED_EVENTS 2048#define AVERAGE_EVENT_SIZE sizeof (struct inotify_event) + 16#define TIMEOUT_MILLISECONDS 10static gbooleanik_source_check (GSource *source){  static int prev_pending = 0, pending_count = 0;    /* We already disabled the PollFD or   * nothing to be read from inotify */  if (!ik_poll_fd_enabled || !(ik_poll_fd.revents & G_IO_IN))    return FALSE;  if (pending_count < MAX_PENDING_COUNT)    {      unsigned int pending;            if (ioctl (inotify_instance_fd, FIONREAD, &pending) == -1)	goto do_read;            pending /= AVERAGE_EVENT_SIZE;            /* Don't wait if the number of pending events is too close       * to the maximum queue size.       */      if (pending > PENDING_THRESHOLD (MAX_QUEUED_EVENTS))	goto do_read;            /* With each successive iteration, the minimum rate for       * further sleep doubles.        */      if (pending-prev_pending < PENDING_MARGINAL_COST (pending_count))	goto do_read;            prev_pending = pending;      pending_count++;            /* We are going to wait to read the events: */            /* Remove the PollFD from the source */      g_source_remove_poll (source, &ik_poll_fd);      /* To avoid threading issues we need to flag that we've done that */      ik_poll_fd_enabled = FALSE;      /* Set a timeout to re-add the PollFD to the source */      g_source_ref (source);      g_timeout_add (TIMEOUT_MILLISECONDS, ik_source_timeout, source);            return FALSE;    }do_read:  /* We are ready to read events from inotify */  prev_pending = 0;  pending_count = 0;    return TRUE;}static gbooleanik_source_dispatch (GSource     *source,		    GSourceFunc  callback,		    gpointer     user_data){  if (callback)    return callback (user_data);  return TRUE;}static GSourceFuncs ik_source_funcs ={  ik_source_prepare,  ik_source_check,  ik_source_dispatch,  NULL};gboolean _ik_startup (void (*cb)(ik_event_t *event)){  static gboolean initialized = FALSE;  GSource *source;    user_cb = cb;  /* Ignore multi-calls */  if (initialized)     return inotify_instance_fd >= 0;    initialized = TRUE;  inotify_instance_fd = inotify_init ();    if (inotify_instance_fd < 0)    return FALSE;  inotify_read_ioc = g_io_channel_unix_new (inotify_instance_fd);  ik_poll_fd.fd = inotify_instance_fd;  ik_poll_fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;  g_io_channel_set_encoding (inotify_read_ioc, NULL, NULL);  g_io_channel_set_flags (inotify_read_ioc, G_IO_FLAG_NONBLOCK, NULL);  source = g_source_new (&ik_source_funcs, sizeof (GSource));  g_source_add_poll (source, &ik_poll_fd);  g_source_set_callback (source, ik_read_callback, NULL, NULL);  g_source_attach (source, NULL);  g_source_unref (source);  cookie_hash = g_hash_table_new (g_direct_hash, g_direct_equal);  event_queue = g_queue_new ();  events_to_process = g_queue_new ();    return TRUE;}static ik_event_internal_t *ik_event_internal_new (ik_event_t *event){  ik_event_internal_t *internal_event = g_new0 (ik_event_internal_t, 1);  GTimeVal tv;    g_assert (event);    g_get_current_time (&tv);  g_time_val_add (&tv, DEFAULT_HOLD_UNTIL_TIME);  internal_event->event = event;  internal_event->hold_until = tv;    return internal_event;}static ik_event_t *ik_event_new (char *buffer){  struct inotify_event *kevent = (struct inotify_event *)buffer;  ik_event_t *event = g_new0 (ik_event_t, 1);    g_assert (buffer);    event->wd = kevent->wd;  event->mask = kevent->mask;  event->cookie = kevent->cookie;  event->len = kevent->len;  if (event->len)    event->name = g_strdup (kevent->name);  else    event->name = g_strdup ("");    return event;}ik_event_t *_ik_event_new_dummy (const char *name,                      gint32      wd,                      guint32     mask){  ik_event_t *event = g_new0 (ik_event_t, 1);  event->wd = wd;  event->mask = mask;  event->cookie = 0;  if (name)    event->name = g_strdup (name);  else    event->name = g_strdup("");    event->len = strlen (event->name);    return event;}void_ik_event_free (ik_event_t *event){  if (event->pair)    _ik_event_free (event->pair);  g_free (event->name);  g_free (event);}gint32_ik_watch (const char *path,            guint32     mask,            int        *err){  gint32 wd = -1;    g_assert (path != NULL);  g_assert (inotify_instance_fd >= 0);    wd = inotify_add_watch (inotify_instance_fd, path, mask);    if (wd < 0)    {      int e = errno;      /* FIXME: debug msg failed to add watch */      if (err)	*err = e;      return wd;    }    g_assert (wd >= 0);  return wd;}int_ik_ignore (const char *path,             gint32      wd){  g_assert (wd >= 0);  g_assert (inotify_instance_fd >= 0);    if (inotify_rm_watch (inotify_instance_fd, wd) < 0)    {      /* int e = errno; */      /* failed to rm watch */      return -1;    }    return 0;}void_ik_move_stats (guint32 *matches,                 guint32 *misses){  if (matches)    *matches = ik_move_matches;    if (misses)    *misses = ik_move_misses;}const char *_ik_mask_to_string (guint32 mask){  gboolean is_dir = mask & IN_ISDIR;  mask &= ~IN_ISDIR;

⌨️ 快捷键说明

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