Exemplo n.º 1
0
/**
 * g_cancellable_connect:
 * @cancellable: A #GCancellable.
 * @callback: The #GCallback to connect.
 * @data: Data to pass to @callback.
 * @data_destroy_func: Free function for @data or %NULL.
 *
 * Convenience function to connect to the #GCancellable::cancelled
 * signal. Also handles the race condition that may happen
 * if the cancellable is cancelled right before connecting.
 *
 * @callback is called at most once, either directly at the
 * time of the connect if @cancellable is already cancelled,
 * or when @cancellable is cancelled in some thread.
 *
 * @data_destroy_func will be called when the handler is
 * disconnected, or immediately if the cancellable is already
 * cancelled.
 *
 * See #GCancellable::cancelled for details on how to use this.
 *
 * Returns: The id of the signal handler or 0 if @cancellable has already
 *          been cancelled.
 *
 * Since: 2.22
 */
gulong
g_cancellable_connect (GCancellable   *cancellable,
		       GCallback       callback,
		       gpointer        data,
		       GDestroyNotify  data_destroy_func)
{
  gulong id;

  g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), 0);

  G_LOCK (cancellable);

  if (cancellable->priv->cancelled)
    {
      void (*_callback) (GCancellable *cancellable,
                         gpointer      user_data);

      _callback = (void *)callback;
      id = 0;

      _callback (cancellable, data);

      if (data_destroy_func)
        data_destroy_func (data);
    }
  else
    {
      id = g_signal_connect_data (cancellable, "cancelled",
                                  callback, data,
                                  (GClosureNotify) data_destroy_func,
                                  0);
    }
  G_UNLOCK (cancellable);

  return id;
}
Exemplo n.º 2
0
void
g_slist_free (GSList *list)
{
  if (list)
    {
      GSList *last_node = list;
  
#ifdef ENABLE_GC_FRIENDLY
      while (last_node->next)
	{
	  last_node->data = NULL;
	  last_node = last_node->next;
	}
      last_node->data = NULL;
#else /* !ENABLE_GC_FRIENDLY */
      list->data = list->next;  
#endif /* ENABLE_GC_FRIENDLY */
	
      G_LOCK (current_allocator);
      last_node->next = current_allocator->free_lists;
      current_allocator->free_lists = list;
      G_UNLOCK (current_allocator);
    }
}
Exemplo n.º 3
0
static void
g_hash_node_destroy (GHashNode      *hash_node,
             GDestroyNotify  key_destroy_func,
             GDestroyNotify  value_destroy_func)
{
  if (key_destroy_func)
    key_destroy_func (hash_node->key);
  if (value_destroy_func)
    value_destroy_func (hash_node->value);
  
#ifdef ENABLE_GC_FRIENDLY
  hash_node->key = NULL;
  hash_node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */

#ifdef DISABLE_MEM_POOLS
  g_free (hash_node);
#else
  G_LOCK (g_hash_global);
  hash_node->next = node_free_list;
  node_free_list = hash_node;
  G_UNLOCK (g_hash_global);
#endif
}
Exemplo n.º 4
0
Arquivo: app.c Projeto: GnLWeB/balde
BALDE_API void
balde_app_add_url_rule(balde_app_t *app, const gchar *endpoint, const gchar *rule,
    const balde_http_method_t method, balde_view_func_t view_func)
{
    BALDE_APP_READ_ONLY(app);
    GError *tmp_error = NULL;
    balde_view_t *view = g_new(balde_view_t, 1);
    view->url_rule = g_new(balde_url_rule_t, 1);
    view->url_rule->endpoint = endpoint;
    view->url_rule->rule = rule;
    view->url_rule->match = balde_parse_url_rule(view->url_rule->rule, &tmp_error);
    if (tmp_error != NULL) {
        g_propagate_error(&(app->error), tmp_error);
        balde_app_free_views(view);
        return;
    }
    view->url_rule->method = method | BALDE_HTTP_OPTIONS;
    if (view->url_rule->method & BALDE_HTTP_GET)
        view->url_rule->method |= BALDE_HTTP_HEAD;
    view->view_func = view_func;
    G_LOCK(views);
    app->priv->views = g_slist_append(app->priv->views, view);
    G_UNLOCK(views);
}
Exemplo n.º 5
0
/**
 * g_io_scheduler_cancel_all_jobs:
 * 
 * Cancels all cancellable I/O jobs. 
 *
 * A job is cancellable if a #GCancellable was passed into
 * g_io_scheduler_push_job().
 **/
void
g_io_scheduler_cancel_all_jobs (void)
{
  GSList *cancellable_list, *l;
  
  G_LOCK (active_jobs);
  cancellable_list = NULL;
  for (l = active_jobs; l != NULL; l = l->next)
    {
      GIOSchedulerJob *job = l->data;
      if (job->cancellable)
	cancellable_list = g_slist_prepend (cancellable_list,
					    g_object_ref (job->cancellable));
    }
  G_UNLOCK (active_jobs);

  for (l = cancellable_list; l != NULL; l = l->next)
    {
      GCancellable *c = l->data;
      g_cancellable_cancel (c);
      g_object_unref (c);
    }
  g_slist_free (cancellable_list);
}
Exemplo n.º 6
0
static void
g_hash_node_destroy (MonoGHashNode      *hash_node,
		     MonoGHashGCType type,
		     GDestroyNotify  key_destroy_func,
		     GDestroyNotify  value_destroy_func)
{
  if (key_destroy_func)
    key_destroy_func (hash_node->key);
  if (value_destroy_func)
    value_destroy_func (hash_node->value);
  
  hash_node->key = NULL;
  hash_node->value = NULL;

  G_LOCK (g_hash_global);
#if defined(HAVE_SGEN_GC) || defined(HAVE_BOEHM_GC)
  hash_node->next = node_free_lists [type];
  node_free_lists [type] = hash_node;
#else
  hash_node->next = node_free_list;
  node_free_list = hash_node;
#endif
  G_UNLOCK (g_hash_global);
}
Exemplo n.º 7
0
/**
 * g_io_scheduler_push_job:
 * @job_func: a #GIOSchedulerJobFunc.
 * @user_data: data to pass to @job_func
 * @notify: (allow-none): a #GDestroyNotify for @user_data, or %NULL
 * @io_priority: the [I/O priority][io-priority]
 * of the request.
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 *
 * Schedules the I/O job to run in another thread.
 *
 * @notify will be called on @user_data after @job_func has returned,
 * regardless whether the job was cancelled or has run to completion.
 * 
 * If @cancellable is not %NULL, it can be used to cancel the I/O job
 * by calling g_cancellable_cancel() or by calling 
 * g_io_scheduler_cancel_all_jobs().
 *
 * Deprecated: use #GThreadPool or g_task_run_in_thread()
 **/
