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 */ 16int 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 */ 31char* 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 */ 57int 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 */ 73int 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 80int 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} 87