Exemple #1
0
/**
 * g_vfs_ftp_connection_accept_data_connection:
 * @conn: a listening connection
 * @cancellable: cancellable to interrupt wait
 * @error: %NULL or location to take a potential error
 *
 * Opens a data connection for @conn by accepting an incoming connection on the
 * address it is listening on via g_vfs_ftp_connection_listen_data_connection(),
 * which must have been called prior to this function.
 * If this function succeeds, a data connection will have been opened, and calls
 * to g_vfs_ftp_connection_get_data_stream() will work.
 *
 * Returns: %TRUE if a connection was successfully acquired
 **/
gboolean
g_vfs_ftp_connection_accept_data_connection (GVfsFtpConnection *conn,
                                             GCancellable *     cancellable,
                                             GError **          error)
{
  GSocket *accepted;
  GCancellable *timer;
  gulong cancel_cb_id;
  GIOCondition condition;

  g_return_val_if_fail (conn != NULL, FALSE);
  g_return_val_if_fail (conn->data == NULL, FALSE);
  g_return_val_if_fail (G_IS_SOCKET (conn->listen_socket), FALSE);

  timer = g_cancellable_new ();
  cancel_cb_id = g_cancellable_connect (cancellable, 
                                        G_CALLBACK (cancel_timer_cb),
                                        timer,
                                        NULL);
  g_object_ref (timer);
  g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
                              G_VFS_FTP_TIMEOUT_IN_SECONDS,
                              cancel_cancellable,
                              timer,
                              g_object_unref);

  condition = g_socket_condition_wait (conn->listen_socket, G_IO_IN, timer, error);

  g_cancellable_disconnect (cancellable, cancel_cb_id);
  g_object_unref (timer);

  if ((condition & G_IO_IN) == 0)
    {
      if (g_cancellable_is_cancelled (timer) &&
          !g_cancellable_is_cancelled (cancellable))
        {
          g_clear_error (error);
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection. "
                                 "Maybe your router does not support this?"));
        }
      else if (error && *error == NULL)
        {
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection."));
        }
      return FALSE;
    }

  accepted = g_socket_accept (conn->listen_socket, cancellable, error);
  if (accepted == NULL)
    return FALSE;

  conn->data = G_IO_STREAM (g_socket_connection_factory_create_connection (accepted));
  g_object_unref (accepted);
  enable_nodelay (G_SOCKET_CONNECTION (conn->data));
  return TRUE;
}
Exemple #2
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);
	}
    }
}
Exemple #3
0
/**
 * g_socket_listener_accept_socket:
 * @listener: a #GSocketListener
 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Blocks waiting for a client to connect to any of the sockets added
 * to the listener. Returns the #GSocket that was accepted.
 *
 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
 * which is often the case, then you should use g_socket_listener_accept()
 * instead.
 *
 * If @source_object is not %NULL it will be filled out with the source
 * object specified when the corresponding socket or address was added
 * to the listener.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the cancellable object from another thread. If the operation
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 *
 * Returns: (transfer full): a #GSocket on success, %NULL on error.
 *
 * Since: 2.22
 */