void
g_io_scheduler_push_job (GIOSchedulerJobFunc  job_func,
			 gpointer             user_data,
			 GDestroyNotify       notify,
			 gint                 io_priority,
			 GCancellable        *cancellable)
{
  GIOSchedulerJob *job;
  GTask *task;

  g_return_if_fail (job_func != NULL);

  job = g_slice_new0 (GIOSchedulerJob);
  job->job_func = job_func;
  job->data = user_data;
  job->destroy_notify = notify;

  if (cancellable)
    job->cancellable = g_object_ref (cancellable);

  job->context = g_main_context_ref_thread_default ();

  G_LOCK (active_jobs);
  active_jobs = g_list_prepend (active_jobs, job);
  job->active_link = active_jobs;
  G_UNLOCK (active_jobs);

  task = g_task_new (NULL, cancellable, NULL, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  g_task_set_source_tag (task, g_io_scheduler_push_job);
G_GNUC_END_IGNORE_DEPRECATIONS
  g_task_set_task_data (task, job, (GDestroyNotify)g_io_job_free);
  g_task_set_priority (task, io_priority);
  g_task_run_in_thread (task, io_job_thread);
  g_object_unref (task);
}
Exemplo n.º 8
0
static gboolean
gst_object_set_name_default (GstObject * object)
{
  const gchar *type_name;
  gint count;
  gchar *name, *tmp;
  gboolean result;
  GQuark q;

  /* to ensure guaranteed uniqueness across threads, only one thread
   * may ever assign a name */
  G_LOCK (object_name_mutex);

  if (!object_name_counts) {
    g_datalist_init (&object_name_counts);
  }

  q = g_type_qname (G_OBJECT_TYPE (object));
  count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q));
  g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1));

  G_UNLOCK (object_name_mutex);

  /* GstFooSink -> foosinkN */
  type_name = g_quark_to_string (q);
  if (strncmp (type_name, "Gst", 3) == 0)
    type_name += 3;
  tmp = g_strdup_printf ("%s%d", type_name, count);
  name = g_ascii_strdown (tmp, -1);
  g_free (tmp);

  result = gst_object_set_name (object, name);
  g_free (name);

  return result;
}
Exemplo n.º 9
0
static void
context_rule_removed (ERuleContext *ctx,
                      EFilterRule *rule)
{
	gpointer key, folder = NULL;

	d(printf("rule removed; %s\n", rule->name));

	/* TODO: remove from folder info cache? */

	G_LOCK (vfolder);
	if (g_hash_table_lookup_extended (vfolder_hash, rule->name, &key, &folder)) {
		g_hash_table_remove (vfolder_hash, key);
		g_free (key);
	}
	G_UNLOCK (vfolder);

	/* FIXME Not passing a GCancellable  or GError. */
	camel_store_delete_folder_sync (
		vfolder_store, rule->name, NULL, NULL);
	/* this must be unref'd after its deleted */
	if (folder)
		g_object_unref ((CamelFolder *) folder);
}
Exemplo n.º 10
0
static void
sendrecv_answerer_fakesink_hand_off (GstElement * fakesink, GstBuffer * buf,
    GstPad * pad, gpointer data)
{
  HandOffData *hod = (HandOffData *) data;
  GstElement *pipeline;

  check_caps (pad, hod);

  pipeline = GST_ELEMENT (gst_element_get_parent (fakesink));

  G_LOCK (check_receive_lock);
  if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pipeline),
              OFFERER_RECEIVES_AUDIO))) {
    g_object_set (G_OBJECT (fakesink), "signal-handoffs", FALSE, NULL);
    g_idle_add (quit_main_loop_idle, hod->loop);
  } else {
    g_object_set_data (G_OBJECT (pipeline), ANSWERER_RECEIVES_AUDIO,
        GINT_TO_POINTER (TRUE));
  }
  G_UNLOCK (check_receive_lock);

  g_object_unref (pipeline);
}
Exemplo n.º 11
0
/**
 * g_datalist_remove_data:
 * @dl: a datalist.
 * @k: the string identifying the data element.
 *
 * Removes an element using its string identifier. The data element's
 * destroy function is called if it has been set.
 **/
void
g_datalist_id_set_data_full (GData	  **datalist,
                             GQuark         key_id,
                             gpointer       data,
                             GDestroyNotify destroy_func)
{
    g_return_if_fail (datalist != NULL);
    if (!data)
        g_return_if_fail (destroy_func == NULL);
    if (!key_id)
    {
        if (data)
            g_return_if_fail (key_id > 0);
        else
            return;
    }

    G_LOCK (g_dataset_global);
    if (!g_dataset_location_ht)
        g_data_initialize ();

    g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
    G_UNLOCK (g_dataset_global);
}
Exemplo n.º 12
0
/**
 * fen_init:
 * 
 * FEN subsystem initializing.
 */
gboolean
fen_init ()
{
    static gboolean initialized = FALSE;
    static gboolean result = FALSE;

    G_LOCK (fen_lock);
    if (initialized) {
        G_UNLOCK (fen_lock);
        return result;
    }

    result = node_class_init();

    if (!result) {
        G_UNLOCK (fen_lock);
        return result;
    }

    initialized = TRUE;

    G_UNLOCK (fen_lock);
    return result;
}
static void
remove_client (Client * client)
{
  g_print ("Removing connection %s\n", client->name);

  g_free (client->name);

  if (client->isource) {
    g_source_destroy (client->isource);
    g_source_unref (client->isource);
  }
  if (client->tosource) {
    g_source_destroy (client->tosource);
    g_source_unref (client->tosource);
  }
  g_object_unref (client->connection);
  g_byte_array_unref (client->current_message);

  G_LOCK (clients);
  clients = g_list_remove (clients, client);
  G_UNLOCK (clients);

  g_slice_free (Client, client);
}
Exemplo n.º 14
0
/**
 * pka_manager_find_plugin:
 * @context: A #PkaContext.
 * @plugin_id: The plugin identifier.
 * @plugin: A location for a #PkaPlugin.
 * @error: A location for a #GError, or %NULL.
 *
 * Finds the plugin matching the requested @plugin_id.  If the context
 * does not have permissions, this operation will fail.
 *
 * If successful, the plugin instance is stored in @plugin.  The caller
 * owns a reference to this plugin and should free it with g_object_unref().
 *
 * Returns: %TRUE if successful; otherwise %FALSE.
 * Side effects: None.
 */
gboolean
pka_manager_find_plugin (PkaContext       *context,   /* IN */
                         const gchar      *plugin_id, /* IN */
                         PkaPlugin       **plugin,    /* OUT */
                         GError          **error)     /* OUT */
{
	PkaPlugin *iter;
	gint i;

	g_return_val_if_fail(context != NULL, FALSE);
	g_return_val_if_fail(plugin != NULL, FALSE);

	ENTRY;
	*plugin = NULL;
	if (!plugin_id) {
		GOTO(failed);
	}
	G_LOCK(plugins);
	for (i = 0; i < manager.plugins->len; i++) {
		iter = g_ptr_array_index(manager.plugins, i);
		if (g_str_equal(pka_plugin_get_id(iter), plugin_id)) {
			/*
			 * TODO: Verify permissions.
			 */
			*plugin = g_object_ref(iter);
			BREAK;
		}
	}
	G_UNLOCK(plugins);
  failed:
  	if (!*plugin) {
  		g_set_error(error, PKA_PLUGIN_ERROR, PKA_PLUGIN_ERROR_INVALID_TYPE,
  		            "The specified plugin could not be found.");
	}
	RETURN(*plugin != NULL);
}
Exemplo n.º 15
0
static void
pad_added_cb (GstElement * element, GstPad * pad, gpointer data)
{
    GstElement *pipeline = GST_ELEMENT (data);
    GstElement *wavenc, *sink;
    GstPadLinkReturn ret;
    GstPad *sinkpad;
    gchar *msg;

    if (gst_pad_get_direction (pad) != GST_PAD_SRC)
        return;

    wavenc = gst_element_factory_make ("wavenc", NULL);

#ifdef MANUAL_CHECK
    {
        gchar *filename;

        G_LOCK (mutex);
        filename = g_strdup_printf ("file_%u.wv", id++);
        GST_DEBUG ("Creating file %s", filename);
        G_UNLOCK (mutex);

        sink = gst_element_factory_make ("filesink", NULL);
        g_object_set (G_OBJECT (sink), "location", filename, NULL);
        g_free (filename);
    }
#else
    {
        sink = gst_element_factory_make ("fakesink", NULL);
    }
#endif

    g_object_set (G_OBJECT (sink), "sync", FALSE, "async", FALSE, NULL);

    gst_bin_add_many (GST_BIN (pipeline), wavenc, sink, NULL);
    sinkpad = gst_element_get_static_pad (wavenc, "sink");

    if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
        msg = g_strdup_printf ("Can not link pads (%d)", ret);
        gst_object_unref (sinkpad);
        goto failed;
    }

    gst_object_unref (sinkpad);

    if (!gst_element_link (wavenc, sink)) {
        msg = g_strdup_printf ("Can not link elements");
        goto failed;
    }

    sinkpad = gst_element_get_static_pad (sink, "sink");
    gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe_cb, NULL,
                       NULL);
    gst_object_unref (sinkpad);

    gst_element_sync_state_with_parent (wavenc);
    gst_element_sync_state_with_parent (sink);

    G_LOCK (hash_mutex);
    g_hash_table_insert (hash, GST_OBJECT_NAME (pad), wavenc);
    G_UNLOCK (hash_mutex);

    return;

