hush: export PWD
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 5 Sep 2009 18:15:17 +0000 (20:15 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 5 Sep 2009 18:15:17 +0000 (20:15 +0200)
function                                             old     new   delta
set_pwd_var                                            -      36     +36
hush_main                                            941     951     +10
evalvar                                             1365    1363      -2
ash_main                                            1364    1362      -2
builtin_cd                                            75      72      -3
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 46/-7)              Total: 39 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/hush.c

index 35d5cde5862f5631edd1c8ea87b0b6fce4cfd8be..eca4ab98cc820c4c2c9536b79bddf99d7d0a08d7 100644 (file)
@@ -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");
index 7ac29ace2ef8c60ccf43816467d2d2e4bfbee931..5794b1ddfe761eae04116c6ed17637d5de5dfcfb 100644 (file)
@@ -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;
 }