GSocket *
g_socket_listener_accept_socket (GSocketListener  *listener,
				 GObject         **source_object,
				 GCancellable     *cancellable,
				 GError          **error)
{
  GSocket *accept_socket, *socket;

  g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);

  if (!check_listener (listener, error))
    return NULL;

  if (listener->priv->sockets->len == 1)
    {
      accept_socket = listener->priv->sockets->pdata[0];
      if (!g_socket_condition_wait (accept_socket, G_IO_IN,
				    cancellable, error))
	return NULL;
    }
  else
    {
      GList *sources;
      struct AcceptData data;
      GMainLoop *loop;

      if (listener->priv->main_context == NULL)
	listener->priv->main_context = g_main_context_new ();

      loop = g_main_loop_new (listener->priv->main_context, FALSE);
      data.loop = loop;
      sources = add_sources (listener,
			     accept_callback,
			     &data,
			     cancellable,
			     listener->priv->main_context);
      g_main_loop_run (loop);
      accept_socket = data.socket;
      free_sources (sources);
      g_main_loop_unref (loop);
    }

  if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
    return NULL;

  if (source_object)
    *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);

  return socket;
}
static gssize
sctp_socket_receive_with_blocking (GSocket * socket, gchar * buffer, gsize size,
    gboolean blocking, GCancellable * cancellable, guint * streamid,
    GError ** error)
{
  gssize ret;

  if (g_socket_is_closed (socket)) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Socket is already closed");
    return -1;
  }

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  while (TRUE) {
    struct sctp_sndrcvinfo sndrcvinfo;
    int flags = 0;

    if (blocking &&
        !g_socket_condition_wait (socket, G_IO_IN, cancellable, error))
      return -1;

    if ((ret = sctp_recvmsg (g_socket_get_fd (socket), buffer, size, NULL, 0,
                &sndrcvinfo, &flags)) < 0) {
      if (errno == EINTR)
        continue;

      if (blocking) {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
          continue;
      }

      g_set_error (error, G_IO_ERROR, errno, "Error receiving data: %s",
          strerror (errno));

      return -1;
    }

    *streamid = sndrcvinfo.sinfo_stream;
    break;
  }

  return ret;
}
static gssize
sctp_socket_send_with_blocking (GSocket * socket, guint streamid,
    guint32 timetolive, const gchar * buffer, gsize size, gboolean blocking,
    GCancellable * cancellable, GError ** error)
{
  gssize ret;

  if (g_socket_is_closed (socket)) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Socket is already closed");
    return -1;
  }

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  while (TRUE) {
    if (blocking &&
        !g_socket_condition_wait (socket, G_IO_OUT, cancellable, error))
      return -1;

    if ((ret = sctp_sendmsg (g_socket_get_fd (socket), buffer, size, NULL, 0,
                0, 0, streamid, timetolive, 0)) < 0) {
      if (errno == EINTR)
        continue;

      if (blocking) {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
          continue;
      }

      g_set_error (error, G_IO_ERROR, errno, "Error sending data: %s",
          strerror (errno));
      return -1;
    }
    break;
  }

  return ret;
}
KmsSCTPResult
kms_sctp_connection_receive (KmsSCTPConnection * conn, KmsSCTPMessage * message,
    GCancellable * cancellable, GError ** err)
{
  GIOCondition condition;
  guint streamid;

  g_return_val_if_fail (conn != NULL, KMS_SCTP_ERROR);
  g_return_val_if_fail (conn->socket != NULL, KMS_SCTP_ERROR);

  if (!g_socket_condition_wait (conn->socket,
          G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, cancellable, err)) {
    return KMS_SCTP_ERROR;
  }

  condition = g_socket_condition_check (conn->socket,
      G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP);

  if ((condition & G_IO_ERR)) {
    g_set_error (err, KMS_SCTP_CONNECTION_ERROR, KMS_CONNECTION_READ_ERROR,
        "Socket in error state");
    return KMS_SCTP_ERROR;
  } else if ((condition & G_IO_HUP)) {
    g_set_error (err, KMS_SCTP_CONNECTION_ERROR, KMS_CONNECTION_READ_ERROR,
        "Connection closed");
    return KMS_SCTP_EOF;
  }

  message->used = sctp_socket_receive (conn->socket, message->buf,
      message->size, cancellable, &streamid, err);

  GST_LOG ("Receive data on stream id %d", streamid);

  if (message->used == 0)
    return KMS_SCTP_EOF;
  else if (message->used < 0)
    return KMS_SCTP_ERROR;
  else
    return KMS_SCTP_OK;
}
Exemple #7
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);
}
Exemple #8
0
static GstFlowReturn
gst_tcp_mix_src_pad_read (GstTCPMixSrcPad * pad, GstBuffer ** outbuf)
{
  GstTCPMixSrc *src = GST_TCP_MIX_SRC (GST_PAD_PARENT (pad));
  gssize avail, receivedBytes;
  GstMapInfo map;
  GError *err = NULL;

  /* if we have a client, wait for read */
  GST_LOG_OBJECT (pad, "asked for a buffer");

  if (!pad->client) {
    if (src->mode == MODE_LOOP)
      goto loop_read;
    else
      goto no_client;
  }

  /* read the buffer header */

read_available_bytes:
  avail = g_socket_get_available_bytes (pad->client);
  if (avail < 0) {
    goto socket_get_available_bytes_error;
  } else if (avail == 0) {
    GIOCondition condition;

    if (!g_socket_condition_wait (pad->client,
            G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, pad->cancellable, &err))
      goto socket_condition_wait_error;

    condition = g_socket_condition_check (pad->client,
        G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP);

    if ((condition & G_IO_ERR))
      goto socket_condition_error;
    else if ((condition & G_IO_HUP))
      goto socket_condition_hup;

    avail = g_socket_get_available_bytes (pad->client);
    if (avail < 0)
      goto socket_get_available_bytes_error;
  }

  if (0 < avail) {
    gsize readBytes = MIN (avail, MAX_READ_SIZE);
    *outbuf = gst_buffer_new_and_alloc (readBytes);
    gst_buffer_map (*outbuf, &map, GST_MAP_READWRITE);
    receivedBytes = g_socket_receive (pad->client, (gchar *) map.data,
        readBytes, pad->cancellable, &err);
  } else {
    /* Connection closed */
    receivedBytes = 0;
    *outbuf = NULL;
  }

  if (receivedBytes == 0)
    goto socket_connection_closed;
  else if (receivedBytes < 0)
    goto socket_receive_error;

  gst_buffer_unmap (*outbuf, &map);
  gst_buffer_resize (*outbuf, 0, receivedBytes);

#if 0
  GST_LOG_OBJECT (pad,
      "Returning buffer from _get of size %" G_GSIZE_FORMAT
      ", ts %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
      ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
      gst_buffer_get_size (*outbuf),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*outbuf)),
      GST_TIME_ARGS (GST_BUFFER_DURATION (*outbuf)),
      GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf));