failed:

    gst_element_set_state (wavenc, GST_STATE_NULL);
    gst_element_set_state (sink, GST_STATE_NULL);
    gst_bin_remove_many (GST_BIN (pipeline), wavenc, sink, NULL);

    GST_ERROR ("Error %s", msg);
    fail (msg);
    g_free (msg);

    g_idle_add ((GSourceFunc) quit_main_loop, NULL);
}
Exemplo n.º 16
0
/**
 * g_dbus_error_encode_gerror:
 * @error: A #GError.
 *
 * Creates a D-Bus error name to use for @error. If @error matches
 * a registered error (cf. g_dbus_error_register_error()), the corresponding
 * D-Bus error name will be returned.
 *
 * Otherwise the a name of the form
 * `org.gtk.GDBus.UnmappedGError.Quark._ESCAPED_QUARK_NAME.Code_ERROR_CODE`
 * will be used. This allows other GDBus applications to map the error
 * on the wire back to a #GError using g_dbus_error_new_for_dbus_error().
 *
 * This function is typically only used in object mappings to put a
 * #GError on the wire. Regular applications should not use it.
 *
 * Returns: A D-Bus error name (never %NULL). Free with g_free().
 *
 * Since: 2.26
 */
gchar *
g_dbus_error_encode_gerror (const GError *error)
{
  RegisteredError *re;
  gchar *error_name;

  g_return_val_if_fail (error != NULL, NULL);

  /* Ensure that e.g. G_DBUS_ERROR is registered using g_dbus_error_register_error() */
  _g_dbus_initialize ();

  error_name = NULL;

  G_LOCK (error_lock);
  re = NULL;
  if (quark_code_pair_to_re != NULL)
    {
      QuarkCodePair pair;
      pair.error_domain = error->domain;
      pair.error_code = error->code;
      g_assert (dbus_error_name_to_re != NULL); /* check invariant */
      re = g_hash_table_lookup (quark_code_pair_to_re, &pair);
    }
  if (re != NULL)
    {
      error_name = g_strdup (re->dbus_error_name);
      G_UNLOCK (error_lock);
    }
  else
    {
      const gchar *domain_as_string;
      GString *s;
      guint n;

      G_UNLOCK (error_lock);

      /* We can't make a lot of assumptions about what domain_as_string
       * looks like and D-Bus is extremely picky about error names so
       * hex-encode it for transport across the wire.
       */
      domain_as_string = g_quark_to_string (error->domain);

      /* 0 is not a domain; neither are non-quark integers */
      g_return_val_if_fail (domain_as_string != NULL, NULL);

      s = g_string_new ("org.gtk.GDBus.UnmappedGError.Quark._");
      for (n = 0; domain_as_string[n] != 0; n++)
        {
          gint c = domain_as_string[n];
          if (g_ascii_isalnum (c))
            {
              g_string_append_c (s, c);
            }
          else
            {
              guint nibble_top;
              guint nibble_bottom;
              g_string_append_c (s, '_');
              nibble_top = ((int) domain_as_string[n]) >> 4;
              nibble_bottom = ((int) domain_as_string[n]) & 0x0f;
              if (nibble_top < 10)
                nibble_top += '0';
              else
                nibble_top += 'a' - 10;
              if (nibble_bottom < 10)
                nibble_bottom += '0';
              else
                nibble_bottom += 'a' - 10;
              g_string_append_c (s, nibble_top);
              g_string_append_c (s, nibble_bottom);
            }
        }
      g_string_append_printf (s, ".Code%d", error->code);
      error_name = g_string_free (s, FALSE);
    }

  return error_name;
}
Exemplo n.º 17
0
/* HOLDS: g_dataset_global_lock */
static inline gpointer
g_data_set_internal (GData	  **datalist,
		     GQuark         key_id,
		     gpointer       data,
		     GDestroyNotify destroy_func,
		     GDataset	   *dataset)
{
  register GData *list;
  
  list = G_DATALIST_GET_POINTER (datalist);
  if (!data)
    {
      register GData *prev;
      
      prev = NULL;
      while (list)
	{
	  if (list->id == key_id)
	    {
	      gpointer ret_data = NULL;

	      if (prev)
		prev->next = list->next;
	      else
		{
		  G_DATALIST_SET_POINTER (datalist, list->next);
		  
		  /* the dataset destruction *must* be done
		   * prior to invocation of the data destroy function
		   */
		  if (!list->next && dataset)
		    g_dataset_destroy_internal (dataset);
		}
	      
	      /* the GData struct *must* already be unlinked
	       * when invoking the destroy function.
	       * we use (data==NULL && destroy_func!=NULL) as
	       * a special hint combination to "steal"
	       * data without destroy notification
	       */
	      if (list->destroy_func && !destroy_func)
		{
		  G_UNLOCK (g_dataset_global);
		  list->destroy_func (list->data);
		  G_LOCK (g_dataset_global);
		}
	      else
		ret_data = list->data;
	      
              g_slice_free (GData, list);
	      
	      return ret_data;
	    }
	  
	  prev = list;
	  list = list->next;
	}
    }
  else
    {
      while (list)
	{
	  if (list->id == key_id)
	    {
	      if (!list->destroy_func)
		{
		  list->data = data;
		  list->destroy_func = destroy_func;
		}
	      else
		{
		  register GDestroyNotify dfunc;
		  register gpointer ddata;
		  
		  dfunc = list->destroy_func;
		  ddata = list->data;
		  list->data = data;
		  list->destroy_func = destroy_func;
		  
		  /* we need to have updated all structures prior to
		   * invocation of the destroy function
		   */
		  G_UNLOCK (g_dataset_global);
		  dfunc (ddata);
		  G_LOCK (g_dataset_global);
		}
	      
	      return NULL;
	    }
	  
	  list = list->next;
	}
      
      list = g_slice_new (GData);
      list->next = G_DATALIST_GET_POINTER (datalist);
      list->id = key_id;
      list->data = data;
      list->destroy_func = destroy_func;
      G_DATALIST_SET_POINTER (datalist, list);
    }

  return NULL;
}
Exemplo n.º 18
0
/**
 * mate_vfs_resolve:
 * @hostname: hostname you want to resolve.
 * @handle: pointer to a pointer to a #MateVFSResolveHandle.
 *
 * Tries to resolve @hostname. If the operation was successful you can
 * get the resolved addresses in form of #MateVFSAddress by calling
 * mate_vfs_resolve_next_address().
 * 
 * Return value: A #MateVFSResult indicating the success of the operation.
 *
 * Since: 2.8
 */
