Commit aa3db6b1 authored by Petr Machata's avatar Petr Machata

Replace os_get_ltrace_conf_filename with os_get_ltrace_conf_filenames

- I.e. allow returning a list of filenames, as opposed to a single
  home directory name.  This is to implement exactly the legacy config
  file behavior on Linux.
parent ff5606a6
......@@ -347,11 +347,16 @@ int arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
* concern itself with it. */
int os_get_config_dirs(int private, const char ***retp);
/* This is called to obtain the name of legacy config file, if any.
* Returns 0 on success, in which case *RETP should be set to the file
* name (it is legitimate to set this to NULL), or a negative value on
* failure. It is OK if the file is not present. */
int os_get_ltrace_conf_filename(const char **retp);
/* This is called to obtain list of legacy config files to import, if
* any. A reference to initialized vector of char* is passed in.
*
* This returns 0 on success, in which case strings from *RETP (if
* any) are interpreted as files names. These files belong to the
* caller and will eventually be freed.
*
* Returns a negative value for failure, in which case *RETP contents
* are not consulted in any way. */
int os_get_ltrace_conf_filenames(struct vect *retp);
/* If arch.h defines ARCH_HAVE_FETCH_ARG, the following callbacks have
* to be implemented: arch_fetch_arg_init, arch_fetch_arg_clone,
......
......@@ -226,6 +226,7 @@ LDFLAGS="${saved_LDFLAGS}"
AM_CPPFLAGS=" \
-DSYSCONFDIR="'\"$(sysconfdir)\"'" \
-DPKGDATADIR="'\"$(pkgdatadir)\"'" \
${AM_CPPFLAGS} \
-I\$(top_srcdir)/sysdeps/${HOST_OS}/${HOST_CPU} \
-I\$(top_srcdir)/sysdeps/${HOST_OS} \
......
......@@ -291,10 +291,9 @@ instead. For the main program binary, basename is considered as well
When looking for a prototype library, ltrace potentially looks into
several directories. On Linux, those are $XDG_CONFIG_HOME/ltrace,
$HOME/.ltrace, \fIX\fR/ltrace for each \fIX\fR in $XDG_CONFIG_DIRS,
and /etc/ltrace (XXX but that should probably be /usr/lib/ltrace). If
the environment variable XDG_CONFIG_HOME is not defined, ltrace looks
into $HOME/.config/ltrace instead.
$HOME/.ltrace, \fIX\fR/ltrace for each \fIX\fR in $XDG_CONFIG_DIRS and
/usr/share/ltrace. If the environment variable XDG_CONFIG_HOME is not
defined, ltrace looks into $HOME/.config/ltrace instead.
There's also a mechanism for loading legacy config files. If
$HOME/.ltrace.conf exists it is imported to every loaded prototype
......
......@@ -400,28 +400,38 @@ load_config(struct protolib_cache *cache,
return 0;
}
static enum callback_status
import_legacy_file(char **fnp, void *data)
{
struct protolib_cache *cache = data;
struct protolib *plib = protolib_cache_file(cache, *fnp, 1);
if (plib != NULL) {
/* The cache now owns the file name. */
*fnp = NULL;
if (protolib_add_import(&cache->imports, plib) < 0)
return CBS_STOP;
}
return CBS_CONT;
}
static int
add_ltrace_conf(struct protolib_cache *cache)
{
/* Look into private config directories for .ltrace.conf and
* into system config directories for ltrace.conf. If it's
* found, add it to implicit import module. */
struct protolib *plib = NULL;
const char *home = NULL;
if (os_get_ltrace_conf_filename(&home) < 0
|| (home != NULL
&& (plib = consider_config_dir(cache, home, ".ltrace")) != NULL
&& protolib_add_import(&cache->imports, plib) < 0)
|| (plib == NULL && load_config(cache, "ltrace", 0, &plib) < 0)
|| (plib != NULL && protolib_add_import(&cache->imports, plib) < 0))
/* N.B. If plib is non-NULL, it has been already
* cached. We don't therefore destroy it on
* failures. */
struct vect legacy_files;
VECT_INIT(&legacy_files, char *);
if (os_get_ltrace_conf_filenames(&legacy_files) < 0) {
vect_destroy(&legacy_files, NULL, NULL);
return -1;
}
/* Never mind whether we've found anything. It's fine if the
* config is absent. */
return 0;
int ret = VECT_EACH(&legacy_files, char *, NULL,
import_legacy_file, cache) == NULL ? 0 : -1;
VECT_DESTROY(&legacy_files, char *, vect_dtor_string, NULL);
return ret;
}
static enum callback_status
......
......@@ -161,10 +161,10 @@ again:
VECT_DESTROY(&v, struct opt_F_t, destroy_opt_F_cb, NULL);
}
/* SYSCONFDIR is passed via -D when compiling. */
const char *sysconfdir = SYSCONFDIR;
if (sysconfdir != NULL)
add_dir(&dirs, sysconfdir, "");
/* PKGDATADIR is passed via -D when compiling. */
const char *pkgdatadir = PKGDATADIR;
if (pkgdatadir != NULL)
add_dir(&dirs, pkgdatadir, "");
if (VECT_PUSHBACK(&dirs, &delim) < 0)
goto fail;
......@@ -173,10 +173,39 @@ again:
}
int
os_get_ltrace_conf_filename(const char **retp)
os_get_ltrace_conf_filenames(struct vect *retp)
{
char *homepath = NULL;
char *syspath = NULL;
#define FN ".ltrace.conf"
if (g_home_dir == NULL)
os_get_config_dirs(0, NULL);
*retp = g_home_dir;
return g_home_dir != NULL ? 0 : -1;
if (g_home_dir != NULL) {
homepath = malloc(strlen(g_home_dir) + 1 + sizeof FN);
if (homepath == NULL
|| sprintf(homepath, "%s/%s", g_home_dir, FN) < 0) {
fail:
free(syspath);
free(homepath);
return -1;
}
}
/* SYSCONFDIR is passed via -D when compiling. */
const char *sysconfdir = SYSCONFDIR;
if (sysconfdir != NULL && *sysconfdir != '\0') {
/* No +1, we skip the initial period. */
syspath = malloc(strlen(sysconfdir) + sizeof FN);
if (syspath == NULL
|| sprintf(syspath, "%s/%s", sysconfdir, FN + 1) < 0)
goto fail;
}
if (VECT_PUSHBACK(retp, &homepath) < 0
|| VECT_PUSHBACK(retp, &syspath) < 0)
goto fail;
return 0;
}
......@@ -202,3 +202,9 @@ vect_each_cst(const struct vect *vec, const void *start_after,
return vect_each((struct vect *)vec, (void *)start_after,
(void *)cb, data);
}
void
vect_dtor_string(char **key, void *data)
{
free(*key);
}
......@@ -204,4 +204,8 @@ void vect_qsort(struct vect *vec, int (*compar)(const void *, const void *));
(int (*)(const void *, const void *))_compar); \
} while (0)
/* A dtor which calls 'free' on elements of a vector. */
void vect_dtor_string(char **key, void *data);
#endif /* VECT_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment