aboutsummaryrefslogtreecommitdiff
path: root/libbb/executable.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-05-06 20:41:10 +0100
committerRon Yorston <rmy@pobox.com>2014-05-06 20:41:10 +0100
commitd3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e (patch)
tree4b364ba4b6b9e96c2629fe382fef0248d76833dd /libbb/executable.c
parent7905d97aeece18da362a5a1e066abff2d2e5c16b (diff)
parentd257608a8429b64e1a04c7cb6d99975eeb2c3955 (diff)
downloadbusybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.tar.gz
busybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.tar.bz2
busybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.zip
Merge branch 'busybox' into merge
Conflicts: debianutils/which.c editors/vi.c libbb/executable.c
Diffstat (limited to 'libbb/executable.c')
-rw-r--r--libbb/executable.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/libbb/executable.c b/libbb/executable.c
new file mode 100644
index 000000000..2e5f6a1b7
--- /dev/null
+++ b/libbb/executable.c
@@ -0,0 +1,106 @@
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 */
16int FAST_FUNC file_is_executable(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_executable 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#if !ENABLE_PLATFORM_MINGW32
32#define next_path_sep(s) strchr(s, ':')
33#endif
34
35char* FAST_FUNC find_executable(const char *filename, char **PATHp)
36{
37 /* About empty components in $PATH:
38 * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
39 * 8.3 Other Environment Variables - PATH
40 * A zero-length prefix is a legacy feature that indicates the current
41 * working directory. It appears as two adjacent colons ( "::" ), as an
42 * initial colon preceding the rest of the list, or as a trailing colon
43 * following the rest of the list.
44 */
45 char *p, *n;
46#if ENABLE_PLATFORM_MINGW32
47 char *w;
48#endif
49
50 p = *PATHp;
51 while (p) {
52 n = (char*)next_path_sep(p);
53 if (n)
54 *n++ = '\0';
55 p = concat_path_file(
56 p[0] ? p : ".", /* handle "::" case */
57 filename
58 );
59 if (file_is_executable(p)) {
60 *PATHp = n;
61 return p;
62 }
63#if ENABLE_PLATFORM_MINGW32
64 else if ((w=win32_execable_file(p))) {
65 *PATHp = n;
66 free(p);
67 return w;
68 }
69#endif
70 free(p);
71 p = n;
72 } /* on loop exit p == NULL */
73 return p;
74}
75
76/* search $PATH for an executable file;
77 * return 1 if found;
78 * return 0 otherwise;
79 */
80int FAST_FUNC executable_exists(const char *filename)
81{
82 char *path = xstrdup(getenv("PATH"));
83 char *tmp = path;
84 char *ret = find_executable(filename, &tmp);
85 free(path);
86 free(ret);
87 return ret != NULL;
88}
89
90#if ENABLE_FEATURE_PREFER_APPLETS
91/* just like the real execvp, but try to launch an applet named 'file' first */
92int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
93{
94 if (find_applet_by_name(file) >= 0)
95 execvp(bb_busybox_exec_path, argv);
96 return execvp(file, argv);
97}
98#endif
99
100int FAST_FUNC BB_EXECVP_or_die(char **argv)
101{
102 BB_EXECVP(argv[0], argv);
103 /* SUSv3-mandated exit codes */
104 xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
105 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
106}