MateVFSResult
mate_vfs_resolve (const char              *hostname,
			    MateVFSResolveHandle  **handle)
{
#ifdef HAVE_GETADDRINFO
	   struct addrinfo hints, *result;
	   int res;
	   gboolean retry = TRUE;

restart:	   
	   memset (&hints, 0, sizeof (hints));
	   hints.ai_socktype = SOCK_STREAM;

#ifdef ENABLE_IPV6
# ifdef HAVE_AI_ADDRCONFIG /* RFC3493 */
	   hints.ai_flags = AI_ADDRCONFIG;
	   hints.ai_family = AF_UNSPEC;
# else	
	   hints.ai_family = AF_UNSPEC;
# endif	
#else
	   hints.ai_family = AF_INET;
#endif /* ENABLE_IPV6 */
	   res = getaddrinfo (hostname, NULL, &hints, &result);
	   
	   if (res != 0) {
			 if (retry && restart_resolve ()) {
				    retry = FALSE;
				    goto restart;
			 } else {
				    return _mate_vfs_result_from_gai_error (res);
			 }
	   }

	   *handle = g_new0 (MateVFSResolveHandle, 1);
	   
	   (*handle)->result  = result;
	   (*handle)->current = result;
	   
	   return MATE_VFS_OK;
#else /* HAVE_GETADDRINFO */
	   struct hostent resbuf, *result = &resbuf;
	   MateVFSResult ret;
	   int res;
	   gboolean retry = TRUE;
#ifdef HAVE_GETHOSTBYNAME_R_GLIBC
	   size_t buflen;
	   char *buf;
	   int h_errnop;

restart:	   
	   buf = NULL;
	   buflen = INIT_BUFSIZE;
	   h_errnop = 0;
	   
	   do {
			 buf = g_renew (char, buf, buflen);
			 
			 res = gethostbyname_r (hostname,
							    &resbuf,
							    buf,
							    buflen,
							    &result,
							    &h_errnop);
			 buflen *= 2;

	   } while (res == ERANGE);

	   if (res != 0 || result == NULL || result->h_addr_list[0] == NULL) {
			 g_free (buf);
			 if (retry && restart_resolve ()) {
				    retry = FALSE;
				    goto restart;
			 } else {
				    return mate_vfs_result_from_h_errno_val (h_errnop);
			 }
	   }

	   ret = resolvehandle_from_hostent (result, handle);
	   g_free (buf);
#elif HAVE_GETHOSTBYNAME_R_SOLARIS
	   size_t buflen;
	   char *buf;
	   int h_errnop;	   
restart:
	   
	   buf = NULL;
	   buflen = INIT_BUFSIZE;
	   h_errnop = 0;
	   
	   do {
			 buf = g_renew (char, buf, buflen);
			 
			 result = gethostbyname_r (hostname,
								  &resbuf,
								  buf,
								  buflen,
								  &h_errnop);
			 buflen *= 2;

	   } while (h_errnop == ERANGE);

	   if (result == NULL) {
			 g_free (buf);
		   
			 if (retry && restart_resolve ()) {
				    retry = FALSE;
				    goto restart;
			 } else {
				    return mate_vfs_result_from_h_errno_val (h_errnop);
			 }
	   }

	   ret = resolvehandle_from_hostent (result, handle);	
	   g_free (buf);
#elif HAVE_GETHOSTBYNAME_R_HPUX
	   struct hostent_data buf;

restart:
	   res = gethostbyname_r (hostname, result, &buf);

	   if (res != 0) {
			 if (retry && restart_resolve ()) {
				    retry = FALSE;
				    goto restart;
			 } else {
				    return mate_vfs_result_from_h_errno_val (h_errnop);
			 }
	   }

	   ret = resolvehandle_from_hostent (result, handle);
#else /* !HAVE_GETHOSTBYNAME_R_GLIBC && !HAVE_GETHOSTBYNAME_R_SOLARIS && !HAVE_GETHOSTBYNAME_R_HPUX */
	   res = 0;/* only set to avoid unused variable error */
	   
	   G_LOCK (dns_lock);
restart:
	   result = gethostbyname (hostname);

	   if (result == NULL) {
			 if (retry && restart_resolve ()) {
				    retry = FALSE;
				    goto restart;
			 } else {
#ifndef G_OS_WIN32
				    ret = mate_vfs_result_from_h_errno ();
#else
				    switch (WSAGetLastError ()) {
				    case WSAHOST_NOT_FOUND:
					    ret = MATE_VFS_ERROR_HOST_NOT_FOUND;
					    break;
				    case WSANO_DATA:
					    ret = MATE_VFS_ERROR_HOST_HAS_NO_ADDRESS;
					    break;
				    case WSATRY_AGAIN:
				    case WSANO_RECOVERY:
					    ret = MATE_VFS_ERROR_NAMESERVER;
				    default:
					    ret = MATE_VFS_ERROR_GENERIC;
				    }
#endif
			 }
	   } else {
			 ret = resolvehandle_from_hostent (result, handle);
	   }

	   G_UNLOCK (dns_lock);
#endif /* !HAVE_GETHOSTBYNAME_R_GLIBC && !HAVE_GETHOSTBYNAME_R_SOLARIS && !HAVE_GETHOSTBYNAME_R_HPUX */
	   return ret;
#endif /* HAVE_GETADDRINFO */
}
Exemplo n.º 19
0
void
resolve_sockaddr(gchar *result, gsize *result_len, GSockAddr *saddr, gboolean usedns, gboolean usefqdn, gboolean use_dns_cache, gboolean normalize_hostnames)
{
  gchar *hname;
  gboolean positive;
  gchar *p, buf[256];
 
  if (saddr && saddr->sa.sa_family != AF_UNIX)
    {
      if (saddr->sa.sa_family == AF_INET
#if ENABLE_IPV6
          || saddr->sa.sa_family == AF_INET6
#endif
         )
        {
          void *addr;
          socklen_t addr_len G_GNUC_UNUSED;
          
          if (saddr->sa.sa_family == AF_INET)
            {
              addr = &((struct sockaddr_in *) &saddr->sa)->sin_addr;
              addr_len = sizeof(struct in_addr);
            }
#if ENABLE_IPV6
          else
            {
              addr = &((struct sockaddr_in6 *) &saddr->sa)->sin6_addr;
              addr_len = sizeof(struct in6_addr);
            }
#endif

          hname = NULL;
          if (usedns)
            {
              if ((!use_dns_cache || !dns_cache_lookup(saddr->sa.sa_family, addr, (const gchar **) &hname, &positive)) && usedns != 2)
                {
#ifdef HAVE_GETNAMEINFO
                  if (getnameinfo(&saddr->sa, saddr->salen, buf, sizeof(buf), NULL, 0, 0) == 0)
                    hname = buf;
#else
                  struct hostent *hp;

                  G_LOCK(resolv_lock);
                  hp = gethostbyaddr(addr, addr_len, saddr->sa.sa_family);
                  G_UNLOCK(resolv_lock);
                  hname = (hp && hp->h_name) ? hp->h_name : NULL;
#endif

                  if (hname)
                    positive = TRUE;

                  if (use_dns_cache && hname)
                    {
                      /* resolution success, store this as a positive match in the cache */
                      dns_cache_store(FALSE, saddr->sa.sa_family, addr, hname, TRUE);
                    }
                } 
            }
            
          if (!hname) 
            {
              inet_ntop(saddr->sa.sa_family, addr, buf, sizeof(buf));
              hname = buf;
              if (use_dns_cache)
                dns_cache_store(FALSE, saddr->sa.sa_family, addr, hname, FALSE);
            }
          else 
            {
              if (!usefqdn && positive)
                {
                  /* we only truncate hostnames if they were positive
                   * matches (e.g. real hostnames and not IP
                   * addresses) */

                  p = strchr(hname, '.');

                  if (p)
                    {
                      if (p - hname > sizeof(buf))
                        p = &hname[sizeof(buf)] - 1;
                      memcpy(buf, hname, p - hname);
                      buf[p - hname] = 0;
                      hname = buf;
                    }
                }
            }
        }
      else
        {
          g_assert_not_reached();
        }
    }
  else 
    {
      if (!local_hostname_fqdn[0])
        reset_cached_hostname();
      if (usefqdn)
        {
          /* avoid copy */
          hname = local_hostname_fqdn;
        }
      else
        {
          hname = local_hostname_short;
        }
    }
  if (normalize_hostnames)
    {
      gint i;

      for (i = 0; hname[i] && i < ((*result_len) - 1); i++)
        {
          result[i] = g_ascii_tolower(hname[i]);
        }
      result[i] = '\0'; /* the closing \0 is not copied by the previous loop */
      *result_len = i;
    }
  else
    {
      gsize len = strlen(hname);

      if (*result_len < len - 1)
        len = *result_len - 1;
      memcpy(result, hname, len);
      result[len] = 0;
      *result_len = len;
    }
}
Exemplo n.º 20
0
gboolean
resolve_hostname(GSockAddr **addr, gchar *name)
{
  if (addr)
    { 
#if HAVE_GETADDRINFO
      struct addrinfo hints;
      struct addrinfo *res;

      memset(&hints, 0, sizeof(hints));
      hints.ai_family = (*addr)->sa.sa_family;
      hints.ai_socktype = 0;
      hints.ai_protocol = 0;
      
      if (getaddrinfo(name, NULL, &hints, &res) == 0)
        {
          /* we only use the first entry in the returned list */
          switch ((*addr)->sa.sa_family)
            {
            case AF_INET:
              g_sockaddr_inet_set_address((*addr), ((struct sockaddr_in *) res->ai_addr)->sin_addr);
              break;
#if ENABLE_IPV6
            case AF_INET6:
              {
                guint16 port;

                /* we need to copy the whole sockaddr_in6 structure as it
                 * might contain scope and other required data */
                port = g_sockaddr_inet6_get_port(*addr);
                *g_sockaddr_inet6_get_sa(*addr) = *((struct sockaddr_in6 *) res->ai_addr);

                /* we need to restore the port number as it is zeroed out by the previous assignment */
                g_sockaddr_inet6_set_port(*addr, port);
                break;
              }
#endif
            default: 
              g_assert_not_reached();
              break;
            }
          freeaddrinfo(res);
        }
      else
        {
          msg_error("Error resolving hostname", evt_tag_str("host", name), NULL);
          return FALSE;
        }
#else
      struct hostent *he;
      
      G_LOCK(resolv_lock);
      he = gethostbyname(name);
      if (he)
        {
          switch ((*addr)->sa.sa_family)
            {
            case AF_INET:
              g_sockaddr_inet_set_address((*addr), *(struct in_addr *) he->h_addr);
              break;
            default: 
              g_assert_not_reached();
              break;
            }
          G_UNLOCK(resolv_lock);
        }
      else
        {
          G_UNLOCK(resolv_lock);
          msg_error("Error resolving hostname", evt_tag_str("host", name), NULL);
          return FALSE;
        }
#endif
    }
  return TRUE;
}
static int
camel_gethostbyaddr_r (const char *addr, int addrlen, int type, struct hostent *host,
		       char *buf, size_t buflen, int *herr)
{
#ifdef ENABLE_IPv6
	int retval, len;

	if ((retval = getnameinfo (addr, addrlen, buf, buflen, NULL, 0, NI_NAMEREQD)) != 0) {
		*herr = ai_to_herr (retval);
		return -1;
	}

	len = ALIGN (strlen (buf) + 1);
	if (buflen < IPv6_BUFLEN_MIN + len + addrlen + sizeof (char *))
		return ERANGE;

	/* h_name */
	host->h_name = buf;
	buf += len;

	/* h_aliases */
	((char **) buf)[0] = NULL;
	host->h_aliases = (char **) buf;
	buf += sizeof (char *);

	/* h_addrtype and h_length */
	host->h_length = addrlen;
	host->h_addrtype = type;

	memcpy (buf, addr, host->h_length);
	addr = buf;
	buf += ALIGN (host->h_length);

	/* h_addr_list */
	((char **) buf)[0] = addr;
	((char **) buf)[1] = NULL;
	host->h_addr_list = (char **) buf;

	return 0;
#else /* No support for IPv6 addresses */
#ifdef HAVE_GETHOSTBYADDR_R
#ifdef GETHOSTBYADDR_R_SEVEN_ARGS
	if (gethostbyaddr_r (addr, addrlen, type, host, buf, buflen, herr))
		return 0;
	else
		return errno;
#else
	struct hostent *hp;
	int retval;

	retval = gethostbyaddr_r (addr, addrlen, type, host, buf, buflen, &hp, herr);
	if (hp != NULL) {
		*herr = 0;
		retval = 0;
	} else if (retval == 0) {
		/* glibc 2.3.2 workaround - it seems that
		 * gethostbyaddr_r will sometimes return 0 on fail and
		 * fill @host with garbage strings from /etc/hosts
		 * (failure to parse the file? who knows). Luckily, it
		 * seems that we can rely on @hp being NULL on
		 * fail.
		 */
		retval = -1;
	}

	return retval;
#endif
#else /* No support for gethostbyaddr_r */
	struct hostent *h;

	G_LOCK (gethost_mutex);

	h = gethostbyaddr (addr, addrlen, type);

	if (!h) {
		*herr = h_errno;
		G_UNLOCK (gethost_mutex);
		return -1;
	}

	GETHOST_PROCESS (h, host, buf, buflen, herr);

	G_UNLOCK (gethost_mutex);

	return 0;
#endif /* HAVE_GETHOSTBYADDR_R */
#endif /* ENABLE_IPv6 */
}
static int
camel_gethostbyname_r (const char *name, struct hostent *host,
		       char *buf, size_t buflen, int *herr)
{
#ifdef ENABLE_IPv6
	struct addrinfo hints, *res;
	int retval, len;
	char *addr;

	memset (&hints, 0, sizeof (struct addrinfo));
#ifdef HAVE_AI_ADDRCONFIG
	hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
#else
	hints.ai_flags = AI_CANONNAME;
#endif
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if ((retval = getaddrinfo (name, NULL, &hints, &res)) != 0) {
		*herr = ai_to_herr (retval);
		return -1;
	}

	len = ALIGN (strlen (res->ai_canonname) + 1);
	if (buflen < IPv6_BUFLEN_MIN + len + res->ai_addrlen + sizeof (char *))
		return ERANGE;

	/* h_name */
	strcpy (buf, res->ai_canonname);
	host->h_name = buf;
	buf += len;

	/* h_aliases */
	((char **) buf)[0] = NULL;
	host->h_aliases = (char **) buf;
	buf += sizeof (char *);

	/* h_addrtype and h_length */
	host->h_length = res->ai_addrlen;
	if (res->ai_family == PF_INET6) {
		host->h_addrtype = AF_INET6;

		addr = (char *) &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
	} else {
		host->h_addrtype = AF_INET;

		addr = (char *) &((struct sockaddr_in *) res->ai_addr)->sin_addr;
	}

	memcpy (buf, addr, host->h_length);
	addr = buf;
	buf += ALIGN (host->h_length);

	/* h_addr_list */
	((char **) buf)[0] = addr;
	((char **) buf)[1] = NULL;
	host->h_addr_list = (char **) buf;

	freeaddrinfo (res);

	return 0;
#else /* No support for IPv6 addresses */
#ifdef HAVE_GETHOSTBYNAME_R
#ifdef GETHOSTBYNAME_R_FIVE_ARGS
	if (gethostbyname_r (name, host, buf, buflen, herr))
		return 0;
	else
		return errno;
#else
	struct hostent *hp;
	int retval;

	retval = gethostbyname_r (name, host, buf, buflen, &hp, herr);
	if (hp != NULL) {
		*herr = 0;
	} else if (retval == 0) {
		/* glibc 2.3.2 workaround - it seems that
		 * gethostbyname_r will sometimes return 0 on fail and
		 * not set the hostent values (hence the crash in bug
		 * #56337).  Hopefully we can depend on @hp being NULL
		 * in this error case like we do with
		 * gethostbyaddr_r().
		 */
		retval = -1;
	}

	return retval;
#endif
#else /* No support for gethostbyname_r */
	struct hostent *h;

	G_LOCK (gethost_mutex);

	h = gethostbyname (name);

	if (!h) {
		*herr = h_errno;
		G_UNLOCK (gethost_mutex);
		return -1;
	}

	GETHOST_PROCESS (h, host, buf, buflen, herr);

	G_UNLOCK (gethost_mutex);

	return 0;
#endif /* HAVE_GETHOSTBYNAME_R */
#endif /* ENABLE_IPv6 */
}
Exemplo n.º 23
0
void select_sound(GtkWidget *menu_item, gpointer data)
{
    GtkWidget *dialog;
    GtkFileFilter *filter, *filter_all;

    play = FALSE;

    dialog = gtk_file_chooser_dialog_new(_("Choose a file"),
                                         NULL,
                                         GTK_FILE_CHOOSER_ACTION_OPEN,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         "Stop Sound", 1000,
                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                         NULL);

    filter = gtk_file_filter_new();
    gtk_file_filter_add_pattern(filter, "*.[mM][pP][1-3]");
    gtk_file_filter_add_pattern(filter, "*.[wW][aA][vV]");
    gtk_file_filter_add_pattern(filter, "*.[oO][gG][gG]");
    gtk_file_filter_set_name(filter, _("Sound Files"));
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);

    filter_all = gtk_file_filter_new();
    gtk_file_filter_add_pattern(filter_all, "*");
    gtk_file_filter_set_name(filter_all, _("All Files"));
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter_all);

    gchar *dir = g_build_filename(installation_dir, "etc", NULL);
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
    g_free(dir);

    gint r = gtk_dialog_run(GTK_DIALOG(dialog));

    if (play) { // can start during dialog
        gtk_widget_destroy(dialog);
        return;
    }

    if (r == 1000) { // stop sound
        G_LOCK(sound);

        g_free(sound_file);
        sound_file = NULL;

        if (dev) ao_close(dev);
        dev = NULL;

        g_key_file_set_string(keyfile, "preferences", "soundfile", "");
        gtk_widget_destroy(dialog);

        G_UNLOCK(sound);
        return;
    }

    if (r != GTK_RESPONSE_ACCEPT) {
        gtk_widget_destroy(dialog);
        return;
    }
               
    G_LOCK(sound);

    g_free(sound_file);
    sound_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
    g_key_file_set_string(keyfile, "preferences", "soundfile", sound_file);

    init_dev();

    G_UNLOCK(sound);

    gtk_widget_destroy(dialog);
}
Exemplo n.º 24
0
/**
 * storaged_log:
 * @level: A #StoragedLogLevel.
 * @function: Pass #G_STRFUNC here.
 * @location: Pass #G_STRLOC here.
 * @format: printf()-style format.
 * @...: Arguments for format.
 *
 * Low-level logging function used by storaged_debug() and other macros.
 */