#endif

  g_clear_error (&err);

  return GST_FLOW_OK;

  /* Handling Errors */
no_client:
  {
    GST_ELEMENT_ERROR (pad, RESOURCE, READ, (NULL),
        ("No client socket (%s)", GST_PAD_NAME (pad)));

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_ERROR;
  }

socket_get_available_bytes_error:
  {
    GST_ELEMENT_ERROR (pad, RESOURCE, READ, (NULL),
        ("Failed to get available bytes from socket"));

    gst_tcp_mix_src_pad_reset (pad);

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_ERROR;
  }

socket_condition_wait_error:
  {
    GST_ELEMENT_ERROR (pad, RESOURCE, READ, (NULL),
        ("Select failed: %s", err->message));
    g_clear_error (&err);

    gst_tcp_mix_src_pad_reset (pad);

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_ERROR;
  }

socket_condition_error:
  {
    GST_ELEMENT_ERROR (pad, RESOURCE, READ, (NULL), ("Socket in error state"));
    *outbuf = NULL;

    gst_tcp_mix_src_pad_reset (pad);

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_ERROR;
  }

socket_condition_hup:
  {
    GST_DEBUG_OBJECT (pad, "Connection closed");
    *outbuf = NULL;

    gst_tcp_mix_src_pad_reset (pad);

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_EOS;
  }

socket_connection_closed:
  {
    GST_DEBUG_OBJECT (pad, "Connection closed");
    if (*outbuf) {
      gst_buffer_unmap (*outbuf, &map);
      gst_buffer_unref (*outbuf);
    }
    *outbuf = NULL;

    gst_tcp_mix_src_pad_reset (pad);

    if (src->mode == MODE_LOOP)
      goto loop_read;
    return GST_FLOW_EOS;
  }

socket_receive_error:
  {
    gst_buffer_unmap (*outbuf, &map);
    gst_buffer_unref (*outbuf);
    *outbuf = NULL;

    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (pad, "Cancelled reading from socket");

      if (src->mode == MODE_LOOP)
        goto loop_read;
      return GST_FLOW_FLUSHING;
    } else {
      GST_ELEMENT_ERROR (pad, RESOURCE, READ, (NULL),
          ("Failed to read from socket: %s", err->message));

      if (src->mode == MODE_LOOP)
        goto loop_read;
      return GST_FLOW_ERROR;
    }
  }

