Skip to content

Commit aa3db6b

Browse files
author
Petr Machata
committed
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.
1 parent ff5606a commit aa3db6b

File tree

7 files changed

+84
-30
lines changed

7 files changed

+84
-30
lines changed

backend.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,16 @@ int arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
347347
* concern itself with it. */
348348
int os_get_config_dirs(int private, const char ***retp);
349349

350-
/* This is called to obtain the name of legacy config file, if any.
351-
* Returns 0 on success, in which case *RETP should be set to the file
352-
* name (it is legitimate to set this to NULL), or a negative value on
353-
* failure. It is OK if the file is not present. */
354-
int os_get_ltrace_conf_filename(const char **retp);
350+
/* This is called to obtain list of legacy config files to import, if
351+
* any. A reference to initialized vector of char* is passed in.
352+
*
353+
* This returns 0 on success, in which case strings from *RETP (if
354+
* any) are interpreted as files names. These files belong to the
355+
* caller and will eventually be freed.
356+
*
357+
* Returns a negative value for failure, in which case *RETP contents
358+
* are not consulted in any way. */
359+
int os_get_ltrace_conf_filenames(struct vect *retp);
355360

356361
/* If arch.h defines ARCH_HAVE_FETCH_ARG, the following callbacks have
357362
* to be implemented: arch_fetch_arg_init, arch_fetch_arg_clone,

configure.ac

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ LDFLAGS="${saved_LDFLAGS}"
226226

227227
AM_CPPFLAGS=" \
228228
-DSYSCONFDIR="'\"$(sysconfdir)\"'" \
229+
-DPKGDATADIR="'\"$(pkgdatadir)\"'" \
229230
${AM_CPPFLAGS} \
230231
-I\$(top_srcdir)/sysdeps/${HOST_OS}/${HOST_CPU} \
231232
-I\$(top_srcdir)/sysdeps/${HOST_OS} \

ltrace.1

+3-4
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,9 @@ instead. For the main program binary, basename is considered as well
291291

292292
When looking for a prototype library, ltrace potentially looks into
293293
several directories. On Linux, those are $XDG_CONFIG_HOME/ltrace,
294-
$HOME/.ltrace, \fIX\fR/ltrace for each \fIX\fR in $XDG_CONFIG_DIRS,
295-
and /etc/ltrace (XXX but that should probably be /usr/lib/ltrace). If
296-
the environment variable XDG_CONFIG_HOME is not defined, ltrace looks
297-
into $HOME/.config/ltrace instead.
294+
$HOME/.ltrace, \fIX\fR/ltrace for each \fIX\fR in $XDG_CONFIG_DIRS and
295+
/usr/share/ltrace. If the environment variable XDG_CONFIG_HOME is not
296+
defined, ltrace looks into $HOME/.config/ltrace instead.
298297

299298
There's also a mechanism for loading legacy config files. If
300299
$HOME/.ltrace.conf exists it is imported to every loaded prototype

prototype.c

+24-14
Original file line numberDiff line numberDiff line change
@@ -400,28 +400,38 @@ load_config(struct protolib_cache *cache,
400400
return 0;
401401
}
402402

403+
static enum callback_status
404+
import_legacy_file(char **fnp, void *data)
405+
{
406+
struct protolib_cache *cache = data;
407+
struct protolib *plib = protolib_cache_file(cache, *fnp, 1);
408+
if (plib != NULL) {
409+
/* The cache now owns the file name. */
410+
*fnp = NULL;
411+
if (protolib_add_import(&cache->imports, plib) < 0)
412+
return CBS_STOP;
413+
}
414+
415+
return CBS_CONT;
416+
}
417+
403418
static int
404419
add_ltrace_conf(struct protolib_cache *cache)
405420
{
406421
/* Look into private config directories for .ltrace.conf and
407422
* into system config directories for ltrace.conf. If it's
408423
* found, add it to implicit import module. */
409-
struct protolib *plib = NULL;
410-
const char *home = NULL;
411-
if (os_get_ltrace_conf_filename(&home) < 0
412-
|| (home != NULL
413-
&& (plib = consider_config_dir(cache, home, ".ltrace")) != NULL
414-
&& protolib_add_import(&cache->imports, plib) < 0)
415-
|| (plib == NULL && load_config(cache, "ltrace", 0, &plib) < 0)
416-
|| (plib != NULL && protolib_add_import(&cache->imports, plib) < 0))
417-
/* N.B. If plib is non-NULL, it has been already
418-
* cached. We don't therefore destroy it on
419-
* failures. */
424+
struct vect legacy_files;
425+
VECT_INIT(&legacy_files, char *);
426+
if (os_get_ltrace_conf_filenames(&legacy_files) < 0) {
427+
vect_destroy(&legacy_files, NULL, NULL);
420428
return -1;
429+
}
421430

422-
/* Never mind whether we've found anything. It's fine if the
423-
* config is absent. */
424-
return 0;
431+
int ret = VECT_EACH(&legacy_files, char *, NULL,
432+
import_legacy_file, cache) == NULL ? 0 : -1;
433+
VECT_DESTROY(&legacy_files, char *, vect_dtor_string, NULL);
434+
return ret;
425435
}
426436