void
storaged_log (StoragedLogLevel     level,
              const gchar         *function,
              const gchar         *location,
              const gchar         *format,
              ...)
{
  va_list var_args;
  gchar *message;
  GTimeVal now;
  time_t now_time;
  struct tm *now_tm;
  gchar time_buf[128];
  const gchar *level_str;
  const gchar *level_color_str;
  gint syslog_priority;
  static gboolean have_called_openlog = FALSE;
  gchar *thread_str;

  va_start (var_args, format);
  message = g_strdup_vprintf (format, var_args);
  va_end (var_args);

  G_LOCK (log_lock);

  if (!have_called_openlog)
    {
      openlog ("storaged",
               LOG_CONS|LOG_NDELAY|LOG_PID,
               LOG_DAEMON);
      have_called_openlog = TRUE;
    }

  g_get_current_time (&now);
  now_time = (time_t) now.tv_sec;
  now_tm = localtime (&now_time);
  strftime (time_buf, sizeof time_buf, "%H:%M:%S", now_tm);

  switch (level)
    {
    case STORAGED_LOG_LEVEL_DEBUG:
      level_str = "[DEBUG]";
      syslog_priority = LOG_DEBUG;
      level_color_str = _color_get (_COLOR_FG_BLUE);
      break;

    case STORAGED_LOG_LEVEL_INFO:
      level_str = "[INFO]";
      syslog_priority = LOG_INFO;
      level_color_str = _color_get (_COLOR_FG_CYAN);
      break;

    case STORAGED_LOG_LEVEL_NOTICE:
      level_str = "[NOTICE]";
      syslog_priority = LOG_NOTICE;
      level_color_str = _color_get (_COLOR_FG_CYAN);
      break;

    case STORAGED_LOG_LEVEL_WARNING:
      level_str = "[WARNING]";
      syslog_priority = LOG_WARNING;
      level_color_str = _color_get (_COLOR_FG_YELLOW);
      break;

    case STORAGED_LOG_LEVEL_ERROR:
      level_str = "[ERROR]";
      syslog_priority = LOG_ERR;
      level_color_str = _color_get (_COLOR_FG_RED);
      break;

    default:
      g_assert_not_reached ();
      break;
    }

  thread_str = g_strdup_printf ("%d", (gint) syscall (SYS_gettid));
  g_print ("%s%s%s.%03d:%s%s%s[%s]%s:%s%s%s:%s %s %s[%s, %s()]%s\n",
           _color_get (_COLOR_BOLD_ON), _color_get (_COLOR_FG_YELLOW), time_buf, (gint) now.tv_usec / 1000, _color_get (_COLOR_RESET),
           _color_get (_COLOR_FG_MAGENTA), _color_get (_COLOR_BOLD_ON), thread_str, _color_get (_COLOR_RESET),
           level_color_str, _color_get (_COLOR_BOLD_ON), level_str, _color_get (_COLOR_RESET),
           message,
           _color_get (_COLOR_FG_BLACK), location, function, _color_get (_COLOR_RESET));
  if (level >= STORAGED_LOG_LEVEL_NOTICE)
    syslog (syslog_priority, "%s", message);
  g_free (message);

  G_UNLOCK (log_lock);
}
Exemplo n.º 25
0
static gboolean
initable_init (GInitable     *initable,
               GCancellable  *cancellable,
               GError       **error)
{
  UDisksClient *client = UDISKS_CLIENT (initable);
  gboolean ret;
  GList *objects, *l;
  GList *interfaces, *ll;

  ret = FALSE;

  /* This method needs to be idempotent to work with the singleton
   * pattern. See the docs for g_initable_init(). We implement this by
   * locking.
   */
  G_LOCK (init_lock);
  if (client->is_initialized)
    {
      if (client->object_manager != NULL)
        ret = TRUE;
      else
        g_assert (client->initialization_error != NULL);
      goto out;
    }
  g_assert (client->initialization_error == NULL);

  client->context = g_main_context_get_thread_default ();
  if (client->context != NULL)
    g_main_context_ref (client->context);

  client->object_manager = udisks_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                                          G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
                                                                          "org.freedesktop.UDisks2",
                                                                          "/org/freedesktop/UDisks2",
                                                                          cancellable,
                                                                          &client->initialization_error);
  if (client->object_manager == NULL)
    goto out;

  /* init all proxies */
  objects = g_dbus_object_manager_get_objects (client->object_manager);
  for (l = objects; l != NULL; l = l->next)
    {
      interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (l->data));
      for (ll = interfaces; ll != NULL; ll = ll->next)
        {
          init_interface_proxy (client, G_DBUS_PROXY (ll->data));
        }
      g_list_foreach (interfaces, (GFunc) g_object_unref, NULL);
      g_list_free (interfaces);
    }
  g_list_foreach (objects, (GFunc) g_object_unref, NULL);
  g_list_free (objects);

  g_signal_connect (client->object_manager,
                    "object-added",
                    G_CALLBACK (on_object_added),
                    client);
  g_signal_connect (client->object_manager,
                    "object-removed",
                    G_CALLBACK (on_object_removed),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-added",
                    G_CALLBACK (on_interface_added),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-removed",
                    G_CALLBACK (on_interface_removed),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-proxy-properties-changed",
                    G_CALLBACK (on_interface_proxy_properties_changed),
                    client);

  ret = TRUE;