loop_read:
  {
#if 0
    GstEvent *event = gst_event_new_flush_start ();

    if (!gst_pad_push_event (pad, event)) {
      GST_ERROR_OBJECT (src, "Failed to flush data on %s.%s",
          GST_ELEMENT_NAME (src), GST_PAD_NAME (pad));
    }
#endif

#if 0
    GST_DEBUG_OBJECT (pad, "Looping");
#endif

    if (src->fill == FILL_NONE) {
      gst_tcp_mix_src_pad_wait_for_client (pad);
      goto read_available_bytes;
    }

    enum
    { buffer_size = 1024 };
    *outbuf = gst_buffer_new_and_alloc (buffer_size);

    switch (src->fill) {
      case FILL_ZERO:
        break;
      case FILL_RAND:
      {
        guchar *p;
        gst_buffer_map (*outbuf, &map, GST_MAP_READWRITE);
        for (p = map.data; p < map.data + buffer_size; p += 4) {
          *((int *) p) = rand ();
        }
      } break;
    }
    return GST_FLOW_OK;
  }
}
gssize fusion_tls_connection_send (FusionTLSConnection* self, guint8* buffer, int buffer_length1, GCancellable* cancellable, GError** error) {
	gssize result = 0L;
	gssize ret = 0L;
	GSocket* _tmp0_ = NULL;
	gboolean _tmp1_ = FALSE;
	GCancellable* _tmp3_ = NULL;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, 0L);
	g_warning ("TLSConnection.vala:123: SEND");
	_tmp0_ = self->priv->socket;
	_tmp1_ = g_socket_is_closed (_tmp0_);
	if (_tmp1_) {
		GError* _tmp2_ = NULL;
		_tmp2_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "Socket is already closed");
		_inner_error_ = _tmp2_;
		if (_inner_error_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error_);
			return 0L;
		} else {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return 0L;
		}
	}
	_tmp3_ = cancellable;
	g_cancellable_set_error_if_cancelled (_tmp3_, &_inner_error_);
	if (_inner_error_ != NULL) {
		if (_inner_error_->domain == G_IO_ERROR) {
			g_propagate_error (error, _inner_error_);
			return 0L;
		} else {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return 0L;
		}
	}
	while (TRUE) {
		gboolean _tmp4_ = FALSE;
		GSocket* _tmp5_ = NULL;
		gboolean _tmp6_ = FALSE;
		gboolean _tmp11_ = FALSE;
		struct gnutls_session_int* _tmp12_ = NULL;
		guint8* _tmp13_ = NULL;
		gint _tmp13__length1 = 0;
		guint8* _tmp14_ = NULL;
		gint _tmp14__length1 = 0;
		gssize _tmp15_ = 0L;
		gssize _tmp16_ = 0L;
		_tmp5_ = self->priv->socket;
		_tmp6_ = g_socket_get_blocking (_tmp5_);
		if (_tmp6_) {
			gboolean _tmp7_ = FALSE;
			GSocket* _tmp8_ = NULL;
			GCancellable* _tmp9_ = NULL;
			gboolean _tmp10_ = FALSE;
			_tmp8_ = self->priv->socket;
			_tmp9_ = cancellable;
			_tmp10_ = g_socket_condition_wait (_tmp8_, G_IO_OUT, _tmp9_, &_inner_error_);
			_tmp7_ = _tmp10_;
			if (_inner_error_ != NULL) {
				if (_inner_error_->domain == G_IO_ERROR) {
					g_propagate_error (error, _inner_error_);
					return 0L;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
					g_clear_error (&_inner_error_);
					return 0L;
				}
			}
			_tmp4_ = !_tmp7_;
		} else {
			_tmp4_ = FALSE;
		}
		_tmp11_ = _tmp4_;
		if (_tmp11_) {
			result = (gssize) (-1);
			return result;
		}
		_tmp12_ = self->tls_session;
		_tmp13_ = buffer;
		_tmp13__length1 = buffer_length1;
		_tmp14_ = buffer;
		_tmp14__length1 = buffer_length1;
		_tmp15_ = gnutls_record_send (_tmp12_, _tmp13_, (gsize) _tmp14__length1);
		ret = _tmp15_;
		_tmp16_ = ret;
		if (_tmp16_ < ((gssize) 0)) {
			int ecode = 0;
			gssize _tmp17_ = 0L;
			int _tmp18_ = 0;
			gboolean _tmp19_ = FALSE;
			GSocket* _tmp20_ = NULL;
			gboolean _tmp21_ = FALSE;
			gboolean _tmp23_ = FALSE;
			int _tmp24_ = 0;
			_tmp17_ = ret;
			ecode = (int) _tmp17_;
			_tmp18_ = ecode;
			if (_tmp18_ == GNUTLS_E_INTERRUPTED) {
				continue;
			}
			_tmp20_ = self->priv->socket;
			_tmp21_ = g_socket_get_blocking (_tmp20_);
			if (_tmp21_) {
				int _tmp22_ = 0;
				_tmp22_ = ecode;
				_tmp19_ = _tmp22_ == GNUTLS_E_AGAIN;
			} else {
				_tmp19_ = FALSE;
			}
			_tmp23_ = _tmp19_;
			if (_tmp23_) {
				continue;
			}
			_tmp24_ = ecode;
			fusion_tls_connection_handle_error (self, _tmp24_, 2, &_inner_error_);
			if (_inner_error_ != NULL) {
				if (_inner_error_->domain == G_IO_ERROR) {
					g_propagate_error (error, _inner_error_);
					return 0L;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
					g_clear_error (&_inner_error_);
					return 0L;
				}
			}
			continue;
		}
		break;
	}
	result = ret;
	return result;
}
Exemple #10
0
static GstFlowReturn
gst_tcp_server_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
  GstTCPServerSrc *src;
  GstFlowReturn ret = GST_FLOW_OK;
  gssize rret, avail;
  gsize read;
  GError *err = NULL;
  GstMapInfo map;

  src = GST_TCP_SERVER_SRC (psrc);

  if (!GST_OBJECT_FLAG_IS_SET (src, GST_TCP_SERVER_SRC_OPEN))
    goto wrong_state;

  if (!src->client_socket) {
    /* wait on server socket for connections */
    src->client_socket =
        g_socket_accept (src->server_socket, src->cancellable, &err);
    if (!src->client_socket)
      goto accept_error;
    /* now read from the socket. */
  }

  /* if we have a client, wait for read */
  GST_LOG_OBJECT (src, "asked for a buffer");

  /* read the buffer header */
  avail = g_socket_get_available_bytes (src->client_socket);
  if (avail < 0) {
    goto get_available_error;
  } else if (avail == 0) {
    GIOCondition condition;

    if (!g_socket_condition_wait (src->client_socket,
            G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, src->cancellable, &err))
      goto select_error;

    condition =
        g_socket_condition_check (src->client_socket,
        G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP);

    if ((condition & G_IO_ERR)) {
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
          ("Socket in error state"));
      *outbuf = NULL;
      ret = GST_FLOW_ERROR;
      goto done;
    } else if ((condition & G_IO_HUP)) {
      GST_DEBUG_OBJECT (src, "Connection closed");
      *outbuf = NULL;
      ret = GST_FLOW_EOS;
      goto done;
    }
    avail = g_socket_get_available_bytes (src->client_socket);
    if (avail < 0)
      goto get_available_error;
  }

  if (avail > 0) {
    read = MIN (avail, MAX_READ_SIZE);
    *outbuf = gst_buffer_new_and_alloc (read);
    gst_buffer_map (*outbuf, &map, GST_MAP_READWRITE);
    rret =
        g_socket_receive (src->client_socket, (gchar *) map.data, read,
        src->cancellable, &err);
  } else {
    /* Connection closed */
    rret = 0;
    *outbuf = NULL;
    read = 0;
  }

  if (rret == 0) {
    GST_DEBUG_OBJECT (src, "Connection closed");
    ret = GST_FLOW_EOS;
    if (*outbuf) {
      gst_buffer_unmap (*outbuf, &map);
      gst_buffer_unref (*outbuf);
    }
    *outbuf = NULL;
  } else if (rret < 0) {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      ret = GST_FLOW_FLUSHING;
      GST_DEBUG_OBJECT (src, "Cancelled reading from socket");
    } else {
      ret = GST_FLOW_ERROR;
      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
          ("Failed to read from socket: %s", err->message));
    }
    gst_buffer_unmap (*outbuf, &map);
    gst_buffer_unref (*outbuf);
    *outbuf = NULL;
  } else {
    ret = GST_FLOW_OK;
    gst_buffer_unmap (*outbuf, &map);
    gst_buffer_resize (*outbuf, 0, rret);

    GST_LOG_OBJECT (src,
        "Returning buffer from _get of size %" G_GSIZE_FORMAT ", ts %"
        GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT
        ", offset %" G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
        gst_buffer_get_size (*outbuf),
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (*outbuf)),
        GST_TIME_ARGS (GST_BUFFER_DURATION (*outbuf)),
        GST_BUFFER_OFFSET (*outbuf), GST_BUFFER_OFFSET_END (*outbuf));
  }
  g_clear_error (&err);

done:
  return ret;

wrong_state:
  {
    GST_DEBUG_OBJECT (src, "connection to closed, cannot read data");
    return GST_FLOW_FLUSHING;
  }
accept_error:
  {
    if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
      GST_DEBUG_OBJECT (src, "Cancelled accepting of client");
    } else {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Failed to accept client: %s", err->message));
    }
    g_clear_error (&err);
    return GST_FLOW_ERROR;
  }
select_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Select failed: %s", err->message));
    g_clear_error (&err);
    return GST_FLOW_ERROR;
  }
get_available_error:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("Failed to get available bytes from socket"));
    return GST_FLOW_ERROR;
  }
}