1 | /* vi: set sw=4 ts=4: */
|
---|
2 | /*
|
---|
3 | * Utility routines.
|
---|
4 | *
|
---|
5 | * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
|
---|
6 | *
|
---|
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree.
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include "libbb.h"
|
---|
11 |
|
---|
12 | /* check if path points to an executable file;
|
---|
13 | * return 1 if found;
|
---|
14 | * return 0 otherwise;
|
---|
15 | */
|
---|
16 | int FAST_FUNC execable_file(const char *name)
|
---|
17 | {
|
---|
18 | struct stat s;
|
---|
19 | return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode));
|
---|
20 | }
|
---|
21 |
|
---|
22 | /* search (*PATHp) for an executable file;
|
---|
23 | * return allocated string containing full path if found;
|
---|
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/).
|
---|
30 | */
|
---|
31 | char* FAST_FUNC find_execable(const char *filename, char **PATHp)
|
---|
32 | {
|
---|
33 | char *p, *n;
|
---|
34 |
|
---|
35 | p = *PATHp;
|
---|
36 | while (p) {
|
---|
37 | n = strchr(p, ':');
|
---|
38 | if (n)
|
---|
39 | *n++ = '\0';
|
---|
40 | if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
|
---|
41 | p = concat_path_file(p, filename);
|
---|
42 | if (execable_file(p)) {
|
---|
43 | *PATHp = n;
|
---|
44 | return p;
|
---|
45 | }
|
---|
46 | free(p);
|
---|
47 | }
|
---|
48 | p = n;
|
---|
49 | } /* on loop exit p == NULL */
|
---|
50 | return p;
|
---|
51 | }
|
---|
52 |
|
---|
53 | /* search $PATH for an executable file;
|
---|
54 | * return 1 if found;
|
---|
55 | * return 0 otherwise;
|
---|
56 | */
|
---|
57 | int FAST_FUNC exists_execable(const char *filename)
|
---|
58 | {
|
---|
59 | char *path = xstrdup(getenv("PATH"));
|
---|
60 | char *tmp = path;
|
---|
61 | char *ret = find_execable(filename, &tmp);
|
---|
62 | free(path);
|
---|
63 | if (ret) {
|
---|
64 | free(ret);
|
---|
65 | return 1;
|
---|
66 | }
|
---|
67 | return 0;
|
---|
68 | }
|
---|
69 |
|
---|
70 | #if ENABLE_FEATURE_PREFER_APPLETS
|
---|
71 | /* just like the real execvp, but try to launch an applet named 'file' first
|
---|
72 | */
|
---|
73 | int FAST_FUNC bb_execvp(const char *file, char *const argv[])
|
---|
74 | {
|
---|
75 | return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file,
|
---|
76 | argv);
|
---|
77 | }
|
---|
78 | #endif
|
---|
79 |
|
---|
80 | int FAST_FUNC BB_EXECVP_or_die(char **argv)
|
---|
81 | {
|
---|
82 | BB_EXECVP(argv[0], argv);
|
---|
83 | /* SUSv3-mandated exit codes */
|
---|
84 | xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
|
---|
85 | bb_perror_msg_and_die("can't execute '%s'", argv[0]);
|
---|
86 | }
|
---|