unixfd: Add support for abstract socket

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5328>
This commit is contained in:
Xavier Claessens 2023-10-23 15:11:23 -04:00 committed by GStreamer Marge Bot
parent d44aa71f24
commit 47c56e3865
4 changed files with 92 additions and 22 deletions

View file

@ -32,6 +32,7 @@
#include "gstunixfd.h"
#include <gio/gunixfdmessage.h>
#include <gio/gunixsocketaddress.h>
typedef struct
{
@ -171,6 +172,42 @@ gst_unix_fd_parse_caps (gchar * payload, gsize payload_size, gchar ** caps_str)
return TRUE;
}
GSocket *
gst_unix_fd_socket_new (const gchar * socket_path,
GUnixSocketAddressType socket_type, GSocketAddress ** address,
GError ** error)
{
if (socket_path == NULL) {
g_set_error_literal (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
"Socket path is NULL");
return NULL;
}
switch (socket_type) {
case G_UNIX_SOCKET_ADDRESS_PATH:
case G_UNIX_SOCKET_ADDRESS_ABSTRACT:
case G_UNIX_SOCKET_ADDRESS_ABSTRACT_PADDED:
*address =
g_unix_socket_address_new_with_type (socket_path, -1, socket_type);
break;
default:
{
gchar *str =
g_enum_to_string (G_TYPE_UNIX_SOCKET_ADDRESS_TYPE, socket_type);
g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
"Unsupported UNIX socket type %s", str);
g_free (str);
return NULL;
}
}
GSocket *socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT, error);
if (socket == NULL)
g_clear_object (address);
return socket;
}
static gboolean
plugin_init (GstPlugin * plugin)
{

View file

@ -79,6 +79,10 @@ gboolean gst_unix_fd_parse_release_buffer(gchar *payload, gsize payload_size,
gboolean gst_unix_fd_parse_caps(gchar *payload, gsize payload_size,
gchar **caps_str);
GSocket *gst_unix_fd_socket_new(const gchar *socket_path,
GUnixSocketAddressType socket_type, GSocketAddress **address,
GError **error);
GST_ELEMENT_REGISTER_DECLARE (unixfdsrc);
GST_ELEMENT_REGISTER_DECLARE (unixfdsink);

View file

@ -78,6 +78,7 @@ struct _GstUnixFdSink
GMainLoop *loop;
gchar *socket_path;
GUnixSocketAddressType socket_type;
GSocket *socket;
GSource *source;
@ -91,10 +92,13 @@ G_DEFINE_TYPE (GstUnixFdSink, gst_unix_fd_sink, GST_TYPE_BASE_SINK);
GST_ELEMENT_REGISTER_DEFINE (unixfdsink, "unixfdsink", GST_RANK_NONE,
GST_TYPE_UNIX_FD_SINK);
#define DEFAULT_SOCKET_TYPE G_UNIX_SOCKET_ADDRESS_PATH
enum
{
PROP_0,
PROP_SOCKET_PATH,
PROP_SOCKET_TYPE,
};
@ -150,6 +154,14 @@ gst_unix_fd_sink_set_property (GObject * object, guint prop_id,
g_free (self->socket_path);
self->socket_path = g_value_dup_string (value);
break;
case PROP_SOCKET_TYPE:
if (self->socket) {
GST_WARNING_OBJECT (self,
"Can only change socket type in NULL or READY state");
break;
}
self->socket_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -170,6 +182,9 @@ gst_unix_fd_sink_get_property (GObject * object, guint prop_id,
case PROP_SOCKET_PATH:
g_value_set_string (value, self->socket_path);
break;
case PROP_SOCKET_TYPE:
g_value_set_enum (value, self->socket_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -321,17 +336,9 @@ gst_unix_fd_sink_start (GstBaseSink * bsink)
GST_OBJECT_LOCK (self);
if (self->socket_path == NULL) {
GST_ERROR_OBJECT (self, "Socket path is NULL");
ret = FALSE;
goto out;
}
addr = g_unix_socket_address_new (self->socket_path);
self->socket =
g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT, &error);
gst_unix_fd_socket_new (self->socket_path, self->socket_type, &addr,
&error);
if (self->socket == NULL) {
GST_ERROR_OBJECT (self, "Failed to create UNIX socket: %s", error->message);
ret = FALSE;
@ -378,7 +385,9 @@ gst_unix_fd_sink_stop (GstBaseSink * bsink)
g_clear_object (&self->socket);
gst_clear_caps (&self->caps);
g_hash_table_remove_all (self->clients);
g_unlink (self->socket_path);
if (self->socket_type == G_UNIX_SOCKET_ADDRESS_PATH)
g_unlink (self->socket_path);
return TRUE;
}
@ -607,4 +616,11 @@ gst_unix_fd_sink_class_init (GstUnixFdSinkClass * klass)
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_SOCKET_TYPE,
g_param_spec_enum ("socket-type", "Socket type",
"The type of underlying socket",
G_TYPE_UNIX_SOCKET_ADDRESS_TYPE, DEFAULT_SOCKET_TYPE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
GST_PARAM_MUTABLE_READY));
}

View file

@ -42,7 +42,6 @@
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gunixfdmessage.h>
#include <gio/gunixsocketaddress.h>
GST_DEBUG_CATEGORY (unixfdsrc_debug);
@ -62,6 +61,7 @@ struct _GstUnixFdSrc
GstPushSrc parent;
gchar *socket_path;
GUnixSocketAddressType socket_type;
GSocket *socket;
GCancellable *cancellable;
@ -74,10 +74,13 @@ G_DEFINE_TYPE (GstUnixFdSrc, gst_unix_fd_src, GST_TYPE_PUSH_SRC);
GST_ELEMENT_REGISTER_DEFINE (unixfdsrc, "unixfdsrc", GST_RANK_NONE,
GST_TYPE_UNIX_FD_SRC);
#define DEFAULT_SOCKET_TYPE G_UNIX_SOCKET_ADDRESS_PATH
enum
{
PROP_0,
PROP_SOCKET_PATH,
PROP_SOCKET_TYPE,
};
typedef struct
@ -158,6 +161,14 @@ gst_unix_fd_src_set_property (GObject * object, guint prop_id,
g_free (self->socket_path);
self->socket_path = g_value_dup_string (value);
break;
case PROP_SOCKET_TYPE:
if (self->socket) {
GST_WARNING_OBJECT (self,
"Can only change socket type in NULL or READY state");
break;
}
self->socket_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -178,6 +189,9 @@ gst_unix_fd_src_get_property (GObject * object, guint prop_id,
case PROP_SOCKET_PATH:
g_value_set_string (value, self->socket_path);
break;
case PROP_SOCKET_TYPE:
g_value_set_enum (value, self->socket_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -198,17 +212,9 @@ gst_unix_fd_src_start (GstBaseSrc * bsrc)
GST_OBJECT_LOCK (self);
if (self->socket_path == NULL) {
GST_ERROR_OBJECT (self, "Socket path is NULL");
ret = FALSE;
goto out;
}
addr = g_unix_socket_address_new (self->socket_path);
self->socket =
g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT, &error);
gst_unix_fd_socket_new (self->socket_path, self->socket_type, &addr,
&error);
if (self->socket == NULL) {
GST_ERROR_OBJECT (self, "Failed to create UNIX socket: %s", error->message);
ret = FALSE;
@ -483,4 +489,11 @@ gst_unix_fd_src_class_init (GstUnixFdSrcClass * klass)
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY));
g_object_class_install_property (gobject_class, PROP_SOCKET_TYPE,
g_param_spec_enum ("socket-type", "Socket type",
"The type of underlying socket",
G_TYPE_UNIX_SOCKET_ADDRESS_TYPE, DEFAULT_SOCKET_TYPE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT |
GST_PARAM_MUTABLE_READY));
}