Initial public busybox upstream commit
[busybox4maemo] / libbb / execable.c
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 tarball for details.
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 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 $PATH for an executable file;
23  * return allocated string containing full path if found;
24  * return NULL otherwise;
25  */
26 char *find_execable(const char *filename)
27 {
28         char *path, *p, *n;
29
30         p = path = xstrdup(getenv("PATH"));
31         while (p) {
32                 n = strchr(p, ':');
33                 if (n)
34                         *n++ = '\0';
35                 if (*p != '\0') { /* it's not a PATH="foo::bar" situation */
36                         p = concat_path_file(p, filename);
37                         if (execable_file(p)) {
38                                 free(path);
39                                 return p;
40                         }
41                         free(p);
42                 }
43                 p = n;
44         }
45         free(path);
46         return NULL;
47 }
48
49 /* search $PATH for an executable file;
50  * return 1 if found;
51  * return 0 otherwise;
52  */
53 int exists_execable(const char *filename)
54 {
55         char *ret = find_execable(filename);
56         if (ret) {
57                 free(ret);
58                 return 1;
59         }
60         return 0;
61 }
62
63 #if ENABLE_FEATURE_PREFER_APPLETS
64 /* just like the real execvp, but try to launch an applet named 'file' first
65  */
66 int bb_execvp(const char *file, char *const argv[])
67 {
68         return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file,
69                                         argv);
70 }
71 #endif