NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: 'cd' if HOME is unset



Jan Schaumann <jschauma%netmeister.org@localhost> 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


Home | Main Index | Thread Index | Old Index