Esempio n. 1
0
static GList *
add_sources (GSocketListener   *listener,
	     GSocketSourceFunc  callback,
	     gpointer           callback_data,
	     GCancellable      *cancellable,
	     GMainContext      *context)
{
  GSocket *socket;
  GSource *source;
  GList *sources;
  int i;

  sources = NULL;
  for (i = 0; i < listener->priv->sockets->len; i++)
    {
      socket = listener->priv->sockets->pdata[i];

      source = g_socket_create_source (socket, G_IO_IN, cancellable);
      g_source_set_callback (source,
                             (GSourceFunc) callback,
                             callback_data, NULL);
      g_source_attach (source, context);

      sources = g_list_prepend (sources, source);
    }

  return sources;
}
Esempio n. 2
0
/* Idle-handler for initial interface and address bootstrapping.
 *
 * We cannot send the RTM_GETADDR message until we processed all packets of
 * the RTM_GETLINK message. So on the first call this idle handler processes
 * all answers of RTM_GETLINK on the second call all answers of RTM_GETADDR
 * and on the third call it creates the regular socket source for listening on
 * the netlink socket, detaching itself from the idle source afterwards.
 */
static gboolean
on_bootstrap (GUPnPLinuxContextManager *self)
{
        if (self->priv->nl_seq == 0) {
                query_all_network_interfaces (self);

                return TRUE;
        } else if (self->priv->nl_seq == 1) {
                query_all_addresses (self);

                return TRUE;
        } else {
                self->priv->netlink_socket_source = g_socket_create_source
                                                (self->priv->netlink_socket,
                                                 G_IO_IN | G_IO_PRI,
                                                 NULL);

                g_source_attach (self->priv->netlink_socket_source,
                                 g_main_context_get_thread_default ());

                g_source_set_callback (self->priv->netlink_socket_source,
                                       (GSourceFunc)
                                       on_netlink_message_available,
                                       self,
                                       NULL);
        }

        return FALSE;
}
Esempio n. 3
0
static void
ensure_condition (GSocket *socket,
		  const char *where,
		  GCancellable *cancellable,
		  GIOCondition condition)
{
  GError *error = NULL;
  GSource *source;

  if (!non_blocking)
    return;

  if (use_source)
    {
      source = g_socket_create_source (socket,
                                       condition,
                                       cancellable);
      g_source_set_callback (source,
                             (GSourceFunc) source_ready,
			     NULL, NULL);
      g_source_attach (source, NULL);
      g_source_unref (source);
      g_main_loop_run (loop);
    }
  else
    {
      if (!g_socket_condition_wait (socket, condition, cancellable, &error))
	{
	  g_printerr ("condition wait error for %s: %s\n",
		      where,
		      error->message);
	  exit (1);
	}
    }
}
void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, PassOwnPtr<WorkItem> item)
{
    GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(fileDescriptor, 0));
    ASSERT(socket);
    GRefPtr<GCancellable> cancellable = adoptGRef(g_cancellable_new());
    GRefPtr<GSource> dispatchSource = adoptGRef(g_socket_create_source(socket.get(), static_cast<GIOCondition>(condition), cancellable.get()));
    ASSERT(dispatchSource);
    EventSource* eventSource = new EventSource(item, this, cancellable.get());
    ASSERT(eventSource);

    g_source_set_callback(dispatchSource.get(), reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWork),
        eventSource, reinterpret_cast<GDestroyNotify>(&WorkQueue::EventSource::deleteEventSource));

    // Set up the event sources under the mutex since this is shared across multiple threads.
    {
        MutexLocker locker(m_eventSourcesLock);
        Vector<EventSource*> sources;
        EventSourceIterator it = m_eventSources.find(fileDescriptor);
        if (it != m_eventSources.end()) 
            sources = it->second;

        sources.append(eventSource);
        m_eventSources.set(fileDescriptor, sources);
    }

    g_source_attach(dispatchSource.get(), m_eventContext);
}
Esempio n. 5
0
gint
main (void)
{
	gboolean ret;
	GSocket *socket = NULL;
	GSocketAddress *address = NULL;
	GError *error = NULL;
	gsize wrote;
	const gchar *buffer = "ping\n";
	const gchar *socket_filename = "/tmp/pk-self-test.socket";
	GSource *source;
	GMainLoop *loop;

	g_type_init ();
	loop = g_main_loop_new (NULL, FALSE);

	/* create socket */
	socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
	if (socket == NULL) {
		g_warning ("failed to create socket: %s", error->message);
		g_error_free (error);
		goto out;
	}
	g_socket_set_blocking (socket, FALSE);
	g_socket_set_keepalive (socket, TRUE);

	/* connect to it */
	address = g_unix_socket_address_new (socket_filename);
	ret = g_socket_connect (socket, address, NULL, &error);
	if (!ret) {
		g_warning ("failed to connect to socket: %s", error->message);
		g_error_free (error);
		goto out;
	}

	/* socket has data */
	source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
	g_source_set_callback (source, (GSourceFunc) pk_socket_example_accept_connection_cb, loop, NULL);
	g_source_attach (source, NULL);

	/* send some data */
	wrote = g_socket_send (socket, buffer, 5, NULL, &error);
	if (wrote != 5) {
		g_warning ("failed to write 5 bytes");
		goto out;
	}

	/* run main loop */
	g_debug ("running main loop");
	g_main_loop_run (loop);
out:
	if (loop != NULL)
		g_main_loop_unref (loop);
	if (socket != NULL)
		g_object_unref (socket);
	if (address != NULL)
		g_object_unref (address);
	return 0;
}
Esempio n. 6
0
/* Queue data starting at byte offset @message_offset from @message’s
 * buffers.
 *
 * Returns the message's length */
