aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-05 13:33:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-05 13:33:59 +0000
commitf592aa36f33430b866e9d7c975c6b9c356100d4b (patch)
treef7a8c565817ce331c6e18a2a399074c6c615cd79
parentf0d6068086b701522b92a7dd941739cf4fbb71e8 (diff)
downloadbusybox-w32-f592aa36f33430b866e9d7c975c6b9c356100d4b.tar.gz
busybox-w32-f592aa36f33430b866e9d7c975c6b9c356100d4b.tar.bz2
busybox-w32-f592aa36f33430b866e9d7c975c6b9c356100d4b.zip
which: -a support (needed for bfin uclibc build script)
real support (with CONFIG_DESKTOP=y): 120+ bytes: text data bss dec hex filename 807958 624 7036 815618 c7202 busybox_old 808085 624 7036 815745 c7281 busybox_unstripped "fake" support (with CONFIG_DESKTOP unset): ~45 bytes: text data bss dec hex filename 797790 611 6996 805397 c4a15 busybox_old 797834 611 6996 805441 c4a41 busybox_unstripped
-rw-r--r--debianutils/which.c64
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/execable.c27
3 files changed, 70 insertions, 23 deletions
diff --git a/debianutils/which.c b/debianutils/which.c
index 5ab67194d..41a864cfa 100644
--- a/debianutils/which.c
+++ b/debianutils/which.c
@@ -13,30 +13,69 @@
13#include "libbb.h" 13#include "libbb.h"
14 14
15int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 15int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
16int which_main(int argc, char **argv) 16int which_main(int argc ATTRIBUTE_UNUSED, char **argv)
17{ 17{
18 USE_DESKTOP(int opt;)
18 int status = EXIT_SUCCESS; 19 int status = EXIT_SUCCESS;
20 char *path;
19 char *p; 21 char *p;
20 22
21 if (argc <= 1 || argv[1][0] == '-') { 23 opt_complementary = "-1"; /* at least one argument */
22 bb_show_usage(); 24 USE_DESKTOP(opt =) getopt32(argv, "a");
23 } 25 argv += optind;
24 26
25 /* This matches what is seen on e.g. ubuntu 27 /* This matches what is seen on e.g. ubuntu.
26 * "which" there is a shell script */ 28 * "which" there is a shell script. */
27 if (!getenv("PATH")) { 29 path = getenv("PATH");
28 putenv((char*)bb_PATH_root_path); 30 if (!path) {
31 path = (char*)bb_PATH_root_path;
32 putenv(path);
33 path += 5; /* skip "PATH=" */
29 } 34 }
30 35
31 while (--argc > 0) { 36 do {
32 argv++; 37#if ENABLE_DESKTOP
38/* Much bloat just to support -a */
33 if (strchr(*argv, '/')) { 39 if (strchr(*argv, '/')) {
34 if (execable_file(*argv)) { 40 if (execable_file(*argv)) {
35 puts(*argv); 41 puts(*argv);
36 continue; 42 continue;
37 } 43 }
44 status = EXIT_FAILURE;
38 } else { 45 } else {
39 p = find_execable(*argv); 46 char *path2 = xstrdup(path);
47 char *tmp = path2;
48
49 p = find_execable(*argv, &tmp);
50 if (!p)
51 status = EXIT_FAILURE;
52 else {
53 print:
54 puts(p);
55 free(p);
56 if (opt) {
57 /* -a: show matches in all PATH components */
58 if (tmp) {
59 p = find_execable(*argv, &tmp);
60 if (p)
61 goto print;
62 }
63 }
64 }
65 free(path2);
66 }
67#else
68/* Just ignoring -a */
69 if (strchr(*argv, '/')) {
70 if (execable_file(*argv)) {
71 puts(*argv);
72 continue;
73 }
74 } else {
75 char *path2 = xstrdup(path);
76 char *tmp = path2;
77 p = find_execable(*argv, &tmp);
78 free(path2);
40 if (p) { 79 if (p) {
41 puts(p); 80 puts(p);
42 free(p); 81 free(p);
@@ -44,7 +83,8 @@ int which_main(int argc, char **argv)
44 } 83 }
45 } 84 }
46 status = EXIT_FAILURE; 85 status = EXIT_FAILURE;
47 } 86#endif
87 } while (*(++argv) != NULL);
48 88
49 fflush_stdout_and_exit(status); 89 fflush_stdout_and_exit(status);
50} 90}
diff --git a/include/libbb.h b/include/libbb.h
index 492a561a9..1e4968bfa 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -700,7 +700,7 @@ void die_if_bad_username(const char* name);
700#endif 700#endif
701 701
702int execable_file(const char *name); 702int execable_file(const char *name);
703char *find_execable(const char *filename); 703char *find_execable(const char *filename, char **PATHp);
704int exists_execable(const char *filename); 704int exists_execable(const char *filename);
705 705
706/* BB_EXECxx always execs (it's not doing NOFORK/NOEXEC stuff), 706/* BB_EXECxx always execs (it's not doing NOFORK/NOEXEC stuff),
diff --git a/libbb/execable.c b/libbb/execable.c
index 2649a6cfe..5c2b4505c 100644
--- a/libbb/execable.c
+++ b/libbb/execable.c
@@ -19,15 +19,20 @@ int execable_file(const char *name)
19 return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode)); 19 return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode));
20} 20}
21 21
22/* search $PATH for an executable file; 22/* search (*PATHp) for an executable file;
23 * return allocated string containing full path if found; 23 * return allocated string containing full path if found;
24 * return NULL otherwise; 24 * PATHp points to the component after the one where it was found
25 * (or NULL),
26 * you may call find_execable again with this PATHp to continue
27 * (if it's not NULL).
28 * return NULL otherwise; (PATHp is undefined)
29 * in all cases (*PATHp) contents will be trashed (s/:/NUL/).
25 */ 30 */
26char *find_execable(const char *filename) 31char *find_execable(const char *filename, char **PATHp)
27{ 32{
28 char *path, *p, *n; 33 char *p, *n;
29 34
30 p = path = xstrdup(getenv("PATH")); 35 p = *PATHp;
31 while (p) { 36 while (p) {
32 n = strchr(p, ':'); 37 n = strchr(p, ':');
33 if (n) 38 if (n)
@@ -35,15 +40,14 @@ char *find_execable(const char *filename)
35 if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ 40 if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
36 p = concat_path_file(p, filename); 41 p = concat_path_file(p, filename);
37 if (execable_file(p)) { 42 if (execable_file(p)) {
38 free(path); 43 *PATHp = n;
39 return p; 44 return p;
40 } 45 }
41 free(p); 46 free(p);
42 } 47 }
43 p = n; 48 p = n;
44 } 49 } /* on loop exit p == NULL */
45 free(path); 50 return p;
46 return NULL;
47} 51}
48 52
49/* search $PATH for an executable file; 53/* search $PATH for an executable file;
@@ -52,7 +56,10 @@ char *find_execable(const char *filename)
52 */ 56 */
53int exists_execable(const char *filename) 57int exists_execable(const char *filename)
54{ 58{
55 char *ret = find_execable(filename); 59 char *path = xstrdup(getenv("PATH"));
60 char *tmp = path;
61 char *ret = find_execable(filename, &tmp);
62 free(path);
56 if (ret) { 63 if (ret) {
57 free(ret); 64 free(ret);
58 return 1; 65 return 1;