diff options
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b25386bc0..b05319a9d 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -518,8 +518,8 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
518 | 518 | ||
519 | for (i = 0; i < npaths; i++) { | 519 | for (i = 0; i < npaths; i++) { |
520 | dir = opendir(paths[i]); | 520 | dir = opendir(paths[i]); |
521 | if (!dir) /* Don't print an error */ | 521 | if (!dir) |
522 | continue; | 522 | continue; /* don't print an error */ |
523 | 523 | ||
524 | while ((next = readdir(dir)) != NULL) { | 524 | while ((next = readdir(dir)) != NULL) { |
525 | int len1; | 525 | int len1; |
@@ -529,18 +529,21 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
529 | if (strncmp(str_found, pfind, strlen(pfind))) | 529 | if (strncmp(str_found, pfind, strlen(pfind))) |
530 | continue; | 530 | continue; |
531 | /* not see .name without .match */ | 531 | /* not see .name without .match */ |
532 | if (*str_found == '.' && *pfind == 0) { | 532 | if (*str_found == '.' && *pfind == '\0') { |
533 | if (NOT_LONE_CHAR(paths[i], '/') || str_found[1]) | 533 | if (NOT_LONE_CHAR(paths[i], '/') || str_found[1]) |
534 | continue; | 534 | continue; |
535 | str_found = ""; /* only "/" */ | 535 | str_found = ""; /* only "/" */ |
536 | } | 536 | } |
537 | found = concat_path_file(paths[i], str_found); | 537 | found = concat_path_file(paths[i], str_found); |
538 | /* hmm, remover in progress? */ | 538 | /* hmm, remove in progress? */ |
539 | if (lstat(found, &st) < 0) | 539 | /* NB: stat() first so that we see is it a directory; |
540 | * but if that fails, use lstat() so that | ||
541 | * we still match dangling links */ | ||
542 | if (stat(found, &st) && lstat(found, &st)) | ||
540 | goto cont; | 543 | goto cont; |
541 | /* find with dirs? */ | 544 | /* find with dirs? */ |
542 | if (paths[i] != dirbuf) | 545 | if (paths[i] != dirbuf) |
543 | strcpy(found, next->d_name); /* only name */ | 546 | strcpy(found, next->d_name); /* only name */ |
544 | 547 | ||
545 | len1 = strlen(found); | 548 | len1 = strlen(found); |
546 | found = xrealloc(found, len1 + 2); | 549 | found = xrealloc(found, len1 + 2); |
@@ -548,7 +551,7 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
548 | found[len1+1] = '\0'; | 551 | found[len1+1] = '\0'; |
549 | 552 | ||
550 | if (S_ISDIR(st.st_mode)) { | 553 | if (S_ISDIR(st.st_mode)) { |
551 | /* name is directory */ | 554 | /* name is a directory */ |
552 | if (found[len1-1] != '/') { | 555 | if (found[len1-1] != '/') { |
553 | found[len1] = '/'; | 556 | found[len1] = '/'; |
554 | } | 557 | } |
@@ -566,7 +569,7 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
566 | closedir(dir); | 569 | closedir(dir); |
567 | } | 570 | } |
568 | if (paths != path1) { | 571 | if (paths != path1) { |
569 | free(paths[0]); /* allocated memory only in first member */ | 572 | free(paths[0]); /* allocated memory is only in first member */ |
570 | free(paths); | 573 | free(paths); |
571 | } | 574 | } |
572 | #undef dirbuf | 575 | #undef dirbuf |