static void
add_to_be_sent (NiceSocket *sock, const NiceOutputMessage *message,
    gsize message_offset, gsize message_len, gboolean head)
{
  TcpPriv *priv = sock->priv;
  struct to_be_sent *tbs;
  guint j;
  gsize offset = 0;

  if (message_offset >= message_len)
    return;

  tbs = g_slice_new0 (struct to_be_sent);
  tbs->length = message_len - message_offset;
  tbs->buf = g_malloc (tbs->length);
  tbs->can_drop = !head;

  if (head)
    g_queue_push_head (&priv->send_queue, tbs);
  else
    g_queue_push_tail (&priv->send_queue, tbs);

  if (priv->io_source == NULL) {
    priv->io_source = g_socket_create_source(sock->fileno, G_IO_OUT, NULL);
    g_source_set_callback (priv->io_source, (GSourceFunc) socket_send_more,
        sock, NULL);
    g_source_attach (priv->io_source, priv->context);
  }

  /* Move the data into the buffer. */
  for (j = 0;
       (message->n_buffers >= 0 && j < (guint) message->n_buffers) ||
       (message->n_buffers < 0 && message->buffers[j].buffer != NULL);
       j++) {
    const GOutputVector *buffer = &message->buffers[j];
    gsize len;

    /* Skip this buffer if it’s within @message_offset. */
    if (buffer->size <= message_offset) {
      message_offset -= buffer->size;
      continue;
    }

    len = MIN (tbs->length - offset, buffer->size - message_offset);
    memcpy (tbs->buf + offset, (guint8 *) buffer->buffer + message_offset, len);
    offset += len;
    message_offset -= len;
  }
}
static GSource *
g_socket_output_stream_pollable_create_source (GPollableOutputStream *pollable,
        GCancellable          *cancellable)
{
    GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable);
    GSource *socket_source, *pollable_source;

    pollable_source = g_pollable_source_new (G_OBJECT (output_stream));
    socket_source = g_socket_create_source (output_stream->priv->socket,
                                            G_IO_OUT, cancellable);
    g_source_set_dummy_callback (socket_source);
    g_source_add_child_source (pollable_source, socket_source);
    g_source_unref (socket_source);

    return pollable_source;
}
Esempio n. 8
0
static void
cockpit_request_start (CockpitWebServer *self,
                       GIOStream *io,
                       gboolean first)
{
  GSocketConnection *connection;
  CockpitRequest *request;
  gboolean input = TRUE;
  GSocket *socket;

  request = g_new0 (CockpitRequest, 1);
  request->web_server = self;
  request->io = g_object_ref (io);
  request->buffer = g_byte_array_new ();

  /* Right before a successive request, EOF is not unexpected */
  request->eof_okay = !first;

  request->timeout = g_timeout_source_new_seconds (cockpit_webserver_request_timeout);
  g_source_set_callback (request->timeout, on_request_timeout, request, NULL);
  g_source_attach (request->timeout, self->main_context);

  if (first)
    {
      connection = G_SOCKET_CONNECTION (io);
      socket = g_socket_connection_get_socket (connection);
      g_socket_set_blocking (socket, FALSE);

      if (self->certificate)
        {
          request->source = g_socket_create_source (g_socket_connection_get_socket (connection),
                                                    G_IO_IN, NULL);
          g_source_set_callback (request->source, (GSourceFunc)on_socket_input, request, NULL);
          g_source_attach (request->source, self->main_context);

          /* Wait on reading input */
          input = FALSE;
        }

    }

  /* Owns the request */
  g_hash_table_add (self->requests, request);

  if (input)
    start_request_input (request);
}
void GSourceWrap::Socket::initialize(const char* name, std::function<bool (GIOCondition)>&& function, GSocket* socket, GIOCondition condition, int priority, GMainContext* context)
{
    ASSERT(!m_source);
    GCancellable* cancellable = g_cancellable_new();
    m_source = adoptGRef(g_socket_create_source(socket, condition, cancellable));
    m_cancellable = adoptGRef(cancellable);

    g_source_set_name(m_source.get(), name);
    g_source_set_priority(m_source.get(), priority);

    g_source_set_callback(m_source.get(), reinterpret_cast<GSourceFunc>(staticSocketCallback),
        new CallbackContext{ WTF::move(function), m_cancellable }, static_cast<GDestroyNotify>(destroyCallbackContext<CallbackContext>));

    if (!context)
        context = g_main_context_get_thread_default();
    g_source_attach(m_source.get(), context);
}
Esempio n. 10
0
void dirserver_init(gchar* baseaddress)
{
    syslog(LOG_DEBUG,"dirserver_init: starting directory server");
    services = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);

    dirserversocket = multicast_createSocket("directoryserver", 2323, &sa);
    if( socket != NULL){
        syslog(LOG_DEBUG,"dirserver_init: socket open");
        GSource *source = g_socket_create_source(dirserversocket,
                            G_IO_IN, NULL);
        ub_assert(source != NULL);
        g_source_set_callback(source, (GSourceFunc)dirserver_read,
                                NULL, NULL);
        g_source_attach(source, g_main_context_default());

    }else{
        syslog(LOG_WARNING,
                "directory-server.c: warning: could not create socket");
    }
    GError * e = NULL;

    GInetAddress *net_base = g_inet_address_new_from_string(baseaddress);
    if( net_base == NULL ){
        syslog(LOG_ERR, "dirserver_init: Could not parse base address");
        return;
    }

    //set up http tcp listener
    GSocketAddress *httpsa = g_inet_socket_address_new(net_base,8080);
    syslog(LOG_DEBUG,"dirserver_init: Creating tcp socket on port 8080\n");
    GSocketService *gss = g_socket_service_new();
    
    //TODO: save a reference to the gss somewhere
    if( g_socket_listener_add_address(G_SOCKET_LISTENER(gss), httpsa,
        G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL, NULL, &e)
            == FALSE ){
        syslog(LOG_WARNING,
            "dirserver_init: error while creating socket listener: %s\n",e->message);
        g_error_free(e);
    }
    g_signal_connect(gss, "incoming", G_CALLBACK(dirserver_tcp_listener),NULL);
    g_socket_service_start(gss); 

    g_timeout_add_seconds(1,dirserver_tick,NULL);
}
Esempio n. 11
0
static gboolean
on_new_connection (GSocketService    *service,
                   GSocketConnection *socket_connection,
                   GObject           *source_object,
                   DasomServer       *server)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  /* TODO: simple authentication using GCredentials */

  GSocket *socket = g_socket_connection_get_socket (socket_connection);

  DasomMessage *message;
  message = dasom_recv_message (socket);

  if (message->header->type == DASOM_MESSAGE_CONNECT)
    dasom_send_message (socket, DASOM_MESSAGE_CONNECT_REPLY, NULL, 0, NULL);
  else
  {
    /* TODO: error handling */
    dasom_send_message (socket, DASOM_MESSAGE_ERROR, NULL, 0, NULL);
    return TRUE; /* TODO: what happened if return value is FALSE */
  }

  DasomConnection *connection;
  connection = dasom_connection_new (*(DasomConnectionType *) message->data,
                                     dasom_server_get_default_engine (server), NULL);
  dasom_message_unref (message);
  connection->socket = socket;
  dasom_server_add_connection (server, connection);

  if (connection->type == DASOM_CONNECTION_DASOM_AGENT)
    server->agents_list = g_list_prepend (server->agents_list, connection);

  connection->source = g_socket_create_source (socket, G_IO_IN, NULL);
  connection->socket_connection = g_object_ref (socket_connection);
  g_source_set_can_recurse (connection->source, TRUE);
  g_source_set_callback (connection->source,
                         (GSourceFunc) on_incoming_message_dasom,
                         connection, NULL);
  g_source_attach (connection->source, server->main_context);

  return TRUE;
}
Esempio n. 12
0
/* Must *not* take the agent lock, since it’s called from within
 * component_set_io_context(), which holds the Component’s I/O lock. */