427437
static enum callback_status

sysdeps/linux-gnu/hooks.c

+36-7
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ os_get_config_dirs(int private, const char ***retp)
161161
VECT_DESTROY(&v, struct opt_F_t, destroy_opt_F_cb, NULL);
162162
}
163163

164-
/* SYSCONFDIR is passed via -D when compiling. */
165-
const char *sysconfdir = SYSCONFDIR;
166-
if (sysconfdir != NULL)
167-
add_dir(&dirs, sysconfdir, "");
164+
/* PKGDATADIR is passed via -D when compiling. */
165+
const char *pkgdatadir = PKGDATADIR;
166+
if (pkgdatadir != NULL)
167+
add_dir(&dirs, pkgdatadir, "");
168168

169169
if (VECT_PUSHBACK(&dirs, &delim) < 0)
170170
goto fail;
@@ -173,10 +173,39 @@ os_get_config_dirs(int private, const char ***retp)
173173
}
174174

175175
int
176-
os_get_ltrace_conf_filename(const char **retp)
176+
os_get_ltrace_conf_filenames(struct vect *retp)
177177
{
178+
char *homepath = NULL;
179+
char *syspath = NULL;
180+
181+
#define FN ".ltrace.conf"
178182
if (g_home_dir == NULL)
179183
os_get_config_dirs(0, NULL);
180-
*retp = g_home_dir;
181-
return g_home_dir != NULL ? 0 : -1;
184+
185+
if (g_home_dir != NULL) {
186+
homepath = malloc(strlen(g_home_dir) + 1 + sizeof FN);
187+
if (homepath == NULL
188+
|| sprintf(homepath, "%s/%s", g_home_dir, FN) < 0) {
189+
fail:
190+
free(syspath);
191+
free(homepath);
192+
return -1;
193+
}
194+
}
195+
196+
/* SYSCONFDIR is passed via -D when compiling. */
197+
const char *sysconfdir = SYSCONFDIR;
198+
if (sysconfdir != NULL && *sysconfdir != '\0') {
199+
/* No +1, we skip the initial period. */
200+
syspath = malloc(strlen(sysconfdir) + sizeof FN);
201+
if (syspath == NULL
202+
|| sprintf(syspath, "%s/%s", sysconfdir, FN + 1) < 0)
203+
goto fail;
204+
}
205+
206+
if (VECT_PUSHBACK(retp, &homepath) < 0
207+
|| VECT_PUSHBACK(retp, &syspath) < 0)
208+
goto fail;
209+
210+
return 0;
182211
}

vect.c

+6
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,9 @@ vect_each_cst(const struct vect *vec, const void *start_after,
202202
return vect_each((struct vect *)vec, (void *)start_after,
203203
(void *)cb, data);
204204
}
205+
206+
void
207+
vect_dtor_string(char **key, void *data)
208+
{
209+
free(*key);
210+
}

vect.h

+4
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,8 @@ void vect_qsort(struct vect *vec, int (*compar)(const void *, const void *));
204204
(int (*)(const void *, const void *))_compar); \
205205
} while (0)
206206

207+
208+
/* A dtor which calls 'free' on elements of a vector. */
209+
void vect_dtor_string(char **key, void *data);
210+
207211
#endif /* VECT_H */

0 commit comments

Comments
 (0)