[pacman-dev] [PATCH] Allow -Qo to perform a functional 'which'
Allan McRae
allan at archlinux.org
Mon Dec 21 18:19:08 EST 2009
Nathan Wayde wrote:
> On 21/12/09 09:55, Allan McRae wrote:
>> When pacman queries the ownership of an object that is not a path,
>> it will check in the users PATH for a match. Implements FS#8798.
>>
>> Patch-by: Shankar<jatheendra at gmail.com>
>> [Allan: rework for master, tidy-up]
>> Signed-off-by: Allan McRae<allan at archlinux.org>
>> ---
>>
>> This was original posted a year ago...
>> http://mailman.archlinux.org/pipermail/pacman-dev/2008-November/007659.html
>>
>>
>> The comments then were that we should maybe refactor out stuff dealing
>> with
>> file paths, specifically removing trailing backslashes. That appears
>> to only
>> occur in two other places and is very simple so I do not thing it needs
>> refactored and can be done in a spearate patch if necessary.
>>
>> The only other part I do not like is the "failed to read file" error
>> block is
>> repeated, but I can not see a nice way to fix that.
>>
>> src/pacman/query.c | 58
>> +++++++++++++++++++++++++++++++++++++++++++++++----
>> 1 files changed, 53 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/pacman/query.c b/src/pacman/query.c
>> index 6b6a25d..6f579fd 100644
>> --- a/src/pacman/query.c
>> +++ b/src/pacman/query.c
>> @@ -56,6 +56,41 @@ static char *resolve_path(const char* file)
>> return(str);
>> }
>>
>> +/* check if filename exists in PATH */
>> +static int search_path(char *filename, struct stat * bufptr)
>> +{
>> + char *envpath, *path, *fullname;
>> + int len;
>> +
>> + if ((envpath = getenv("PATH")) == NULL) {
>> + return(-1);
>> + }
>> + if ((envpath = strdup(envpath)) == NULL) {
>> + return(-1);
>> + }
>> +
>> + fullname = calloc(PATH_MAX+1, sizeof(char));
>> +
>> + while ((path = strsep(&envpath, ":")) != NULL) {
>> + len = strlen(path);
>> +
>> + /* strip the trailing slash if one exists */
>> + if(path[len - 1] == '/') {
>> + path[len - 1] = '\0';
>> + }
>> +
>> + snprintf(fullname, PATH_MAX+1, "%s/%s", path, filename);
>> +
>> + if(stat(fullname, bufptr) == 0) {
>> + strncpy(filename, fullname, PATH_MAX+1);
>> + free(fullname);
>> + return(0);
>> + }
>> + }
>> + free(fullname);
>> + return(-1);
>> +}
>> +
>
> just a heads-up, search_path() contains a memory leak; envpath is never
> free()'d. Note, the original envpath is lost in the call to strsep().
>
So it does... someone did not run valgrind on the patch :P
If I understand this correctly, I need to have another variable that
keeps track of the pointer to the strdup object while the original gets
split. I.e.:
+/* check if filename exists in PATH */
+static int search_path(char *filename, struct stat * bufptr)
+{
+ char *envpath, *envpathsplit, *path, *fullname;
+ int len;
+
+ if ((envpath = getenv("PATH")) == NULL) {
+ return(-1);
+ }
+ if ((envpath = envpathsplit = strdup(envpath)) == NULL) {
+ return(-1);
+ }
+
+ fullname = calloc(PATH_MAX+1, sizeof(char));
+
+ while ((path = strsep(&envpathsplit, ":")) != NULL) {
+ len = strlen(path);
+
+ /* strip the trailing slash if one exists */
+ if(path[len - 1] == '/') {
+ path[len - 1] = '\0';
+ }
+
+ snprintf(fullname, PATH_MAX+1, "%s/%s", path, filename);
+
+ if(stat(fullname, bufptr) == 0) {
+ strncpy(filename, fullname, PATH_MAX+1);
+ free(envpath);
+ free(fullname);
+ return(0);
+ }
+ }
+ free(envpath);
+ free(fullname);
+ return(-1);
+}
That seems to make valgrind happy and keeps everything working. Does
that make sense or am I doing something stupid...
Updated patch on my working branch.
Allan
More information about the pacman-dev
mailing list