Skip to content

Commit 982f906

Browse files
committed
libbb: Add find_path function
libbb contains a find_execable() function to find an executable in a colon separated path. The code can be reused by making the environment variable name and the is-executable test parameters. Do this and add a find_path() Signed-off-by: Sascha Hauer <[email protected]> Link: https://lore.barebox.org/[email protected] Signed-off-by: Sascha Hauer <[email protected]>
1 parent 303b5b0 commit 982f906

File tree

2 files changed

+41
-21
lines changed

2 files changed

+41
-21
lines changed

include/libbb.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88

99
char *concat_path_file(const char *path, const char *filename);
1010
char *concat_subpath_file(const char *path, const char *f);
11-
int execable_file(const char *name);
11+
bool execable_file(const char *name);
1212
char *find_execable(const char *filename);
13+
char *find_path(const char *path, const char *filename,
14+
bool (*filter)(const char *));
1315
char* last_char_is(const char *s, int c);
1416

1517
enum {

lib/libbb.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,47 @@ char *concat_subpath_file(const char *path, const char *f)
4949
}
5050
EXPORT_SYMBOL(concat_subpath_file);
5151

52+
/**
53+
* find_path - find a file in a colon separated path
54+
* @path: The search path, colon separated
55+
* @filename: The filename to search for
56+
* @filter: filter function
57+
*
58+
* searches for @filename in a colon separated list of directories given in
59+
* @path. @filter should return true when the current file matches the expectations,
60+
* false otherwise. @filter should check for existence of the file, but could also
61+
* check for additional flags.
62+
*/
63+
char *find_path(const char *path, const char *filename,
64+
bool (*filter)(const char *))
65+
{
66+
char *p, *n, *freep;
67+
68+
freep = p = strdup(path);
69+
while (p) {
70+
n = strchr(p, ':');
71+
if (n)
72+
*n++ = '\0';
73+
if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
74+
p = concat_path_file(p, filename);
75+
if (filter(p)) {
76+
free(freep);
77+
return p;
78+
}
79+
free(p);
80+
}
81+
p = n;
82+
}
83+
free(freep);
84+
return NULL;
85+
}
86+
EXPORT_SYMBOL(find_path);
87+
5288
/* check if path points to an executable file;
5389
* return 1 if found;
5490
* return 0 otherwise;
5591
*/
56-
int execable_file(const char *name)
92+
bool execable_file(const char *name)
5793
{
5894
struct stat s;
5995
return (!stat(name, &s) && S_ISREG(s.st_mode));
@@ -67,25 +103,7 @@ EXPORT_SYMBOL(execable_file);
67103
*/
68104
char *find_execable(const char *filename)
69105
{
70-
char *path, *p, *n;
71-
72-
p = path = strdup(getenv("PATH"));
73-
while (p) {
74-
n = strchr(p, ':');
75-
if (n)
76-
*n++ = '\0';
77-
if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
78-
p = concat_path_file(p, filename);
79-
if (execable_file(p)) {
80-
free(path);
81-
return p;
82-
}
83-
free(p);
84-
}
85-
p = n;
86-
}
87-
free(path);
88-
return NULL;
106+
return find_path(getenv("PATH"), filename, execable_file);
89107
}
90108
EXPORT_SYMBOL(find_execable);
91109

0 commit comments

Comments
 (0)