static void
socket_source_attach (SocketSource *socket_source, GMainContext *context)
{
  GSource *source;

  /* Create a source. */
  source = g_socket_create_source (socket_source->socket->fileno,
      G_IO_IN, NULL);
  g_source_set_callback (source, (GSourceFunc) component_io_cb,
      socket_source, NULL);

  /* Add the source. */
  nice_debug ("Attaching source %p (socket %p, FD %d) to context %p", source,
      socket_source->socket, g_socket_get_fd (socket_source->socket->fileno),
      context);

  g_assert (socket_source->source == NULL);
  socket_source->source = source;
  g_source_attach (source, context);
}
Esempio n. 13
0
void GMainLoopSource::schedule(const char* name, std::function<bool (GIOCondition)> function, GSocket* socket, GIOCondition condition, std::function<void ()> destroyFunction, GMainContext* context)
{
    cancel();

    ASSERT(!m_context.source);
    GCancellable* socketCancellable = g_cancellable_new();
    m_context = {
        adoptGRef(g_socket_create_source(socket, condition, socketCancellable)),
        nullptr, // cancellable
        adoptGRef(socketCancellable),
        nullptr, // voidCallback
        nullptr, // boolCallback
        WTF::move(function),
        WTF::move(destroyFunction)
    };

    ASSERT(m_status == Ready);
    m_status = Scheduled;
    g_source_set_name(m_context.source.get(), name);
    g_source_set_callback(m_context.source.get(), reinterpret_cast<GSourceFunc>(socketSourceCallback), this, nullptr);
    g_source_attach(m_context.source.get(), context);
}
Esempio n. 14
0
static gboolean net_createUDPSocket(struct node *n, guint classid)
{
    GError * err = NULL;
    GInetAddress *addr = n->netadr;
    guint port = 2300+n->classes[classid];

    syslog(LOG_DEBUG,"net_createSockets: Creating udp socket on port %u\n", port);

    GSocketAddress * sa = g_inet_socket_address_new(addr,port);

    n->udpsockets[classid].n = n;
    GSocket *socket = g_socket_new(G_SOCKET_FAMILY_IPV6,
                        G_SOCKET_TYPE_DATAGRAM,
                        G_SOCKET_PROTOCOL_UDP,
                        NULL);

    ub_assert(socket != NULL);

    if( g_socket_bind(socket, sa, TRUE, &err) == FALSE ){
        syslog(LOG_WARNING, "net_createSockets: Error while binding udp socket: %s\n", err->message);
        g_error_free(err);
        return FALSE;
    }

    GSource *source = g_socket_create_source(socket, G_IO_IN, NULL);
    ub_assert(source != NULL);
    g_source_set_callback(source, (GSourceFunc)udp_read,
            &(n->udpsockets[classid]) , NULL);
    g_source_attach(source, g_main_context_default());
    n->udpsockets[classid].socket = socket;
    n->udpsockets[classid].source = source;
    n->udpsockets[classid].socketaddress = sa;
    n->udpsockets[classid].classid = classid;

    //broadcast_addService(n->classes[classid]);
    return TRUE;
}
Esempio n. 15
0
static gboolean fusion_tls_output_stream_real_write_async_co (FusionTlsOutputStreamWriteAsyncData* _data_) {
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = NULL;
	_data_->_tmp0_ = _data_->self->priv->socket;
	_data_->_tmp1_ = 0;
	_data_->_tmp1_ = g_socket_condition_check (_data_->_tmp0_, G_IO_OUT);
	if (_data_->_tmp1_ == 0) {
		_data_->_tmp2_ = NULL;
		_data_->_tmp2_ = _data_->self->priv->socket;
		_data_->_tmp3_ = NULL;
		_data_->_tmp3_ = _data_->cancellable;
		_data_->_tmp4_ = NULL;
		_data_->_tmp4_ = g_socket_create_source (_data_->_tmp2_, (G_IO_OUT | G_IO_HUP) | G_IO_ERR, _data_->_tmp3_);
		_data_->source = _data_->_tmp4_;
		_data_->_tmp5_ = NULL;
		_data_->_tmp5_ = _data_->source;
		g_source_set_callback (_data_->_tmp5_, (GSourceFunc) _fusion_tls_output_stream_real_write_async_co_gsocket_source_func, _data_, NULL);
		_data_->_tmp6_ = NULL;
		_data_->_tmp6_ = _data_->source;
		_data_->_tmp7_ = NULL;
		_data_->_tmp7_ = g_main_context_get_thread_default ();
		g_source_attach (_data_->_tmp6_, _data_->_tmp7_);
		_data_->_state_ = 1;
		return FALSE;
		_state_1:
		;
		_g_source_unref0 (_data_->source);
	}
	_data_->_tmp9_ = NULL;
	_data_->_tmp9_ = _data_->self->priv->connection;
	_data_->_tmp10_ = NULL;
	_data_->_tmp10__length1 = 0;
	_data_->_tmp10_ = _data_->buffer;
	_data_->_tmp10__length1 = _data_->buffer_length1;
	_data_->_tmp11_ = NULL;
	_data_->_tmp11_ = _data_->cancellable;
	_data_->_tmp12_ = 0L;
	_data_->_tmp12_ = fusion_tls_connection_send (_data_->_tmp9_, _data_->_tmp10_, _data_->_tmp10__length1, _data_->_tmp11_, &_data_->_inner_error_);
	_data_->_tmp8_ = _data_->_tmp12_;
	if (_data_->_inner_error_ != NULL) {
		if (_data_->_inner_error_->domain == G_IO_ERROR) {
			g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
			g_error_free (_data_->_inner_error_);
			if (_data_->_state_ == 0) {
				g_simple_async_result_complete_in_idle (_data_->_async_result);
			} else {
				g_simple_async_result_complete (_data_->_async_result);
			}
			g_object_unref (_data_->_async_result);
			return FALSE;
		} else {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
			g_clear_error (&_data_->_inner_error_);
			return FALSE;
		}
	}
	_data_->result = _data_->_tmp8_;
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}
static void
_channel_accepted (TpChannel *channel,
    const GValue *addressv,
    const GError *in_error,
    gpointer user_data,
    GObject *obj)
{
  TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj;
  GSocketAddress *remote_address;
  GError *error = NULL;

  if (in_error != NULL)
    {
      DEBUG ("Failed to Accept Stream Tube: %s", in_error->message);

      operation_failed (self, in_error);
      return;
    }

  tp_cli_channel_type_stream_tube_connect_to_new_local_connection (
      TP_CHANNEL (self), new_local_connection_cb, NULL, NULL,
      G_OBJECT (self), &error);

  if (error != NULL)
    {
      DEBUG ("Failed to connect to NewLocalConnection signal");
      operation_failed (self, error);

      g_error_free (error);
      return;
    }

  remote_address = tp_g_socket_address_from_variant (self->priv->socket_type,
      addressv, &error);
  if (error != NULL)
    {
      DEBUG ("Failed to convert address: %s", error->message);

      operation_failed (self, error);
      g_error_free (error);
      return;
    }

  /* Connect to CM */
  g_socket_set_blocking (self->priv->client_socket, FALSE);
  g_socket_connect (self->priv->client_socket, remote_address, NULL, &error);

  if (error == NULL)
    {
      /* Socket is connected */
      client_socket_connected (self);
      goto out;
    }
  else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
    {
      /* We have to wait that the socket is connected */
      GSource *source;

      source = g_socket_create_source (self->priv->client_socket,
          G_IO_OUT, NULL);

      g_source_attach (source, g_main_context_get_thread_default ());

      g_source_set_callback (source, (GSourceFunc) client_socket_cb,
          self, NULL);

      g_error_free (error);
      g_source_unref (source);
    }
  else
    {
      DEBUG ("Failed to connect to CM: %s", error->message);

      operation_failed (self, error);

      g_error_free (error);
    }

out:
  g_object_unref (remote_address);
}
Esempio n. 17
0
static void
dasom_im_init (DasomIM *im)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  GSocketClient  *client;
  GSocketAddress *address;
  GSocket        *socket;
  GError         *error = NULL;

  address = g_unix_socket_address_new_with_type (DASOM_ADDRESS, -1,
                                                 G_UNIX_SOCKET_ADDRESS_ABSTRACT);
  client = g_socket_client_new ();
  im->connection = g_socket_client_connect (client,
                                            G_SOCKET_CONNECTABLE (address),
                                            NULL, &error);
  g_object_unref (address);
  g_object_unref (client);

  if (im->connection == NULL)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message);
    g_clear_error (&error);
    return;
  }

  socket = g_socket_connection_get_socket (im->connection);

  if (!socket)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, "Can't get socket");
    return;
  }

  DasomMessage *message;

  DasomConnectionType type = DASOM_CONNECTION_DASOM_IM;

  dasom_send_message (socket, DASOM_MESSAGE_CONNECT, &type, sizeof (DasomConnectionType), NULL);
  g_socket_condition_wait (socket, G_IO_IN, NULL, NULL);
  message = dasom_recv_message (socket);

  if (G_UNLIKELY (message == NULL ||
                  message->header->type != DASOM_MESSAGE_CONNECT_REPLY))
  {
    dasom_message_unref (message);
    g_error ("Couldn't connect to dasom daemon");
  }

  dasom_message_unref (message);

  im->result = g_slice_new0 (DasomResult);
  im->preedit_string = g_strdup ("");

  GMutex mutex;

  g_mutex_init (&mutex);
  g_mutex_lock (&mutex);

  if (G_UNLIKELY (dasom_im_sockets_context == NULL))
  {
    dasom_im_sockets_context = g_main_context_new ();
    dasom_im_sockets_context_ref_count++;
  }
  else
  {
    dasom_im_sockets_context = g_main_context_ref (dasom_im_sockets_context);
    dasom_im_sockets_context_ref_count++;
  }

  g_mutex_unlock (&mutex);

  /* when g_main_context_iteration(), iterate only sockets */
  im->sockets_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->sockets_context_source, TRUE);
  g_source_attach (im->sockets_context_source, dasom_im_sockets_context);
  g_source_set_callback (im->sockets_context_source,
                         (GSourceFunc) on_incoming_message,
                         im, NULL);

  im->default_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->default_context_source, TRUE);
  g_source_set_callback (im->default_context_source,
                         (GSourceFunc) on_incoming_message, im, NULL);
  g_source_attach (im->default_context_source, NULL);
}
Esempio n. 18
0
static gboolean
component_source_prepare (GSource *source, gint *timeout_)
{
  ComponentSource *component_source = (ComponentSource *) source;
  NiceAgent *agent;
  NiceComponent *component;
  GSList *parentl, *childl;

  agent = g_weak_ref_get (&component_source->agent_ref);
  if (!agent)
    return FALSE;

  /* Needed due to accessing the Component. */
  agent_lock ();

  if (!agent_find_component (agent,
          component_source->stream_id, component_source->component_id, NULL,
          &component))
    goto done;


  if (component->socket_sources_age ==
      component_source->component_socket_sources_age)
    goto done;

  /* If the age has changed, either
   *  - one or more new socket has been prepended
   *  - old sockets have been removed
   */

  /* Add the new child sources. */

  for (parentl = component->socket_sources; parentl; parentl = parentl->next) {
    SocketSource *parent_socket_source = parentl->data;
    SocketSource *child_socket_source;

    if (parent_socket_source->socket->fileno == NULL)
      continue;

    /* Iterating the list of socket sources every time isn't a big problem
     * because the number of pairs is limited ~100 normally, so there will
     * rarely be more than 10.
     */
    childl = g_slist_find_custom (component_source->socket_sources,
        parent_socket_source->socket, _find_socket_source);

    /* If we have reached this state, then all sources new sources have been
     * added, because they are always prepended.
     */
    if (childl)
      break;

    child_socket_source = g_slice_new0 (SocketSource);
    child_socket_source->socket = parent_socket_source->socket;
    child_socket_source->source =
        g_socket_create_source (child_socket_source->socket->fileno, G_IO_IN,
            NULL);
    g_source_set_dummy_callback (child_socket_source->source);
    g_source_add_child_source (source, child_socket_source->source);
    g_source_unref (child_socket_source->source);
    component_source->socket_sources =
        g_slist_prepend (component_source->socket_sources, child_socket_source);
  }


  for (childl = component_source->socket_sources;
       childl;) {
    SocketSource *child_socket_source = childl->data;
    GSList *next = childl->next;

    parentl = g_slist_find_custom (component->socket_sources,
      child_socket_source->socket, _find_socket_source);

    /* If this is not a currently used socket, remove the relevant source */
    if (!parentl) {
      g_source_remove_child_source (source, child_socket_source->source);
      g_slice_free (SocketSource, child_socket_source);
      component_source->socket_sources =
          g_slist_delete_link (component_source->socket_sources, childl);
    }

    childl = next;
  }


  /* Update the age. */
  component_source->component_socket_sources_age = component->socket_sources_age;

 done:

  agent_unlock_and_emit (agent);
  g_object_unref (agent);

  /* We can’t be sure if the ComponentSource itself needs to be dispatched until
   * poll() is called on all the child sources. */
  return FALSE;
}
static gboolean
g_network_monitor_netlink_initable_init (GInitable     *initable,
                                         GCancellable  *cancellable,
                                         GError       **error)
{
  GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable);
  gint sockfd, val;
  struct sockaddr_nl snl;

  /* We create the socket the old-school way because sockaddr_netlink
   * can't be represented as a GSocketAddress
   */
  sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  if (sockfd == -1)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      return FALSE;
    }

  snl.nl_family = AF_NETLINK;
  snl.nl_pid = snl.nl_pad = 0;
  snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE;
  if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      close (sockfd);
      return FALSE;
    }

  val = 1;
  if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &val, sizeof (val)) != 0)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                   _("Could not create network monitor: %s"),
                   g_strerror (errno));
      close (sockfd);
      return FALSE;
    }

  nl->priv->sock = g_socket_new_from_fd (sockfd, error);
  if (error)
    {
      g_prefix_error (error, "%s", _("Could not create network monitor: "));
      close (sockfd);
      return FALSE;
    }

  /* Request the current state */
  if (!request_dump (nl, error))
    return FALSE;

  /* And read responses; since we haven't yet marked the socket
   * non-blocking, each call will block until a message is received.
   */
  while (nl->priv->dump_networks)
    {
      if (!read_netlink_messages (NULL, G_IO_IN, nl))
        break;
    }

  g_socket_set_blocking (nl->priv->sock, FALSE);
  nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL);
  g_source_set_callback (nl->priv->source,
                         (GSourceFunc) read_netlink_messages, nl, NULL);
  g_source_attach (nl->priv->source,
                   g_main_context_get_thread_default ());

  return TRUE;
}
Esempio n. 20
0
static gboolean
gssdp_socket_source_do_init (GInitable                   *initable,
                             G_GNUC_UNUSED GCancellable  *cancellable,
                             GError                     **error)
{
        GSSDPSocketSource *self = NULL;
        GInetAddress *iface_address = NULL;
        GSocketAddress *bind_address = NULL;
        GInetAddress *group = NULL;
        GError *inner_error = NULL;
        GSocketFamily family;
        gboolean success = FALSE;

        self = GSSDP_SOCKET_SOURCE (initable);
        iface_address = g_inet_address_new_from_string (self->priv->host_ip);
        if (iface_address == NULL) {
                g_set_error (error,
                             GSSDP_ERROR,
                             GSSDP_ERROR_FAILED,
                             "Invalid host ip: %s",
                             self->priv->host_ip);

                goto error;
        }

        family = g_inet_address_get_family (iface_address);

        if (family == G_SOCKET_FAMILY_IPV4)
                group = g_inet_address_new_from_string (SSDP_ADDR);
        else {
                g_set_error_literal (error,
                                     GSSDP_ERROR,
                                     GSSDP_ERROR_FAILED,
                                     "IPv6 address");

                goto error;
        }


        /* Create socket */
        self->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
                                           G_SOCKET_TYPE_DATAGRAM,
                                           G_SOCKET_PROTOCOL_UDP,
                                           &inner_error);

        if (!self->priv->socket) {
                g_propagate_prefixed_error (error,
                                            inner_error,
                                            "Could not create socket");

                goto error;
        }

        /* Enable broadcasting */
        if (!gssdp_socket_enable_broadcast (self->priv->socket,
                                            TRUE,
                                            &inner_error)) {
                g_propagate_prefixed_error (error,
                                            inner_error,
                                            "Failed to enable broadcast");
                goto error;
        }

        /* TTL */
        if (!self->priv->ttl)
                /* UDA/1.0 says 4, UDA/1.1 says 2 */
                self->priv->ttl = 4;

        if (!gssdp_socket_set_ttl (self->priv->socket,
                                   self->priv->ttl,
                                   &inner_error)) {
                g_propagate_prefixed_error (error,
                                            inner_error,
                                            "Failed to set TTL to %u", self->priv->ttl);

                goto error;
        }

        /* Set up additional things according to the type of socket desired */
        if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
                /* Enable multicast loopback */
                if (!gssdp_socket_enable_loop (self->priv->socket,
                                               TRUE,
                                               &inner_error)) {
                        g_propagate_prefixed_error (
                                        error,
                                        inner_error,
                                        "Failed to enable loop-back");

                        goto error;
                }

                if (!gssdp_socket_mcast_interface_set (self->priv->socket,
                                                       iface_address,
                                                       &inner_error)) {
                        g_propagate_prefixed_error (
                                        error,
                                        inner_error,
                                        "Failed to set multicast interface");

                        goto error;
                }

