mirror of https://github.com/sheumann/hush.git
Add code to get the path of the current executable, which we need to re-execute the shell.
On the GS, this uses GS/OS calls. Versions for OS X and Linux are also included.
This commit is contained in:
parent
6bd3b140ea
commit
bff0844d44
3
Makefile
3
Makefile
|
@ -35,7 +35,8 @@ LIBBB_B_SRC = \
|
|||
libbb/escape.seq.c \
|
||||
libbb/messages.c \
|
||||
libbb/bb.basename.c \
|
||||
libbb/mempcpy.c
|
||||
libbb/mempcpy.c \
|
||||
libbb/get.exec.path.c
|
||||
|
||||
LIBBB_C_SRC = \
|
||||
libbb/perror.msg.c \
|
||||
|
|
|
@ -50,7 +50,8 @@ SRCS = \
|
|||
libbb/bb.basename.c \
|
||||
libbb/mempcpy.c \
|
||||
libbb/vfork.and.run.c \
|
||||
libbb/poll.c
|
||||
libbb/poll.c \
|
||||
libbb/get.exec.path.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
INCLUDES = -I include -I shell -I libbb
|
||||
|
|
|
@ -228,8 +228,6 @@
|
|||
#define ENABLE_FEATURE_PREFER_APPLETS 0
|
||||
#define IF_FEATURE_PREFER_APPLETS(x)
|
||||
#define IF_NOT_FEATURE_PREFER_APPLETS(x) x
|
||||
#define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe"
|
||||
#define ENABLE_BUSYBOX_EXEC_PATH 1
|
||||
#ifdef MAKE_SUID
|
||||
# define IF_BUSYBOX_EXEC_PATH(x) x "CONFIG_BUSYBOX_EXEC_PATH"
|
||||
#else
|
||||
|
|
|
@ -1520,7 +1520,6 @@ extern const char bb_path_wtmp_file[] ALIGN1;
|
|||
#else
|
||||
# define bb_dev_null ".null"
|
||||
#endif
|
||||
extern const char bb_busybox_exec_path[] ALIGN1;
|
||||
|
||||
extern const int const_int_0;
|
||||
extern const int const_int_1;
|
||||
|
@ -1639,6 +1638,8 @@ static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a)
|
|||
*/
|
||||
int signal_parent_to_resume(void);
|
||||
|
||||
/* Get path of current executable */
|
||||
char *get_exec_path(void);
|
||||
|
||||
/* Simple unit-testing framework */
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Code to get the full path of the currently-running executable on various platforms.
|
||||
*
|
||||
* By Stephen Heumann
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* This should return a pointer that can be deallocated with free() when done,
|
||||
* or NULL on failure. */
|
||||
char *get_exec_path(void);
|
||||
|
||||
|
||||
#ifdef __appleiigs__
|
||||
|
||||
#include <gsos.h>
|
||||
#include <orca.h>
|
||||
|
||||
/* Prefix 1 is set to the directory containing the executable at launch.
|
||||
* We append the result of a GetName call to this to get the full pathname.
|
||||
*/
|
||||
char *get_exec_path(void) {
|
||||
PrefixRecGS prefixRec;
|
||||
GetNameRecGS nameRec;
|
||||
ResultBuf255 *prefix, *name;
|
||||
char *result;
|
||||
|
||||
prefix = malloc(sizeof(ResultBuf255));
|
||||
if (prefix == NULL)
|
||||
return NULL;
|
||||
prefixRec.pCount = 2;
|
||||
prefixRec.prefixNum = 1; /* Info for prefix 1 */
|
||||
prefixRec.buffer.getPrefix = prefix;
|
||||
prefix->bufSize = sizeof(ResultBuf255);
|
||||
|
||||
GetPrefixGS(&prefixRec);
|
||||
if (toolerror()) {
|
||||
free(prefix);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = malloc(sizeof(ResultBuf255));
|
||||
if (name == NULL) {
|
||||
free(prefix);
|
||||
return NULL;
|
||||
}
|
||||
nameRec.pCount = 1;
|
||||
nameRec.dataBuffer = name;
|
||||
name->bufSize = sizeof(ResultBuf255);
|
||||
|
||||
GetNameGS(&nameRec);
|
||||
if (toolerror()) {
|
||||
free(prefix);
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = malloc(prefix->bufString.length + name->bufString.length + 1);
|
||||
if (result == NULL) {
|
||||
free(prefix);
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(result, prefix->bufString.text, prefix->bufString.length);
|
||||
memcpy(result + prefix->bufString.length, name->bufString.text, name->bufString.length);
|
||||
result[prefix->bufString.length + name->bufString.length] = 0;
|
||||
free(prefix);
|
||||
free(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
char *get_exec_path(void) {
|
||||
char *buf;
|
||||
uint32_t bufsize = 256;
|
||||
int result;
|
||||
|
||||
while (1) {
|
||||
buf = malloc(bufsize);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
result = _NSGetExecutablePath(buf, &bufsize);
|
||||
if (result == 0)
|
||||
return buf;
|
||||
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
char *get_exec_path(void) {
|
||||
return strdup("/proc/self/exe");
|
||||
}
|
||||
|
||||
#elif defined(BSD)
|
||||
|
||||
char *get_exec_path(void) {
|
||||
/* Works on some BSDs but not all -- hope for the best! */
|
||||
return strdup("/proc/curproc/exe");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char *get_exec_path(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -35,7 +35,6 @@ const char bb_msg_standard_output[] ALIGN1 = "standard output";
|
|||
|
||||
const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
|
||||
|
||||
const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
|
||||
const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
|
||||
/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
|
||||
* but I want to save a few bytes here. Check libbb.h before changing! */
|
||||
|
|
|
@ -859,6 +859,8 @@ static struct globals G;
|
|||
struct lineedit_statics;
|
||||
struct lineedit_statics *lineedit_ptr_to_statics;
|
||||
|
||||
static char *hush_exec_path;
|
||||
|
||||
|
||||
/* Function prototypes for builtins */
|
||||
static int builtin_cd(char **argv) FAST_FUNC;
|
||||
|
@ -5874,7 +5876,7 @@ static void re_execute_shell(char ***to_free, const char *s,
|
|||
if (SPECIAL_JOBSTOP_SIGS != 0)
|
||||
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
||||
signal_parent_to_resume();
|
||||
execve(bb_busybox_exec_path, argv, pp);
|
||||
execve(hush_exec_path, argv, pp);
|
||||
/* Fallback. Useful for init=/bin/hush usage etc */
|
||||
if (argv[0][0] == '/')
|
||||
execve(argv[0], argv, pp);
|
||||
|
@ -6738,7 +6740,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
|
|||
/* Don't propagate SIG_IGN to the child */
|
||||
if (SPECIAL_JOBSTOP_SIGS != 0)
|
||||
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
||||
execv(bb_busybox_exec_path, argv);
|
||||
execv(hush_exec_path, argv);
|
||||
/* If they called chroot or otherwise made the binary no longer
|
||||
* executable, fall through */
|
||||
}
|
||||
|
@ -8031,6 +8033,7 @@ int hush_main(int argc, char **argv)
|
|||
struct variable *shell_ver;
|
||||
|
||||
INIT_G();
|
||||
hush_exec_path = get_exec_path();
|
||||
if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
|
||||
G.last_exitcode = EXIT_SUCCESS;
|
||||
#if ENABLE_HUSH_FAST
|
||||
|
|
Loading…
Reference in New Issue