Jan Schaumann <jscha...@netmeister.org> wrote:

> "A common extension when HOME is undefined is to get
> the login directory from the user database for the
> invoking user. This does not occur on System V
> implementations."
> 
> I'm surprised that /bin/sh does not use the user's
> home directory from getpwuid() in that case

Attached is a proposed patch to change this such that
/bin/sh and /bin/ksh would fall back to
getpwuid()->pw_dir if HOME is unset as suggested by
POSIX as a "common extension".

What do you think?

-Jan
Index: ksh/c_ksh.c
===================================================================
RCS file: /cvsroot/src/bin/ksh/c_ksh.c,v
retrieving revision 1.29
diff -u -p -r1.29 c_ksh.c
--- ksh/c_ksh.c 3 Jun 2018 12:18:29 -0000       1.29
+++ ksh/c_ksh.c 24 Dec 2022 23:01:47 -0000
@@ -10,6 +10,7 @@ __RCSID("$NetBSD: c_ksh.c,v 1.29 2018/06
 #endif
 
 #include <sys/stat.h>
+#include <pwd.h>
 #include <ctype.h>
 
 #include "sh.h"
@@ -30,6 +31,7 @@ c_cd(wp)
        int phys_path;
        char *cdpath;
        char *fdir = NULL;
+       struct passwd *p;
 
        while ((optc = ksh_getopt(wp, &builtin_opt, "LP")) != EOF)
                switch (optc) {
@@ -55,8 +57,12 @@ c_cd(wp)
        if (!wp[0]) {
                /* No arguments - go home */
                if ((dir = str_val(global("HOME"))) == null) {
-                       bi_errorf("no home directory (HOME not set)");
-                       return 1;
+                       if ((p = getpwuid(getuid())) == NULL) {
+                               bi_errorf("getpwuid() failed: %s", 
strerror(errno));
+                               return 1;
+                       } else {
+                               dir = p->pw_dir;
+                       }
                }
        } else if (!wp[1]) {
                /* One argument: - or dir */
Index: ksh/ksh.Man
===================================================================
RCS file: /cvsroot/src/bin/ksh/ksh.Man,v
retrieving revision 1.26
diff -u -p -r1.26 ksh.Man
--- ksh/ksh.Man 26 Aug 2018 22:52:34 -0000      1.26
+++ ksh/ksh.Man 24 Dec 2022 23:01:48 -0000
@@ -1739,7 +1739,9 @@ An empty entry in the \fBCDPATH\fP entry
 If a non-empty directory from \fBCDPATH\fP is used, the resulting full
 path is printed to standard output.
 If \fIdir\fP is
-missing, the home directory \fB$HOME\fP is used.
+missing, the home directory \fB$HOME\fP is used;
+if \fB$HOME\fP is unset, the user's home directory is
+determined from the password database.
 If \fIdir\fP is
 \fB\-\fP, the previous working directory is used (see OLDPWD parameter).
 If \fB\-L\fP option (logical path) is used or if the \fBphysical\fP option
Index: sh/cd.c
===================================================================
RCS file: /cvsroot/src/bin/sh/cd.c,v
retrieving revision 1.50
diff -u -p -r1.50 cd.c
--- sh/cd.c     5 Jul 2017 20:00:27 -0000       1.50
+++ sh/cd.c     24 Dec 2022 23:01:48 -0000
@@ -43,6 +43,7 @@ __RCSID("$NetBSD: cd.c,v 1.50 2017/07/05
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <pwd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -83,6 +84,7 @@ cdcmd(int argc, char **argv)
        const char *path, *cp;
        char *p;
        char *d;
+       struct passwd *pwd;
        struct stat statb;
        int print = cdprint;    /* set -o cdprint to enable */
 
@@ -97,8 +99,13 @@ cdcmd(int argc, char **argv)
        dest = *argptr;
        if (dest == NULL) {
                dest = bltinlookup("HOME", 1);
-               if (dest == NULL)
-                       error("HOME not set");
+               if (dest == NULL) {
+                       if ((pwd = getpwuid(getuid())) == NULL) {
+                               error("getpwuid() failed: %s", strerror(errno));
+                       } else {
+                               dest = pwd->pw_dir;
+                       }
+               }
        } else if (argptr[1]) {
                /* Do 'ksh' style substitution */
                if (!curdir)
Index: sh/sh.1
===================================================================
RCS file: /cvsroot/src/bin/sh/sh.1,v
retrieving revision 1.229
diff -u -p -r1.229 sh.1
--- sh/sh.1     18 Sep 2020 07:21:26 -0000      1.229
+++ sh/sh.1     24 Dec 2022 23:01:50 -0000
@@ -31,7 +31,7 @@
 .\"
 .\"    @(#)sh.1        8.6 (Berkeley) 5/4/95
 .\"
-.Dd September 18, 2020
+.Dd December 24, 2022
 .Dt SH 1
 .\" everything except c o and s (keep them ordered)
 .ds flags abCEeFfhIiLmnpquVvXx
@@ -2431,7 +2431,9 @@ of utilities, the name for built-ins or 
 .\"
 .It Ic cd Oo Fl P Oc Op Ar directory Op Ar replace
 Switch to the specified directory (default
-.Ev $HOME ) .
+.Ev $HOME ,
+or, if unset, the home directory of the current user
+as specified in the password database).
 If
 .Ar replace
 is specified, then the new directory name is generated by replacing

Reply via email to