]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/vlcpulse.c
shine: avoid double free
[vlc] / modules / audio_output / vlcpulse.c
index 4b6465c9be1260530b930559f691782a495ece17..feecfa722928a732081de7c09c77a359bec260d9 100644 (file)
@@ -12,7 +12,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
@@ -27,7 +27,7 @@
 #include <vlc_common.h>
 #include <pulse/pulseaudio.h>
 
-#include "vlcpulse.h"
+#include "audio_output/vlcpulse.h"
 #include <assert.h>
 #include <stdlib.h>
 #include <locale.h>
@@ -68,6 +68,16 @@ static bool context_wait (pa_context *ctx, pa_threaded_mainloop *mainloop)
     return 0;
 }
 
+static void context_event_cb(pa_context *c, const char *name, pa_proplist *pl,
+                             void *userdata)
+{
+    vlc_object_t *obj = userdata;
+
+    msg_Warn (obj, "unhandled context event \"%s\"", name);
+    (void) c;
+    (void) pl;
+}
+
 /**
  * Initializes the PulseAudio main loop and connects to the PulseAudio server.
  * @return a PulseAudio context on success, or NULL on error
@@ -94,10 +104,29 @@ pa_context *vlc_pa_connect (vlc_object_t *obj, pa_threaded_mainloop **mlp)
     pa_proplist *props = pa_proplist_new ();
     if (likely(props != NULL))
     {
-        pa_proplist_sets (props, PA_PROP_APPLICATION_NAME, ua);
-        pa_proplist_sets (props, PA_PROP_APPLICATION_ID, "org.VideoLAN.VLC");
-        pa_proplist_sets (props, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION);
-        pa_proplist_sets (props, PA_PROP_APPLICATION_ICON_NAME, PACKAGE_NAME);
+        char *str;
+
+        if (ua != NULL)
+            pa_proplist_sets (props, PA_PROP_APPLICATION_NAME, ua);
+
+        str = var_InheritString (obj, "app-id");
+        if (str != NULL)
+        {
+            pa_proplist_sets (props, PA_PROP_APPLICATION_ID, str);
+            free (str);
+        }
+        str = var_InheritString (obj, "app-version");
+        if (str != NULL)
+        {
+            pa_proplist_sets (props, PA_PROP_APPLICATION_VERSION, str);
+            free (str);
+        }
+        str = var_InheritString (obj, "app-icon-name");
+        if (str != NULL)
+        {
+            pa_proplist_sets (props, PA_PROP_APPLICATION_ICON_NAME, str);
+            free (str);
+        }
         //pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE, _("C"));
         pa_proplist_sets (props, PA_PROP_APPLICATION_LANGUAGE,
                           setlocale (LC_MESSAGES, NULL));
@@ -107,18 +136,33 @@ pa_context *vlc_pa_connect (vlc_object_t *obj, pa_threaded_mainloop **mlp)
         //pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_BINARY,
         //                  PACKAGE_NAME);
 
-        char buf[sysconf (_SC_GETPW_R_SIZE_MAX)];
-        struct passwd pwbuf, *pw;
+        for (size_t max = sysconf (_SC_GETPW_R_SIZE_MAX), len = max % 1024 + 1024;
+             len < max; len += 1024)
+        {
+            struct passwd pwbuf, *pw;
+            char buf[len];
+
+            if (getpwuid_r (getuid (), &pwbuf, buf, sizeof (buf), &pw) == 0)
+            {
+                if (pw != NULL)
+                    pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_USER,
+                                      pw->pw_name);
+                break;
+            }
+        }
 
-        if (getpwuid_r (getuid (), &pwbuf, buf, sizeof (buf), &pw) == 0
-         && pw != NULL)
-            pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_USER,
-                              pw->pw_name);
+        for (size_t max = sysconf (_SC_HOST_NAME_MAX), len = max % 1024 + 1024;
+             len < max; len += 1024)
+        {
+            char hostname[len];
 
-        char hostname[sysconf (_SC_HOST_NAME_MAX)];
-        if (gethostname (hostname, sizeof (hostname)) == 0)
-            pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_HOST,
-                              hostname);
+            if (gethostname (hostname, sizeof (hostname)) == 0)
+            {
+                pa_proplist_sets (props, PA_PROP_APPLICATION_PROCESS_HOST,
+                                  hostname);
+                break;
+            }
+        }
 
         const char *session = getenv ("XDG_SESSION_COOKIE");
         if (session != NULL)
@@ -144,6 +188,7 @@ pa_context *vlc_pa_connect (vlc_object_t *obj, pa_threaded_mainloop **mlp)
         goto fail;
 
     pa_context_set_state_callback (ctx, context_state_cb, mainloop);
+    pa_context_set_event_callback (ctx, context_event_cb, obj);
     if (pa_context_connect (ctx, NULL, 0, NULL) < 0
      || context_wait (ctx, mainloop))
     {
@@ -177,6 +222,7 @@ void vlc_pa_disconnect (vlc_object_t *obj, pa_context *ctx,
 {
     pa_threaded_mainloop_lock (mainloop);
     pa_context_disconnect (ctx);
+    pa_context_set_event_callback (ctx, NULL, NULL);
     pa_context_set_state_callback (ctx, NULL, NULL);
     pa_context_unref (ctx);
     pa_threaded_mainloop_unlock (mainloop);