out:
  client->is_initialized = TRUE;
  if (!ret)
    {
      g_assert (client->initialization_error != NULL);
      g_propagate_error (error, g_error_copy (client->initialization_error));
    }
  G_UNLOCK (init_lock);
  return ret;
}
/* g_main_iterate () runs a single iteration of the mainloop, or,
 * if !dispatch checks to see if any sources need dispatching.
 * basic algorithm for dispatch=TRUE:
 *
 * 1) while the list of currently pending sources is non-empty,
 *    we call (*dispatch) on those that are !IN_CALL or can_recurse,
 *    removing sources from the list after each returns.
 *    the return value of (*dispatch) determines whether the source
 *    itself is kept alive.
 *
 * 2) call (*prepare) for sources that are not yet SOURCE_READY and
 *    are !IN_CALL or can_recurse. a return value of TRUE determines
 *    that the source would like to be dispatched immediatedly, it
 *    is then flagged as SOURCE_READY.
 *
 * 3) poll with the pollfds from all sources at the priority of the
 *    first source flagged as SOURCE_READY. if there are any sources
 *    flagged as SOURCE_READY, we use a timeout of 0 or the minimum
 *    of all timouts otherwise.
 *
 * 4) for each source !IN_CALL or can_recurse, if SOURCE_READY or
 *    (*check) returns true, add the source to the pending list.
 *    once one source returns true, stop after checking all sources
 *    at that priority.
 *
 * 5) while the list of currently pending sources is non-empty,
 *    call (*dispatch) on each source, removing the source
 *    after the call.
 *
 */
