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

📄 inotify-kernel.c

📁 this is a glib for c language
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (is_dir)    {      switch (mask)	{	case IN_ACCESS:	  return "ACCESS (dir)";	case IN_MODIFY:	  return "MODIFY (dir)";	case IN_ATTRIB:	  return "ATTRIB (dir)";	case IN_CLOSE_WRITE:	  return "CLOSE_WRITE (dir)";	case IN_CLOSE_NOWRITE:	  return "CLOSE_NOWRITE (dir)"; 	case IN_OPEN:	  return "OPEN (dir)";	case IN_MOVED_FROM:	  return "MOVED_FROM (dir)";	case IN_MOVED_TO:	  return "MOVED_TO (dir)";	case IN_DELETE:	  return "DELETE (dir)";	case IN_CREATE:	  return "CREATE (dir)";	case IN_DELETE_SELF:	  return "DELETE_SELF (dir)";	case IN_UNMOUNT:	  return "UNMOUNT (dir)";	case IN_Q_OVERFLOW:	  return "Q_OVERFLOW (dir)";	case IN_IGNORED:	  return "IGNORED (dir)";	default:	  return "UNKNOWN_EVENT (dir)";	}    }  else    {      switch (mask)	{	case IN_ACCESS:	  return "ACCESS";	case IN_MODIFY:	  return "MODIFY";	case IN_ATTRIB:	  return "ATTRIB";	case IN_CLOSE_WRITE:	  return "CLOSE_WRITE";	case IN_CLOSE_NOWRITE:	  return "CLOSE_NOWRITE";	case IN_OPEN:	  return "OPEN";	case IN_MOVED_FROM:	  return "MOVED_FROM";	case IN_MOVED_TO:	  return "MOVED_TO";	case IN_DELETE:	  return "DELETE";	case IN_CREATE:	  return "CREATE";	case IN_DELETE_SELF:	  return "DELETE_SELF";	case IN_UNMOUNT:	  return "UNMOUNT";	case IN_Q_OVERFLOW:	  return "Q_OVERFLOW";	case IN_IGNORED:	  return "IGNORED";	default:	  return "UNKNOWN_EVENT";	}    }}static voidik_read_events (gsize  *buffer_size_out,                 gchar **buffer_out){  static gchar *buffer = NULL;  static gsize buffer_size;    /* Initialize the buffer on our first call */  if (buffer == NULL)    {      buffer_size = AVERAGE_EVENT_SIZE;      buffer_size *= MAX_QUEUED_EVENTS;      buffer = g_malloc (buffer_size);    }  *buffer_size_out = 0;  *buffer_out = NULL;    memset (buffer, 0, buffer_size);  if (g_io_channel_read_chars (inotify_read_ioc, (char *)buffer, buffer_size, buffer_size_out, NULL) != G_IO_STATUS_NORMAL) {    /* error reading */  }  *buffer_out = buffer;}static gbooleanik_read_callback (gpointer user_data){  gchar *buffer;  gsize buffer_size, buffer_i, events;    G_LOCK (inotify_lock);  ik_read_events (&buffer_size, &buffer);    buffer_i = 0;  events = 0;  while (buffer_i < buffer_size)    {      struct inotify_event *event;      gsize event_size;      event = (struct inotify_event *)&buffer[buffer_i];      event_size = sizeof(struct inotify_event) + event->len;      g_queue_push_tail (events_to_process, ik_event_internal_new (ik_event_new (&buffer[buffer_i])));      buffer_i += event_size;      events++;    }    /* If the event process callback is off, turn it back on */  if (!process_eq_running && events)    {      process_eq_running = TRUE;      g_timeout_add (PROCESS_EVENTS_TIME, ik_process_eq_callback, NULL);    }    G_UNLOCK (inotify_lock);    return TRUE;}static gbooleang_timeval_lt (GTimeVal *val1,               GTimeVal *val2){  if (val1->tv_sec < val2->tv_sec)    return TRUE;    if (val1->tv_sec > val2->tv_sec)    return FALSE;    /* val1->tv_sec == val2->tv_sec */  if (val1->tv_usec < val2->tv_usec)    return TRUE;    return FALSE;}static gbooleang_timeval_eq (GTimeVal *val1,               GTimeVal *val2){  return (val1->tv_sec == val2->tv_sec) && (val1->tv_usec == val2->tv_usec);}static voidik_pair_events (ik_event_internal_t *event1,                 ik_event_internal_t *event2){  g_assert (event1 && event2);  /* We should only be pairing events that have the same cookie */  g_assert (event1->event->cookie == event2->event->cookie);  /* We shouldn't pair an event that already is paired */  g_assert (event1->pair == NULL && event2->pair == NULL);    /* Pair the internal structures and the ik_event_t structures */  event1->pair = event2;  event1->event->pair = event2->event;    if (g_timeval_lt (&event1->hold_until, &event2->hold_until))    event1->hold_until = event2->hold_until;    event2->hold_until = event1->hold_until;}static voidik_event_add_microseconds (ik_event_internal_t *event,                            glong                ms){  g_assert (event);  g_time_val_add (&event->hold_until, ms);}static gbooleanik_event_ready (ik_event_internal_t *event){  GTimeVal tv;  g_assert (event);    g_get_current_time (&tv);    /* An event is ready if,   *   * it has no cookie -- there is nothing to be gained by holding it   * or, it is already paired -- we don't need to hold it anymore   * or, we have held it long enough   */  return    event->event->cookie == 0 ||    event->pair != NULL ||    g_timeval_lt (&event->hold_until, &tv) ||    g_timeval_eq (&event->hold_until, &tv);}static voidik_pair_moves (gpointer data,                gpointer user_data){  ik_event_internal_t *event = (ik_event_internal_t *)data;    if (event->seen == TRUE || event->sent == TRUE)    return;    if (event->event->cookie != 0)    {      /* When we get a MOVED_FROM event we delay sending the event by       * MOVE_HOLD_UNTIL_TIME microseconds. We need to do this because a       * MOVED_TO pair _might_ be coming in the near future */      if (event->event->mask & IN_MOVED_FROM)	{	  g_hash_table_insert (cookie_hash, GINT_TO_POINTER (event->event->cookie), event);	  /* because we don't deliver move events there is no point in waiting for the match right now. */	  ik_event_add_microseconds (event, MOVE_HOLD_UNTIL_TIME);	}      else if (event->event->mask & IN_MOVED_TO)	{	  /* We need to check if we are waiting for this MOVED_TO events cookie to pair it with	   * a MOVED_FROM */	  ik_event_internal_t *match = NULL;	  match = g_hash_table_lookup (cookie_hash, GINT_TO_POINTER (event->event->cookie));	  if (match)	    {	      g_hash_table_remove (cookie_hash, GINT_TO_POINTER (event->event->cookie));	      ik_pair_events (match, event);	    }	}    }  event->seen = TRUE;}static voidik_process_events (void){  g_queue_foreach (events_to_process, ik_pair_moves, NULL);  while (!g_queue_is_empty (events_to_process))    {      ik_event_internal_t *event = g_queue_peek_head (events_to_process);            /* This must have been sent as part of a MOVED_TO/MOVED_FROM */      if (event->sent)	{	  /* Pop event */	  g_queue_pop_head (events_to_process);	  /* Free the internal event structure */	  g_free (event);	  continue;	}            /* The event isn't ready yet */      if (!ik_event_ready (event))	break;            /* Pop it */      event = g_queue_pop_head (events_to_process);            /* Check if this is a MOVED_FROM that is also sitting in the cookie_hash */      if (event->event->cookie && event->pair == NULL &&	  g_hash_table_lookup (cookie_hash, GINT_TO_POINTER (event->event->cookie)))	g_hash_table_remove (cookie_hash, GINT_TO_POINTER (event->event->cookie));            if (event->pair)	{	  /* We send out paired MOVED_FROM/MOVED_TO events in the same event buffer */	  /* g_assert (event->event->mask == IN_MOVED_FROM && event->pair->event->mask == IN_MOVED_TO); */	  /* Copy the paired data */	  event->pair->sent = TRUE;	  event->sent = TRUE;	  ik_move_matches++;	}      else if (event->event->cookie)	{	  /* If we couldn't pair a MOVED_FROM and MOVED_TO together, we change	   * the event masks */	  /* Changeing MOVED_FROM to DELETE and MOVED_TO to create lets us make	   * the gaurantee that you will never see a non-matched MOVE event */	  	  if (event->event->mask & IN_MOVED_FROM)	    {	      event->event->mask = IN_DELETE|(event->event->mask & IN_ISDIR);	      ik_move_misses++; /* not super accurate, if we aren't watching the destination it still counts as a miss */	    }	  if (event->event->mask & IN_MOVED_TO)	    event->event->mask = IN_CREATE|(event->event->mask & IN_ISDIR);	}            /* Push the ik_event_t onto the event queue */      g_queue_push_tail (event_queue, event->event);      /* Free the internal event structure */      g_free (event);    }}static gbooleanik_process_eq_callback (gpointer user_data){  gboolean res;    /* Try and move as many events to the event queue */  G_LOCK (inotify_lock);  ik_process_events ();    while (!g_queue_is_empty (event_queue))    {      ik_event_t *event = g_queue_pop_head (event_queue);            user_cb (event);    }  res = TRUE;    if (g_queue_get_length (events_to_process) == 0)    {      process_eq_running = FALSE;      res = FALSE;    }    G_UNLOCK (inotify_lock);    return res;}

⌨️ 快捷键说明

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