source: MondoRescue/branches/3.3/mindi-busybox/libbb/executable.c@ 3901

Last change on this file since 3901 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 2.6 KB
RevLine 
[3621]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 */
31char* FAST_FUNC find_executable(const char *filename, char **PATHp)
32{
33 /* About empty components in $PATH:
34 * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
35 * 8.3 Other Environment Variables - PATH
36 * A zero-length prefix is a legacy feature that indicates the current
37 * working directory. It appears as two adjacent colons ( "::" ), as an
38 * initial colon preceding the rest of the list, or as a trailing colon
39 * following the rest of the list.
40 */
41 char *p, *n;
42
43 p = *PATHp;
44 while (p) {
45 n = strchr(p, ':');
46 if (n)
47 *n++ = '\0';
48 p = concat_path_file(
49 p[0] ? p : ".", /* handle "::" case */
50 filename
51 );
52 if (file_is_executable(p)) {
53 *PATHp = n;
54 return p;
55 }
56 free(p);
57 p = n;
58 } /* on loop exit p == NULL */
59 return p;
60}
61
62/* search $PATH for an executable file;
63 * return 1 if found;
64 * return 0 otherwise;
65 */
66int FAST_FUNC executable_exists(const char *filename)
67{
68 char *path = xstrdup(getenv("PATH"));
69 char *tmp = path;
70 char *ret = find_executable(filename, &tmp);
71 free(path);
72 free(ret);
73 return ret != NULL;
74}
75
76#if ENABLE_FEATURE_PREFER_APPLETS
77/* just like the real execvp, but try to launch an applet named 'file' first */
78int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
79{
80 if (find_applet_by_name(file) >= 0)
81 execvp(bb_busybox_exec_path, argv);
82 return execvp(file, argv);
83}
84#endif
85
86void FAST_FUNC BB_EXECVP_or_die(char **argv)
87{
88 BB_EXECVP(argv[0], argv);
89 /* SUSv3-mandated exit codes */
90 xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
91 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
92}
93
94/* Typical idiom for applets which exec *optional* PROG [ARGS] */
95void FAST_FUNC exec_prog_or_SHELL(char **argv)
96{
97 if (argv[0]) {
98 BB_EXECVP_or_die(argv);
99 }
100 run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL);
101}
Note: See TracBrowser for help on using the repository browser.