#ifdef G_OS_WIN32
                bind_address = g_inet_socket_address_new (iface_address,
                                                          SSDP_PORT);
#else
                bind_address = g_inet_socket_address_new (group,
                                                          SSDP_PORT);
#endif
        } else {
                guint port = SSDP_PORT;

                /* Use user-supplied or random port for the socket source used
                 * by M-SEARCH */
                if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_SEARCH)
                        port = self->priv->port;

                bind_address = g_inet_socket_address_new (iface_address,
                                                          port);
        }

        /* Normally g_socket_bind does this, but it is disabled on
         * windows since SO_REUSEADDR has different semantics
         * there, also we nees SO_REUSEPORT on OpenBSD. This is a nop
         * everywhere else.
         */
        if (!gssdp_socket_reuse_address (self->priv->socket,
                                         TRUE,
                                         &inner_error)) {
                g_propagate_prefixed_error (
                                error,
                                inner_error,
                                "Failed to enable reuse");

                goto error;
        }

        /* Bind to requested port and address */
        if (!g_socket_bind (self->priv->socket,
                            bind_address,
                            TRUE,
                            &inner_error)) {
                g_propagate_prefixed_error (error,
                                            inner_error,
                                            "Failed to bind socket");

                goto error;
        }

        if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {

                 /* Subscribe to multicast channel */
                if (!gssdp_socket_mcast_group_join (self->priv->socket,
                                                    group,
                                                    iface_address,
                                                    &inner_error)) {
                        char *address = g_inet_address_to_string (group);
                        g_propagate_prefixed_error (error,
                                                    inner_error,
                                                    "Failed to join group %s",
                                                    address);
                        g_free (address);

                        goto error;
                }
        }

        self->priv->source = g_socket_create_source (self->priv->socket,
                                                     G_IO_IN | G_IO_ERR,
                                                     NULL);
        success = TRUE;

