From 74314914704609541ca0da9bf1f52469ea5e1079 Mon Sep 17 00:00:00 2001 From: Peter Kjellerstedt Date: Wed, 20 Aug 2008 11:51:38 +0000 Subject: gst/udp/: Avoid leaking internally allocated file descriptors when setting custom file descriptors. Fixes #543101. Original commit message from CVS: Patch by: Peter Kjellerstedt * gst/udp/gstdynudpsink.c: (gst_dynudpsink_init), (gst_dynudpsink_finalize), (gst_dynudpsink_set_property), (gst_dynudpsink_init_send), (gst_dynudpsink_close): * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_init), (gst_multiudpsink_finalize), (gst_multiudpsink_set_property): * gst/udp/gstudpsrc.c: (gst_udpsrc_finalize), (gst_udpsrc_set_property): Avoid leaking internally allocated file descriptors when setting custom file descriptors. Fixes #543101. --- gst/udp/gstdynudpsink.c | 34 ++++++++++++++++++++++------------ gst/udp/gstmultiudpsink.c | 17 ++++++++++++++--- gst/udp/gstudpsrc.c | 25 +++++++++++++++++-------- 3 files changed, 53 insertions(+), 23 deletions(-) (limited to 'gst/udp') diff --git a/gst/udp/gstdynudpsink.c b/gst/udp/gstdynudpsink.c index 02d52b2f..f9b3eb8e 100644 --- a/gst/udp/gstdynudpsink.c +++ b/gst/udp/gstdynudpsink.c @@ -41,11 +41,6 @@ GST_DEBUG_CATEGORY_STATIC (dynudpsink_debug); #define GST_CAT_DEFAULT (dynudpsink_debug) -#define CLOSE_IF_REQUESTED(udpctx) \ - if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \ - CLOSE_SOCKET(udpctx->sock); \ - udpctx->sock = -1; - static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, @@ -80,6 +75,16 @@ enum PROP_CLOSEFD }; +#define CLOSE_IF_REQUESTED(udpctx) \ +G_STMT_START { \ + if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \ + CLOSE_SOCKET(udpctx->sock); \ + if (udpctx->sock == udpctx->sockfd) \ + udpctx->sockfd = UDP_DEFAULT_SOCKFD; \ + } \ + udpctx->sock = -1; \ +} G_STMT_END + static void gst_dynudpsink_base_init (gpointer g_class); static void gst_dynudpsink_class_init (GstDynUDPSink * klass); static void gst_dynudpsink_init (GstDynUDPSink * udpsink); @@ -179,12 +184,8 @@ gst_dynudpsink_class_init (GstDynUDPSink * klass) static void gst_dynudpsink_init (GstDynUDPSink * sink) { - GstDynUDPSink *udpsink; - WSA_STARTUP (sink); - udpsink = GST_DYNUDPSINK (sink); - sink->sockfd = UDP_DEFAULT_SOCKFD; sink->closefd = UDP_DEFAULT_CLOSEFD; sink->externalfd = FALSE; @@ -195,6 +196,13 @@ gst_dynudpsink_init (GstDynUDPSink * sink) static void gst_dynudpsink_finalize (GObject * object) { + GstDynUDPSink *udpsink; + + udpsink = GST_DYNUDPSINK (object); + + if (udpsink->sockfd >= 0 && udpsink->closefd) + CLOSE_SOCKET (udpsink->sockfd); + G_OBJECT_CLASS (parent_class)->finalize (object); WSA_CLEANUP (object); @@ -265,6 +273,9 @@ gst_dynudpsink_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_SOCKFD: + if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock && + udpsink->closefd) + CLOSE_SOCKET (udpsink->sockfd); udpsink->sockfd = g_value_get_int (value); GST_DEBUG ("setting SOCKFD to %d", udpsink->sockfd); break; @@ -309,7 +320,7 @@ gst_dynudpsink_init_send (GstDynUDPSink * sink) if (sink->sockfd == -1) { /* create sender socket if none available */ - if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1) + if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) goto no_socket; bc_val = 1; @@ -348,8 +359,7 @@ gst_dynudpsink_get_stats (GstDynUDPSink * sink, const gchar * host, gint port) static void gst_dynudpsink_close (GstDynUDPSink * sink) { - if (sink->sock != -1) - CLOSE_IF_REQUESTED (sink); + CLOSE_IF_REQUESTED (sink); } static GstStateChangeReturn diff --git a/gst/udp/gstmultiudpsink.c b/gst/udp/gstmultiudpsink.c index 1188b31a..e08613ea 100644 --- a/gst/udp/gstmultiudpsink.c +++ b/gst/udp/gstmultiudpsink.c @@ -105,9 +105,14 @@ enum }; #define CLOSE_IF_REQUESTED(udpctx) \ - if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \ +G_STMT_START { \ + if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \ CLOSE_SOCKET(udpctx->sock); \ - udpctx->sock = -1; + if (udpctx->sock == udpctx->sockfd) \ + udpctx->sockfd = DEFAULT_SOCKFD; \ + } \ + udpctx->sock = DEFAULT_SOCK; \ +} G_STMT_END static void gst_multiudpsink_base_init (gpointer g_class); static void gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass); @@ -332,7 +337,7 @@ gst_multiudpsink_init (GstMultiUDPSink * sink) WSA_STARTUP (sink); sink->client_lock = g_mutex_new (); - sink->sock = -1; + sink->sock = DEFAULT_SOCK; sink->sockfd = DEFAULT_SOCKFD; sink->closefd = DEFAULT_CLOSEFD; sink->externalfd = (sink->sockfd != -1); @@ -352,6 +357,9 @@ gst_multiudpsink_finalize (GObject * object) g_list_foreach (sink->clients, (GFunc) free_client, NULL); g_list_free (sink->clients); + if (sink->sockfd >= 0 && sink->closefd) + CLOSE_SOCKET (sink->sockfd); + g_mutex_free (sink->client_lock); WSA_CLEANUP (object); @@ -517,6 +525,9 @@ gst_multiudpsink_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_SOCKFD: + if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock && + udpsink->closefd) + CLOSE_SOCKET (udpsink->sockfd); udpsink->sockfd = g_value_get_int (value); GST_DEBUG_OBJECT (udpsink, "setting SOCKFD to %d", udpsink->sockfd); break; diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 586f1d83..ed0dbc0b 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -141,13 +141,6 @@ typedef int socklen_t; GST_DEBUG_CATEGORY_STATIC (udpsrc_debug); #define GST_CAT_DEFAULT (udpsrc_debug) -#define CLOSE_IF_REQUESTED(udpctx) \ -G_STMT_START { \ - if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \ - CLOSE_SOCKET(udpctx->sock.fd); \ - udpctx->sock.fd = -1; \ -} G_STMT_END - static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, @@ -191,6 +184,16 @@ enum PROP_LAST }; +#define CLOSE_IF_REQUESTED(udpctx) \ +G_STMT_START { \ + if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \ + CLOSE_SOCKET(udpctx->sock.fd); \ + if (udpctx->sock.fd == udpctx->sockfd) \ + udpctx->sockfd = UDP_DEFAULT_SOCKFD; \ + } \ + udpctx->sock.fd = UDP_DEFAULT_SOCK; \ +} G_STMT_END + static void gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data); static GstCaps *gst_udpsrc_getcaps (GstBaseSrc * src); @@ -348,7 +351,10 @@ gst_udpsrc_finalize (GObject * object) g_free (udpsrc->multi_group); g_free (udpsrc->uri); - WSA_CLEANUP (src); + if (udpsrc->sockfd >= 0 && udpsrc->closefd) + CLOSE_SOCKET (udpsrc->sockfd); + + WSA_CLEANUP (object); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -671,6 +677,9 @@ gst_udpsrc_set_property (GObject * object, guint prop_id, const GValue * value, break; } case PROP_SOCKFD: + if (udpsrc->sockfd >= 0 && udpsrc->sockfd != udpsrc->sock.fd && + udpsrc->closefd) + CLOSE_SOCKET (udpsrc->sockfd); udpsrc->sockfd = g_value_get_int (value); GST_DEBUG ("setting SOCKFD to %d", udpsrc->sockfd); break; -- cgit