1 /*****************************************************************************
2 * linux/dirs.c: Linux-specific directories
3 *****************************************************************************
4 * Copyright © 2008-2012 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
27 #include <linux/limits.h>
29 #include <vlc_common.h>
31 #include "config/configuration.h"
33 char *config_GetLibDir (void)
43 /* Reading and parsing /proc/self/maps is slow, so cache the value since
44 * it's guaranteed not to change during the life-time of the process. */
45 vlc_mutex_lock(&cache
.lock
);
46 if (cache
.path
[0] != '\0')
48 char *ret
= strdup(cache
.path
);
49 vlc_mutex_unlock(&cache
.lock
);
54 /* Find the path to libvlc (i.e. ourselves) */
55 FILE *maps
= fopen ("/proc/self/maps", "rte");
61 uintptr_t needle
= (uintptr_t)config_GetLibDir
;
65 ssize_t len
= getline (&line
, &linelen
, maps
);
70 if (sscanf (line
, "%p-%p", &start
, &end
) < 2)
72 /* This mapping contains the address of this function. */
73 if (needle
< (uintptr_t)start
|| (uintptr_t)end
<= needle
)
76 char *dir
= strchr (line
, '/');
80 char *file
= strrchr (line
, '/');
85 if (asprintf (&path
, "%s/"PACKAGE
, dir
) == -1)
94 path
= strdup(PKGLIBDIR
);
95 if (likely(path
!= NULL
&& sizeof(cache
.path
) > strlen(path
)))
96 strcpy(cache
.path
, path
);
97 vlc_mutex_unlock(&cache
.lock
);
101 char *config_GetDataDir (void)
103 const char *path
= getenv ("VLC_DATA_PATH");
105 return strdup (path
);
107 char *libdir
= config_GetLibDir ();
109 return NULL
; /* OOM */
111 char *datadir
= NULL
;
113 /* There are no clean ways to do this, are there?
114 * Due to multilibs, we cannot simply append ../share/. */
115 char *p
= strstr (libdir
, "/lib/");
119 /* Deal with nested "lib" directories. Grmbl. */
120 while ((p2
= strstr (p
+ 4, "/lib/")) != NULL
)
124 if (unlikely(asprintf (&datadir
, "%s/share/"PACKAGE
, libdir
) == -1))
128 return (datadir
!= NULL
) ? datadir
: strdup (PKGDATADIR
);