Hi,<br><br>I prefer this implementation than the older one, because it check on executable(Maybe we add a attribute for that or check on shebang) file and call found with the full path.<br>I was thinking about to put this as RFC..., because I don't have really a usecase for this.<br>
Some commands can do a autocompletion for files that are in $PATH, when this is needed.<br><br>The naming things, I don't like the name, too. I was doing the naming like the others functions.<br>I will send a v2 with a better name and functionheader<br>
<br>Regards<br>Alexander Aring<br><br><div class="gmail_quote">2012/9/11 Sascha Hauer <span dir="ltr"><<a href="mailto:s.hauer@pengutronix.de" target="_blank">s.hauer@pengutronix.de</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Tue, Sep 11, 2012 at 07:31:58AM +0200, Alexander Aring wrote:<br>
> Rewritten path complete, to use it maybe<br>
> in another functions.<br>
<br>
</div>Do you have a usecase for this?<br>
<div><div class="h5"><br>
><br>
> Signed-off-by: Alexander Aring <<a href="mailto:alex.aring@gmail.com">alex.aring@gmail.com</a>><br>
> ---<br>
> common/complete.c | 73 +++++++++++++------------------------------------------<br>
> include/libbb.h | 2 ++<br>
> lib/libbb.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++-<br>
> 3 files changed, 82 insertions(+), 57 deletions(-)<br>
><br>
> diff --git a/common/complete.c b/common/complete.c<br>
> index 6a871ef..a06c070 100644<br>
> --- a/common/complete.c<br>
> +++ b/common/complete.c<br>
> @@ -25,6 +25,8 @@<br>
> #include <libgen.h><br>
> #include <command.h><br>
> #include <environment.h><br>
> +#include <errno.h><br>
> +#include <libbb.h><br>
><br>
> static int file_complete(struct string_list *sl, char *instr, int exec)<br>
> {<br>
> @@ -70,65 +72,24 @@ out:<br>
> return 0;<br>
> }<br>
><br>
> -static int path_command_complete(struct string_list *sl, char *instr)<br>
> +static int path_command_complete(char *name, void *priv)<br>
> {<br>
> - struct stat s;<br>
> - DIR *dir;<br>
> - struct dirent *d;<br>
> - char tmp[PATH_MAX];<br>
> - char *path, *p, *n;<br>
> -<br>
> - p = path = strdup(getenv("PATH"));<br>
> -<br>
> - if (!path)<br>
> - return -1;<br>
> -<br>
> - while (p) {<br>
> - n = strchr(p, ':');<br>
> - if (n)<br>
> - *n++ = '\0';<br>
> - if (*p == '\0') {<br>
> - p = n;<br>
> - continue;<br>
> - }<br>
> - dir = opendir(p);<br>
> + struct string_list *sl = priv;<br>
> + char *filename;<br>
><br>
> - /* We need to check all PATH dirs, so if one failed,<br>
> - * try next */<br>
> - if (!dir) {<br>
> - p = n;<br>
> - continue;<br>
> - }<br>
> + filename = strrchr(name, '/') + 1;<br>
> + if (!filename)<br>
> + return -EINVAL;<br>
><br>
> - while ((d = readdir(dir))) {<br>
> - if (!strcmp(d->d_name, ".") ||<br>
> - !strcmp(d->d_name, ".."))<br>
> - continue;<br>
> + strcat(filename, " ");<br>
><br>
> - if (!strncmp(instr, d->d_name, strlen(instr))) {<br>
> - strcpy(tmp, d->d_name);<br>
> - if (!stat(tmp, &s) &&<br>
> - S_ISDIR(s.st_mode))<br>
> - continue;<br>
> - else<br>
> - strcat(tmp, " ");<br>
> -<br>
> - /* This function is called<br>
> - * after command_complete,<br>
> - * so we check if a double<br>
> - * entry exist */<br>
> - if (string_list_contains<br>
> - (sl, tmp) == 0) {<br>
> - string_list_add_sorted(sl, tmp);<br>
> - }<br>
> - }<br>
> - }<br>
> -<br>
> - closedir(dir);<br>
> - p = n;<br>
> - }<br>
> -<br>
> - free(path);<br>
> + /* This function is called<br>
> + * after command_complete,<br>
> + * so we check if a double<br>
> + * entry exist */<br>
> + if (!string_list_contains<br>
> + (sl, filename))<br>
> + string_list_add_sorted(sl, filename);<br>
><br>
> return 0;<br>
> }<br>
> @@ -334,7 +295,7 @@ int complete(char *instr, char **outstr)<br>
> instr = t;<br>
> } else {<br>
> command_complete(&sl, instr);<br>
> - path_command_complete(&sl, instr);<br>
> + find_execable_like(path_command_complete, instr, &sl);<br>
> env_param_complete(&sl, instr, 0);<br>
> }<br>
> if (*instr == '$')<br>
> diff --git a/include/libbb.h b/include/libbb.h<br>
> index 47b2e08..0ef702b 100644<br>
> --- a/include/libbb.h<br>
> +++ b/include/libbb.h<br>
> @@ -11,6 +11,8 @@ char *concat_subpath_file(const char *path, const char *f);<br>
> int execable_file(const char *name);<br>
> char *find_execable(const char *filename);<br>
> char* last_char_is(const char *s, int c);<br>
> +int find_execable_like(int found(char *name, void *priv),<br>
> + const char *likelyname, void *priv);<br>
><br>
> enum {<br>
> ACTION_RECURSE = (1 << 0),<br>
> diff --git a/lib/libbb.c b/lib/libbb.c<br>
> index e0d7481..daf77c7 100644<br>
> --- a/lib/libbb.c<br>
> +++ b/lib/libbb.c<br>
> @@ -14,6 +14,7 @@<br>
> #include <xfuncs.h><br>
> #include <malloc.h><br>
> #include <environment.h><br>
> +#include <errno.h><br>
><br>
> /* concatenate path and file name to new allocation buffer,<br>
> * not adding '/' if path name already has '/'<br>
> @@ -60,7 +61,6 @@ int execable_file(const char *name)<br>
> }<br>
> EXPORT_SYMBOL(execable_file);<br>
><br>
> -<br>
> /* search $PATH for an executable file;<br>
> * return allocated string containing full path if found;<br>
> * return NULL otherwise;<br>
> @@ -89,6 +89,68 @@ char *find_execable(const char *filename)<br>
> }<br>
> EXPORT_SYMBOL(find_execable);<br>
><br>
> +/* search $PATH for an executable file which is<br>
> + * like the filename specified in likelyname;<br>
> + * A likelyname on match will call the found function;<br>
> + * Caller need to duplicate the name string in<br>
> + * found functionpointer, if he want to save it;<br>
> + * return 0 on success and <0 on error;<br>
> + */<br>
> +int find_execable_like(int found(char *name, void *priv),<br>
> + const char *likelyname, void *priv)<br>
<br>
</div></div>I don't like the name very much. Can we name it execable_complete?<br>
Also I would use the likelyname argument as first argument, because<br>
then it would read "on 'name' do call 'found'"<br>
<br>
(I always stumble over 'execable', it should rather be 'executable', but<br>
we have the former everywhere, so either change them all keep it here<br>
aswell)<br>
<span class="HOEnZb"><font color="#888888"><br>
Sascha<br>
<br>
--<br>
Pengutronix e.K. | |<br>
Industrial Linux Solutions | <a href="http://www.pengutronix.de/" target="_blank">http://www.pengutronix.de/</a> |<br>
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: <a href="tel:%2B49-5121-206917-0" value="+4951212069170">+49-5121-206917-0</a> |<br>
Amtsgericht Hildesheim, HRA 2686 | Fax: <a href="tel:%2B49-5121-206917-5555" value="+4951212069175555">+49-5121-206917-5555</a> |<br>
</font></span></blockquote></div><br>