summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c4
-rw-r--r--shell/hush.c61
2 files changed, 60 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 35d5cde58..eca4ab98c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12985,7 +12985,7 @@ init(void)
/* from var.c: */
{
char **envp;
- char ppid[sizeof(int)*3 + 1];
+ char ppid[sizeof(int)*3 + 2];
const char *p;
struct stat st1, st2;
@@ -12996,7 +12996,7 @@ init(void)
}
}
- snprintf(ppid, sizeof(ppid), "%u", (unsigned) getppid());
+ sprintf(ppid, "%u", (unsigned) getppid());
setvar("PPID", ppid, 0);
p = lookupvar("PWD");
diff --git a/shell/hush.c b/shell/hush.c
index 7ac29ace2..5794b1ddf 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -58,7 +58,7 @@
* TODOs:
* grep for "TODO" and fix (some of them are easy)
* builtins: ulimit
- * special variables (PWD etc)
+ * special variables (done: PWD)
* follow IFS rules more precisely, including update semantics
* export builtin should be special, its arguments are assignments
* and therefore expansion of them should be "one-word" expansion:
@@ -1432,6 +1432,13 @@ static int set_local_var(char *str, int flg_export, int local_lvl, int flg_read_
return 0;
}
+/* Used at startup and after each cd */
+static void set_pwd_var(int exp)
+{
+ set_local_var(xasprintf("PWD=%s", get_cwd(/*force:*/ 1)),
+ /*exp:*/ exp, /*lvl:*/ 0, /*ro:*/ 0);
+}
+
static int unset_local_var_len(const char *name, int name_len)
{
struct variable *cur;
@@ -1604,6 +1611,9 @@ static const char* setup_prompt_string(int promptmode)
/* Set up the prompt */
if (promptmode == 0) { /* PS1 */
free((char*)G.PS1);
+ /* bash uses $PWD value, even if it is set by user.
+ * It uses current dir only if PWD is unset.
+ * We always use current dir. */
G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
prompt_str = G.PS1;
} else
@@ -6432,8 +6442,49 @@ int hush_main(int argc, char **argv)
}
e++;
}
+ /* reinstate HUSH_VERSION */
debug_printf_env("putenv '%s'\n", hush_version_str);
- putenv((char *)hush_version_str); /* reinstate HUSH_VERSION */
+ putenv((char *)hush_version_str);
+
+ /* Export PWD */
+ set_pwd_var(/*exp:*/ 1);
+ /* bash also exports SHLVL and _,
+ * and sets (but doesn't export) the following variables:
+ * BASH=/bin/bash
+ * BASH_VERSINFO=([0]="3" [1]="2" [2]="0" [3]="1" [4]="release" [5]="i386-pc-linux-gnu")
+ * BASH_VERSION='3.2.0(1)-release'
+ * HOSTTYPE=i386
+ * MACHTYPE=i386-pc-linux-gnu
+ * OSTYPE=linux-gnu
+ * HOSTNAME=<xxxxxxxxxx>
+ * PPID=<NNNNN>
+ * EUID=<NNNNN>
+ * UID=<NNNNN>
+ * GROUPS=()
+ * LINES=<NNN>
+ * COLUMNS=<NNN>
+ * BASH_ARGC=()
+ * BASH_ARGV=()
+ * BASH_LINENO=()
+ * BASH_SOURCE=()
+ * DIRSTACK=()
+ * PIPESTATUS=([0]="0")
+ * HISTFILE=/<xxx>/.bash_history
+ * HISTFILESIZE=500
+ * HISTSIZE=500
+ * MAILCHECK=60
+ * PATH=/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
+ * SHELL=/bin/bash
+ * SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
+ * TERM=dumb
+ * OPTERR=1
+ * OPTIND=1
+ * IFS=$' \t\n'
+ * PS1='\s-\v\$ '
+ * PS2='> '
+ * PS4='+ '
+ */
+
#if ENABLE_FEATURE_EDITING
G.line_input_state = new_line_input_t(FOR_SHELL);
#endif
@@ -6816,7 +6867,11 @@ static int FAST_FUNC builtin_cd(char **argv)
bb_perror_msg("cd: %s", newdir);
return EXIT_FAILURE;
}
- get_cwd(1);
+ /* Read current dir (get_cwd(1) is inside) and set PWD.
+ * Note: do not enforce exporting. If PWD was unset or unexported,
+ * set it again, but do not export. bash does the same.
+ */
+ set_pwd_var(/*exp:*/ 0);
return EXIT_SUCCESS;
}