error:
        if (iface_address != NULL)
                g_object_unref (iface_address);
        if (bind_address != NULL)
                g_object_unref (bind_address);
        if (group != NULL)
                g_object_unref (group);
        if (!success)
                /* Be aware that inner_error has already been free'd by
                 * g_propagate_error(), so we cannot access its contents
                 * anymore. */
                if (error == NULL)
                        g_warning ("Failed to create socket source");

        return success;
}
Esempio n. 21
0
static gpointer
gst_net_client_clock_thread (gpointer data)
{
  GstNetClientClock *self = data;
  GstNetTimePacket *packet;
  GMainContext *ctx;
  GSourceFuncs funcs = { NULL, };
  GSource *source;
  GIOCondition cond;
  gboolean timeout;
  GSocket *socket = self->priv->socket;
  GError *err = NULL;
  GstClock *clock = data;

  GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket);

  g_socket_set_blocking (socket, TRUE);
  g_socket_set_timeout (socket, 0);

  ctx = g_main_context_new ();

  source = g_socket_create_source (socket, G_IO_IN, self->priv->cancel);
  g_source_set_name (source, "GStreamer net client clock thread socket");
  g_source_set_callback (source, (GSourceFunc) gst_net_client_clock_socket_cb,
      &cond, NULL);
  g_source_attach (source, ctx);
  g_source_unref (source);

  /* GSocket only support second granularity for timeouts, so roll our own
   * timeout source (so we don't have to create a new source whenever the
   * timeout changes, as we would have to do with the default timeout source) */
  funcs.prepare = gst_net_client_clock_timeout_source_prepare;
  funcs.check = gst_net_client_clock_timeout_source_check;
  funcs.dispatch = gst_net_client_clock_timeout_source_dispatch;
  funcs.finalize = NULL;
  source = g_source_new (&funcs, sizeof (GstNetClientClockTimeoutSource));
  ((GstNetClientClockTimeoutSource *) source)->clock = self;
  ((GstNetClientClockTimeoutSource *) source)->p_timeout = &timeout;
  g_source_set_name (source, "GStreamer net client clock timeout");
  g_source_attach (source, ctx);
  g_source_unref (source);

  while (!g_cancellable_is_cancelled (self->priv->cancel)) {
    cond = 0;
    timeout = FALSE;
    g_main_context_iteration (ctx, TRUE);

    if (g_cancellable_is_cancelled (self->priv->cancel))
      break;

    if (timeout) {
      /* timed out, let's send another packet */
      GST_DEBUG_OBJECT (self, "timed out");

      packet = gst_net_time_packet_new (NULL);

      packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self));

      GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->local_time));

      gst_net_time_packet_send (packet, self->priv->socket,
          self->priv->servaddr, NULL);

      g_free (packet);

      /* reset timeout (but are expecting a response sooner anyway) */
      self->priv->timeout_expiration =
          gst_util_get_timestamp () + gst_clock_get_timeout (clock);
      continue;
    }

    /* got data to read? */
    if ((cond & G_IO_IN)) {
      GstClockTime new_local;

      new_local = gst_clock_get_internal_time (GST_CLOCK (self));

      packet = gst_net_time_packet_receive (socket, NULL, &err);

      if (err != NULL) {
        GST_WARNING_OBJECT (self, "receive error: %s", err->message);
        g_error_free (err);
        err = NULL;
        continue;
      }

      GST_LOG_OBJECT (self, "got packet back");
      GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->local_time));
      GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (packet->remote_time));
      GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT,
          GST_TIME_ARGS (new_local));

      /* observe_times will reset the timeout */
      gst_net_client_clock_observe_times (self, packet->local_time,
          packet->remote_time, new_local);

      g_free (packet);
      continue;
    }

    if ((cond & (G_IO_ERR | G_IO_HUP))) {
      GST_DEBUG_OBJECT (self, "socket error?! %s", g_strerror (errno));
      g_usleep (G_USEC_PER_SEC / 10);
      continue;
    }
  }

  GST_INFO_OBJECT (self, "shutting down net client clock thread");
  g_main_context_unref (ctx);
  return NULL;
}
Esempio n. 22
0
File: main.c Progetto: dram/configs
int main(void)
{
	GSocket *sock;

	sock = create_socket();
	committed = g_string_new("");

	puts("Emacs-fcitx is ready.");

	while (TRUE) {
		GSource *source;
		GSocket *connection;
		GMainLoop *main_loop;

		if ((connection = g_socket_accept(sock, NULL, NULL)) == NULL) {
			perror("g_socket_accept");
			exit(1);
		}

		puts("Opening connection.");

		client = fcitx_client_new();

		g_signal_connect(client, "connected",
				 G_CALLBACK(connect_cb), NULL);
		g_signal_connect(client, "disconnected",
				 G_CALLBACK(destroy_cb), NULL);
		g_signal_connect(client, "enable-im",
				 G_CALLBACK(enable_im_cb), NULL);
		g_signal_connect(client, "close-im",
				 G_CALLBACK(close_im_cb), NULL);
		g_signal_connect(client, "forward-key",
				 G_CALLBACK(forward_key_cb), NULL);
		g_signal_connect(client, "commit-string",
				 G_CALLBACK(commit_string_cb), NULL);
		g_signal_connect(client,
				 "update-client-side-ui",
				 G_CALLBACK(update_client_side_ui_cb),
				 connection);

		main_loop = g_main_loop_new(NULL, FALSE);

		source = g_socket_create_source(
			connection,
			(GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR), NULL);

		g_source_set_callback(
			source, (GSourceFunc)source_cb, main_loop, NULL);

		g_source_attach(source, NULL);

		g_main_loop_run(main_loop);

		puts("main loop finished.");

		g_socket_close(connection, NULL);

		g_object_unref(client);
		g_source_unref(source);
		g_object_unref(connection);
		g_main_loop_unref(main_loop);
	}

	g_object_unref(sock);
	g_string_free(committed, TRUE);

	return 0;
}
Esempio n. 23
0
int init_netlink(GMainLoop *loop) {
	GSocket *gsocket = NULL;
	int socket_fd = 0;
	GSource *source;
	struct sockaddr_nl my_nla;
	struct nlmsghdr *nl_hdr;
	char buff[BUFF_SIZE];
	struct cn_msg *cn_hdr;
	enum proc_cn_mcast_op *mcop_msg;


	/* create socket */
	/*
	 * Create an endpoint for communication. Use the kernel user
	 * interface device (PF_NETLINK) which is a datagram oriented
	 * service (SOCK_DGRAM). The protocol used is the connector
	 * protocol (NETLINK_CONNECTOR)
	 */
	socket_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);

	if (socket_fd == -1) {
		g_warning ("netlink: failed to create socket: %s", g_strerror(errno));
		return 1;
	}

	my_nla.nl_family = AF_NETLINK;
	my_nla.nl_groups = CN_IDX_PROC;
	my_nla.nl_pid = getpid();
	my_nla.nl_pad = 0;

	if (bind(socket_fd, (struct sockaddr *)&my_nla, sizeof(my_nla)) < 0) {
		g_warning("netlink: binding sk_nl error: %s\n", g_strerror(errno));
		g_warning("netlink: realtime monitoring disabled. compile kernel with PROC_EVENTS enabled");
		goto out;
	}

	gsocket = g_socket_new_from_fd(socket_fd, NULL);
	if(gsocket == NULL) {
		g_warning("netlink: can't create socket");
		goto out;
	}

	nl_hdr = (struct nlmsghdr *)buff;
	cn_hdr = (struct cn_msg *)NLMSG_DATA(nl_hdr);
	mcop_msg = (enum proc_cn_mcast_op*)&cn_hdr->data[0];
	g_debug("netlink: sending proc connector: PROC_CN_MCAST_LISTEN... ");
	memset(buff, 0, sizeof(buff));
	*mcop_msg = PROC_CN_MCAST_LISTEN;

	/* test if PROC_CN_MCAST_LISTEN will success */
	netlink_proc_listening = FALSE;
	g_socket_set_timeout(gsocket, 10);

	/* fill the netlink header */
	nl_hdr->nlmsg_len = SEND_MESSAGE_LEN;
	nl_hdr->nlmsg_type = NLMSG_DONE;
	nl_hdr->nlmsg_flags = 0;
	nl_hdr->nlmsg_seq = 0;
	nl_hdr->nlmsg_pid = getpid();

	/* fill the connector header */
	cn_hdr->id.idx = CN_IDX_PROC;
	cn_hdr->id.val = CN_VAL_PROC;
	cn_hdr->seq = 0;
	cn_hdr->ack = 0;
	cn_hdr->len = sizeof(enum proc_cn_mcast_op);
	g_debug("netlink: sending netlink message len=%d, cn_msg len=%d\n",
		nl_hdr->nlmsg_len, (int) sizeof(struct cn_msg));
	if (send(socket_fd, nl_hdr, nl_hdr->nlmsg_len, 0) != nl_hdr->nlmsg_len) {
		g_warning("netlink: failed to send proc connector mcast ctl op!: %s\n",
			g_strerror(errno));
	}
	g_debug("sent\n");

	/* socket has data */
	source = g_socket_create_source (gsocket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
	g_source_set_callback (source, (GSourceFunc) nl_connection_handler, loop, NULL);
	g_source_attach (source, NULL);

	return 0;
out:
	return 1;

}