From 20643843847c12c2a3689ee7be28f351132a20e0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 23 Jun 2021 06:33:58 +0200 Subject: libfile: Add copy_fd() Signed-off-by: Sascha Hauer Link: https://lore.barebox.org/20210623043359.18391-3-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer --- lib/libfile.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'lib') diff --git a/lib/libfile.c b/lib/libfile.c index 4ab8db11ad..40b1d8bb27 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -100,6 +100,29 @@ int read_full(int fd, void *buf, size_t size) } EXPORT_SYMBOL(read_full); +int copy_fd(int in, int out) +{ + int bs = 4096, ret; + void *buf = malloc(bs); + + if (!buf) + return -ENOMEM; + + while (1) { + ret = read(in, buf, bs); + if (ret <= 0) + break; + + ret = write_full(out, buf, ret); + if (ret < 0) + break; + } + + free(buf); + + return ret; +} + /* * read_file_line - read a line from a file * -- cgit v1.2.3 From 982f9063b4290d5d44f230cde09f130a9318d3b5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 24 Jun 2021 10:52:10 +0200 Subject: 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 Link: https://lore.barebox.org/20210624085223.14616-6-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer --- include/libbb.h | 4 +++- lib/libbb.c | 58 +++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/include/libbb.h b/include/libbb.h index a3a13b41ce..e191874052 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -8,8 +8,10 @@ char *concat_path_file(const char *path, const char *filename); char *concat_subpath_file(const char *path, const char *f); -int execable_file(const char *name); +bool execable_file(const char *name); char *find_execable(const char *filename); +char *find_path(const char *path, const char *filename, + bool (*filter)(const char *)); char* last_char_is(const char *s, int c); enum { diff --git a/lib/libbb.c b/lib/libbb.c index d0c9bf4d80..642e54d78f 100644 --- a/lib/libbb.c +++ b/lib/libbb.c @@ -49,11 +49,47 @@ char *concat_subpath_file(const char *path, const char *f) } EXPORT_SYMBOL(concat_subpath_file); +/** + * find_path - find a file in a colon separated path + * @path: The search path, colon separated + * @filename: The filename to search for + * @filter: filter function + * + * searches for @filename in a colon separated list of directories given in + * @path. @filter should return true when the current file matches the expectations, + * false otherwise. @filter should check for existence of the file, but could also + * check for additional flags. + */ +char *find_path(const char *path, const char *filename, + bool (*filter)(const char *)) +{ + char *p, *n, *freep; + + freep = p = strdup(path); + while (p) { + n = strchr(p, ':'); + if (n) + *n++ = '\0'; + if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ + p = concat_path_file(p, filename); + if (filter(p)) { + free(freep); + return p; + } + free(p); + } + p = n; + } + free(freep); + return NULL; +} +EXPORT_SYMBOL(find_path); + /* check if path points to an executable file; * return 1 if found; * return 0 otherwise; */ -int execable_file(const char *name) +bool execable_file(const char *name) { struct stat s; return (!stat(name, &s) && S_ISREG(s.st_mode)); @@ -67,25 +103,7 @@ EXPORT_SYMBOL(execable_file); */ char *find_execable(const char *filename) { - char *path, *p, *n; - - p = path = strdup(getenv("PATH")); - while (p) { - n = strchr(p, ':'); - if (n) - *n++ = '\0'; - if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ - p = concat_path_file(p, filename); - if (execable_file(p)) { - free(path); - return p; - } - free(p); - } - p = n; - } - free(path); - return NULL; + return find_path(getenv("PATH"), filename, execable_file); } EXPORT_SYMBOL(find_execable); -- cgit v1.2.3