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 *****************************************************************************/
28 #include <linux/limits.h>
30 #include <vlc_common.h>
32 #include "config/configuration.h"
34 static char *config_GetLibDirRaw(void)
37 /* Find the path to libvlc (i.e. ourselves) */
38 FILE *maps
= fopen ("/proc/self/maps", "rte");
44 uintptr_t needle
= (uintptr_t)config_GetLibDir
;
48 ssize_t len
= getline (&line
, &linelen
, maps
);
53 if (sscanf (line
, "%p-%p", &start
, &end
) < 2)
55 /* This mapping contains the address of this function. */
56 if (needle
< (uintptr_t)start
|| (uintptr_t)end
<= needle
)
59 char *dir
= strchr (line
, '/');
63 char *file
= strrchr (line
, '/');
76 path
= strdup(LIBDIR
);
80 static char cached_path
[PATH_MAX
] = LIBDIR
;
82 static void config_GetLibDirOnce(void)
84 char *path
= config_GetLibDirRaw();
85 if (likely(path
!= NULL
&& sizeof (cached_path
) > strlen(path
)))
86 strcpy(cached_path
, path
);
90 char *config_GetLibDir(void)
92 static pthread_once_t once
= PTHREAD_ONCE_INIT
;
94 /* Reading and parsing /proc/self/maps is slow, so cache the value since
95 * it's guaranteed not to change during the life-time of the process. */
96 pthread_once(&once
, config_GetLibDirOnce
);
97 return strdup(cached_path
);