about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--Src/Modules/newuser.c5
-rw-r--r--Src/init.c20
-rw-r--r--Src/params.c5
-rw-r--r--Src/subst.c2
-rw-r--r--Src/utils.c4
6 files changed, 23 insertions, 16 deletions
diff --git a/README b/README
index e27d3ea1d..cfad042a0 100644
--- a/README
+++ b/README
@@ -31,6 +31,9 @@ variables as an error, so can still return status 0 (depending on the
 handling of other arguments).  This appears to be the standard shell
 behaviour.
 
+The variable HOME is no longer set by the shell; it must be present
+in the environment.  It is valid for the variable to be unset.
+
 Documentation
 -------------
 
diff --git a/Src/Modules/newuser.c b/Src/Modules/newuser.c
index ba66d56f3..72d16e272 100644
--- a/Src/Modules/newuser.c
+++ b/Src/Modules/newuser.c
@@ -67,8 +67,11 @@ boot_(UNUSED(Module m))
     if (emulation != EMULATE_ZSH)
 	return 0;
 
-    if (!dotdir)
+    if (!dotdir) {
 	dotdir = home;
+	if (!dotdir)
+	    return;
+    }
 
     if (check_dotfile(dotdir, ".zshenv") == 0 ||
 	check_dotfile(dotdir, ".zprofile") == 0 ||
diff --git a/Src/init.c b/Src/init.c
index 6751df6ba..adb6eb84a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -795,22 +795,23 @@ setupvals(void)
      * recheck the info for `USERNAME'     */
     cached_uid = getuid();
 
-    /* Get password entry and set info for `HOME' and `USERNAME' */
+    /* Get password entry and set info for `USERNAME' */
 #ifdef HAVE_GETPWUID
     if ((pswd = getpwuid(cached_uid))) {
-	home = metafy(pswd->pw_dir, -1, META_DUP);
 	cached_username = ztrdup(pswd->pw_name);
     } else
 #endif /* HAVE_GETPWUID */
 	   {
-	home = ztrdup("/");
 	cached_username = ztrdup("");
     }
 
-    /* Try a cheap test to see if we can *
-     * initialize `PWD' from `HOME'      */
-    if (ispwd(home))
-	pwd = ztrdup(home);
+    /*
+     * Try a cheap test to see if we can initialize `PWD' from `HOME'.
+     * HOME must come from the environment; we're not allowed to
+     * set it locally.
+     */
+    if ((ptr = getenv("HOME")) && ispwd(ptr))
+	pwd = ztrdup(ptr);
     else if ((ptr = zgetenv("PWD")) && (strlen(ptr) < PATH_MAX) &&
 	     (ptr = metafy(ptr, -1, META_STATIC), ispwd(ptr)))
 	pwd = ztrdup(ptr);
@@ -1105,8 +1106,11 @@ sourcehome(char *s)
 
     queue_signals();
     if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
-	!(h = getsparam("ZDOTDIR")))
+	!(h = getsparam("ZDOTDIR"))) {
 	h = home;
+	if (!h)
+	    return;
+    }
 
     {
 	/* Let source() complain if path is too long */
diff --git a/Src/params.c b/Src/params.c
index 0d3b6a25b..5e4231cac 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -257,7 +257,7 @@ IPDEF1("TTYIDLE", ttyidle_gsu, PM_READONLY),
 IPDEF2("USERNAME", username_gsu, PM_DONTIMPORT|PM_RESTRICTED),
 IPDEF2("-", dash_gsu, PM_READONLY),
 IPDEF2("histchars", histchars_gsu, PM_DONTIMPORT),
-IPDEF2("HOME", home_gsu, 0),
+IPDEF2("HOME", home_gsu, PM_UNSET),
 IPDEF2("TERM", term_gsu, 0),
 IPDEF2("WORDCHARS", wordchars_gsu, 0),
 IPDEF2("IFS", ifs_gsu, PM_DONTIMPORT),
@@ -690,9 +690,6 @@ createparamtable(void)
     *envp = '\0';
     opts[ALLEXPORT] = oae;
 
-    pm = (Param) paramtab->getnode(paramtab, "HOME");
-    if (!(pm->flags & PM_EXPORTED))
-	addenv(pm, home);
     pm = (Param) paramtab->getnode(paramtab, "LOGNAME");
     if (!(pm->flags & PM_EXPORTED))
 	addenv(pm, pm->u.str);
diff --git a/Src/subst.c b/Src/subst.c
index d92be8f89..bbe7b3f07 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -417,7 +417,7 @@ filesubstr(char **namptr, int assign)
 
 	val = zstrtol(str + 1, &ptr, 10);
 	if (isend(str[1])) {   /* ~ */
-	    *namptr = dyncat(home, str + 1);
+	    *namptr = dyncat(home ? home : "", str + 1);
 	    return 1;
 	} else if (str[1] == '+' && isend(str[2])) {   /* ~+ */
 	    *namptr = dyncat(pwd, str + 2);
diff --git a/Src/utils.c b/Src/utils.c
index 5a1c5ab30..dcaac9661 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -630,8 +630,8 @@ finddir(char *s)
      * whenever a node is added to or removed from the hash table, and *
      * whenever the value of $HOME changes.  (On startup, too.)        */
     if (!s) {
-	homenode.dir = home;
-	homenode.diff = strlen(home);
+	homenode.dir = home ? home : "";
+	homenode.diff = home ? strlen(home) : 0;
 	if(homenode.diff==1)
 	    homenode.diff = 0;
 	if(!finddir_full)