static gboolean
g_main_iterate (gboolean block,
		gboolean dispatch)
{
  GHook *hook;
  GTimeVal current_time  = { 0, 0 };
  gint n_ready = 0;
  gint current_priority = 0;
  gint timeout;
  gboolean retval = FALSE;

  g_return_val_if_fail (!block || dispatch, FALSE);

  g_get_current_time (&current_time);

  G_LOCK (main_loop);

#ifdef G_THREADS_ENABLED
  if (poll_waiting)
    {
      g_warning("g_main_iterate(): main loop already active in another thread");
      G_UNLOCK (main_loop);
      return FALSE;
    }
#endif
  
  /* If recursing, finish up current dispatch, before starting over */
  if (pending_dispatches)
    {
      if (dispatch)
	g_main_dispatch (&current_time);
      
      G_UNLOCK (main_loop);

      return TRUE;
    }

  /* Prepare all sources */

  timeout = block ? -1 : 0;
  
  hook = g_hook_first_valid (&source_list, TRUE);
  while (hook)
    {
      GSource *source = (GSource*) hook;
      gint source_timeout = -1;

      if ((n_ready > 0) && (source->priority > current_priority))
	{
	  g_hook_unref (&source_list, hook);
	  break;
	}
      if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
	{
	  hook = g_hook_next_valid (&source_list, hook, TRUE);
	  continue;
	}

      if (!(hook->flags & G_SOURCE_READY))
	{
	  gboolean (*prepare)  (gpointer  source_data, 
				GTimeVal *current_time,
				gint     *timeout,
				gpointer  user_data);

	  prepare = ((GSourceFuncs *) hook->func)->prepare;
	  in_check_or_prepare++;
	  G_UNLOCK (main_loop);

	  if ((*prepare) (source->source_data, &current_time, &source_timeout, source->hook.data))
	    hook->flags |= G_SOURCE_READY;
	  
	  G_LOCK (main_loop);
	  in_check_or_prepare--;
	}

      if (hook->flags & G_SOURCE_READY)
	{
	  if (!dispatch)
	    {
	      g_hook_unref (&source_list, hook);
	      G_UNLOCK (main_loop);

	      return TRUE;
	    }
	  else
	    {
	      n_ready++;
	      current_priority = source->priority;
	      timeout = 0;
	    }
	}
      
      if (source_timeout >= 0)
	{
	  if (timeout < 0)
	    timeout = source_timeout;
	  else
	    timeout = MIN (timeout, source_timeout);
	}

      hook = g_hook_next_valid (&source_list, hook, TRUE);
    }

  /* poll(), if necessary */

  g_main_poll (timeout, n_ready > 0, current_priority);

  if (timeout != 0)
    g_get_current_time (&current_time);
  
  /* Check to see what sources need to be dispatched */

  n_ready = 0;
  
  hook = g_hook_first_valid (&source_list, TRUE);
  while (hook)
    {
      GSource *source = (GSource *)hook;

      if ((n_ready > 0) && (source->priority > current_priority))
	{
	  g_hook_unref (&source_list, hook);
	  break;
	}
      if (G_HOOK_IN_CALL (hook) && !(hook->flags & G_SOURCE_CAN_RECURSE))
	{
	  hook = g_hook_next_valid (&source_list, hook, TRUE);
	  continue;
	}

      if (!(hook->flags & G_SOURCE_READY))
	{
	  gboolean (*check) (gpointer  source_data,
			     GTimeVal *current_time,
			     gpointer  user_data);

	  check = ((GSourceFuncs *) hook->func)->check;
	  in_check_or_prepare++;
	  G_UNLOCK (main_loop);
	  
	  if ((*check) (source->source_data, &current_time, source->hook.data))
	    hook->flags |= G_SOURCE_READY;

	  G_LOCK (main_loop);
	  in_check_or_prepare--;
	}

      if (hook->flags & G_SOURCE_READY)
	{
	  if (dispatch)
	    {
	      hook->flags &= ~G_SOURCE_READY;
	      g_hook_ref (&source_list, hook);
	      pending_dispatches = g_slist_prepend (pending_dispatches, source);
	      current_priority = source->priority;
	      n_ready++;
	    }
	  else
	    {
	      g_hook_unref (&source_list, hook);
	      G_UNLOCK (main_loop);

	      return TRUE;
	    }
	}
      
      hook = g_hook_next_valid (&source_list, hook, TRUE);
    }
 
  /* Now invoke the callbacks */

  if (pending_dispatches)
    {
      pending_dispatches = g_slist_reverse (pending_dispatches);
      g_main_dispatch (&current_time);
      retval = TRUE;
    }

  G_UNLOCK (main_loop);

  return retval;
}
/* HOLDS: main_loop_lock */
static void
g_main_poll (gint     timeout,
	     gboolean use_priority,
	     gint     priority)
{
#ifdef  G_MAIN_POLL_DEBUG
  GTimer *poll_timer;
#endif
  GPollFD *fd_array;
  GPollRec *pollrec;
  gint i;
  gint npoll;

#ifdef G_THREADS_ENABLED
#ifndef NATIVE_WIN32
  if (wake_up_pipe[0] < 0)
    {
      if (pipe (wake_up_pipe) < 0)
	g_error ("Cannot create pipe main loop wake-up: %s\n",
		 g_strerror (errno));

      wake_up_rec.fd = wake_up_pipe[0];
      wake_up_rec.events = G_IO_IN;
      g_main_add_poll_unlocked (0, &wake_up_rec);
    }
#else
  if (wake_up_semaphore == NULL)
    {
      if ((wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL)) == NULL)
	g_error ("Cannot create wake-up semaphore: %d", GetLastError ());
      wake_up_rec.fd = (gint) wake_up_semaphore;
      wake_up_rec.events = G_IO_IN;
      g_main_add_poll_unlocked (0, &wake_up_rec);
    }
#endif
#endif
  fd_array = g_new (GPollFD, n_poll_records);
 
  pollrec = poll_records;
  i = 0;
  while (pollrec && (!use_priority || priority >= pollrec->priority))
    {
      if (pollrec->fd->events)
	{
	  fd_array[i].fd = pollrec->fd->fd;
	  /* In direct contradiction to the Unix98 spec, IRIX runs into
	   * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
	   * flags in the events field of the pollfd while it should
	   * just ignoring them. So we mask them out here.
	   */
	  fd_array[i].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
	  fd_array[i].revents = 0;
	  i++;
	}
      
      pollrec = pollrec->next;
    }
#ifdef G_THREADS_ENABLED
  poll_waiting = TRUE;
  poll_changed = FALSE;
