Subject: Use relative library directory

Allow relocated libraries to use their own plug-in directory.

Index: libao-1.2.2/src/audio_out.c
===================================================================
--- libao-1.2.2.orig/src/audio_out.c
+++ libao-1.2.2/src/audio_out.c
@@ -29,6 +29,7 @@
 
  ********************************************************************/
 
+#define _GNU_SOURCE
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -58,6 +59,9 @@ static int dlclose(void *handle) { retur
 #ifndef AO_PLUGIN_PATH
 #define AO_PLUGIN_PATH "/usr/local/lib/ao"
 #endif
+#ifndef PLUGIN_VERSION
+#define PLUGIN_VERSION 4
+#endif
 #ifndef SHARED_LIB_EXT
 #define SHARED_LIB_EXT ".so"
 #endif
@@ -281,6 +285,44 @@ static driver_list* _load_static_drivers
 }
 
 
+static const char *ao_plugin_path(void)
+{
+	static const char *plugin_dir;
+	static char *runtime_dir;
+
+	if (plugin_dir)
+		return plugin_dir;
+
+	char *dir = NULL;
+	do {
+		Dl_info dlinfo;
+		if (!dladdr(ao_initialize, &dlinfo))
+			break;
+		char *slash = strrchr(dlinfo.dli_fname, '/');
+		if (!slash)
+			break;
+		size_t length = slash - dlinfo.dli_fname;
+		#define STRINGIFY_VALUE(x) STRINGIFY(x)
+		#define STRINGIFY(x) #x
+		static const char SUBDIR[] = "/ao/plugins-"
+			STRINGIFY_VALUE(PLUGIN_VERSION);
+		dir = malloc(length + sizeof SUBDIR);
+		if (!dir)
+			break;
+		char *next = mempcpy(dir, dlinfo.dli_fname, length);
+		memcpy(next, SUBDIR, sizeof SUBDIR);
+		runtime_dir = dir;
+	} while (0);
+	plugin_dir = dir ? : AO_PLUGIN_PATH;
+	return plugin_dir;
+
+	__attribute__((destructor)) void destructor(void)
+	{
+		free(runtime_dir);
+	}
+}
+
+
 /* Load the dynamic drivers from disk and append them to end of the
    driver list.  end points the driver_list node to append to. */
 static void _append_dynamic_drivers(driver_list *end)
@@ -295,13 +337,13 @@ static void _append_dynamic_drivers(driv
         ao_device *device = ao_global_dummy;
 
 	/* now insert any plugins we find */
-	plugindir = opendir(AO_PLUGIN_PATH);
-        adebug("Loading driver plugins from %s...\n",AO_PLUGIN_PATH);
+	plugindir = opendir(ao_plugin_path());
+        adebug("Loading driver plugins from %s...\n",ao_plugin_path());
 	if (plugindir != NULL) {
           while ((plugin_dirent = readdir(plugindir)) != NULL) {
-            char fullpath[strlen(AO_PLUGIN_PATH) + 1 + strlen(plugin_dirent->d_name) + 1];
+            char fullpath[strlen(ao_plugin_path()) + 1 + strlen(plugin_dirent->d_name) + 1];
             snprintf(fullpath, sizeof(fullpath), "%s/%s",
-                     AO_PLUGIN_PATH, plugin_dirent->d_name);
+                     ao_plugin_path(), plugin_dirent->d_name);
             if (!stat(fullpath, &statbuf) &&
                 S_ISREG(statbuf.st_mode) &&
                 (ext = strrchr(plugin_dirent->d_name, '.')) != NULL) {