#endif
  
  npoll = i;
  if (npoll || timeout != 0)
    {
#ifdef	G_MAIN_POLL_DEBUG
      g_print ("g_main_poll(%d) timeout: %d\r", npoll, timeout);
      poll_timer = g_timer_new ();
#endif
      
      G_UNLOCK (main_loop);
      (*poll_func) (fd_array, npoll, timeout);
      G_LOCK (main_loop);
      
#ifdef	G_MAIN_POLL_DEBUG
      g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
	       npoll,
	       timeout,
	       g_timer_elapsed (poll_timer, NULL));
      g_timer_destroy (poll_timer);
      pollrec = poll_records;
      i = 0;
      while (i < npoll)
	{
	  if (pollrec->fd->events)
	    {
	      if (fd_array[i].revents)
		{
		  g_print (" [%d:", fd_array[i].fd);
		  if (fd_array[i].revents & G_IO_IN)
		    g_print ("i");
		  if (fd_array[i].revents & G_IO_OUT)
		    g_print ("o");
		  if (fd_array[i].revents & G_IO_PRI)
		    g_print ("p");
		  if (fd_array[i].revents & G_IO_ERR)
		    g_print ("e");
		  if (fd_array[i].revents & G_IO_HUP)
		    g_print ("h");
		  if (fd_array[i].revents & G_IO_NVAL)
		    g_print ("n");
		  g_print ("]");
		}
	      i++;
	    }
	  pollrec = pollrec->next;
	}
      g_print ("\n");
#endif
    } /* if (npoll || timeout != 0) */
  
#ifdef G_THREADS_ENABLED
  if (!poll_waiting)
    {
#ifndef NATIVE_WIN32
      gchar c;
      read (wake_up_pipe[0], &c, 1);
#endif
    }
  else
    poll_waiting = FALSE;

  /* If the set of poll file descriptors changed, bail out
   * and let the main loop rerun
   */
  if (poll_changed)
    {
      g_free (fd_array);
      return;
    }
#endif

  pollrec = poll_records;
  i = 0;
  while (i < npoll)
    {
      if (pollrec->fd->events)
	{
	  pollrec->fd->revents = fd_array[i].revents;
	  i++;
	}
      pollrec = pollrec->next;
    }

  g_free (fd_array);
}
Exemplo n.º 28
0
static void on_dummy_monitor_destroy(GFile* gf, GFileMonitor* mon)
{
    G_LOCK(hash);
    g_hash_table_remove(dummy_hash, gf);
    G_UNLOCK(hash);
}
Exemplo n.º 29
0
/**
 * g_content_type_guess:
 * @filename: (allow-none): a string, or %NULL
 * @data: (allow-none) (array length=data_size): a stream of data, or %NULL
 * @data_size: the size of @data
 * @result_uncertain: (allow-none) (out): return location for the certainty
 *     of the result, or %NULL
 *
 * Guesses the content type based on example data. If the function is
 * uncertain, @result_uncertain will be set to %TRUE. Either @filename
 * or @data may be %NULL, in which case the guess will be based solely
 * on the other argument.
 *
 * Returns: a string indicating a guessed content type for the
 *     given data. Free with g_free()
 */
gchar *
g_content_type_guess (const gchar  *filename,
                      const guchar *data,
                      gsize         data_size,
                      gboolean     *result_uncertain)
{
  char *basename;
  const char *name_mimetypes[10], *sniffed_mimetype;
  char *mimetype;
  int i;
  int n_name_mimetypes;
  int sniffed_prio;

  sniffed_prio = 0;
  n_name_mimetypes = 0;
  sniffed_mimetype = XDG_MIME_TYPE_UNKNOWN;

  if (result_uncertain)
    *result_uncertain = FALSE;

  /* our test suite and potentially other code used -1 in the past, which is
   * not documented and not allowed; guard against that */
  g_return_val_if_fail (data_size != (gsize) -1, g_strdup (XDG_MIME_TYPE_UNKNOWN));

  G_LOCK (gio_xdgmime);

  if (filename)
    {
      i = strlen (filename);
      if (filename[i - 1] == '/')
        {
          name_mimetypes[0] = "inode/directory";
          name_mimetypes[1] = NULL;
          n_name_mimetypes = 1;
          if (result_uncertain)
            *result_uncertain = TRUE;
        }
      else
        {
          basename = g_path_get_basename (filename);
          n_name_mimetypes = xdg_mime_get_mime_types_from_file_name (basename, name_mimetypes, 10);
          g_free (basename);
        }
    }

  /* Got an extension match, and no conflicts. This is it. */
  if (n_name_mimetypes == 1)
    {
      gchar *s = g_strdup (name_mimetypes[0]);
      G_UNLOCK (gio_xdgmime);
      return s;
    }

  if (data)
    {
      sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, &sniffed_prio);
      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
          data &&
          looks_like_text (data, data_size))
        sniffed_mimetype = "text/plain";

      /* For security reasons we don't ever want to sniff desktop files
       * where we know the filename and it doesn't have a .desktop extension.
       * This is because desktop files allow executing any application and
       * we don't want to make it possible to hide them looking like something
       * else.
       */
      if (filename != NULL &&
          strcmp (sniffed_mimetype, "application/x-desktop") == 0)
        sniffed_mimetype = "text/plain";
    }

  if (n_name_mimetypes == 0)
    {
      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
          result_uncertain)
        *result_uncertain = TRUE;

      mimetype = g_strdup (sniffed_mimetype);
    }
  else
    {
      mimetype = NULL;
      if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN)
        {
          if (sniffed_prio >= 80) /* High priority sniffing match, use that */
            mimetype = g_strdup (sniffed_mimetype);
          else
            {
              /* There are conflicts between the name matches and we
               * have a sniffed type, use that as a tie breaker.
               */
              for (i = 0; i < n_name_mimetypes; i++)
                {
                  if ( xdg_mime_mime_type_subclass (name_mimetypes[i], sniffed_mimetype))
                    {
                      /* This nametype match is derived from (or the same as)
                       * the sniffed type). This is probably it.
                       */
                      mimetype = g_strdup (name_mimetypes[i]);
                      break;
                    }
                }
            }
        }

      if (mimetype == NULL)
        {
          /* Conflicts, and sniffed type was no help or not there.
           * Guess on the first one
           */
          mimetype = g_strdup (name_mimetypes[0]);
          if (result_uncertain)
            *result_uncertain = TRUE;
        }
    }

  G_UNLOCK (gio_xdgmime);

  return mimetype;
}
Exemplo n.º 30
0
static gboolean
initable_init (GInitable     *initable,
               GCancellable  *cancellable,
               GError       **error)
{
  GoaClient *client = GOA_CLIENT (initable);
  gboolean ret;

  ret = FALSE;

  /* This method needs to be idempotent to work with the singleton
   * pattern. See the docs for g_initable_init(). We implement this by
   * locking.
   */
  G_LOCK (init_lock);
  if (client->is_initialized)
    {
      if (client->object_manager != NULL)
        ret = TRUE;
      else
        g_assert (client->initialization_error != NULL);
      goto out;
    }
  g_assert (client->initialization_error == NULL);

  client->object_manager = goa_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                                       G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
                                                                       "org.gnome.OnlineAccounts",
                                                                       "/org/gnome/OnlineAccounts",
                                                                       cancellable,
                                                                       &client->initialization_error);
  if (client->object_manager == NULL)
    goto out;
  g_signal_connect (client->object_manager,
                    "object-added",
                    G_CALLBACK (on_object_added),
                    client);
  g_signal_connect (client->object_manager,
                    "object-removed",
                    G_CALLBACK (on_object_removed),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-proxy-properties-changed",
                    G_CALLBACK (on_interface_proxy_properties_changed),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-added",
                    G_CALLBACK (on_interface_added),
                    client);
  g_signal_connect (client->object_manager,
                    "interface-removed",
                    G_CALLBACK (on_interface_removed),
                    client);

  ret = TRUE;

out:
  client->is_initialized = TRUE;
  if (!ret)
    {
      g_assert (client->initialization_error != NULL);
      g_propagate_error (error, g_error_copy (client->initialization_error));
    }
  G_UNLOCK (init_lock);
  return ret;
}