Subject: bin/1760: /bin/sh `cd -' dumps core if you've never changed directories
To: None <gnats-bugs@gnats.netbsd.org>
From: Scott Reynolds <scottr@Plexus.COM>
List: netbsd-bugs
Date: 11/13/1995 12:30:39
>Number: 1760
>Category: bin
>Synopsis: /bin/sh `cd -' dumps core if you've never changed directories
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Nov 13 13:50:02 1995
>Last-Modified:
>Originator: Scott Reynolds
>Organization:
>Release: 1.1_ALPHA, 13 Nov 1995
>Environment:
N/A
System: NetBSD beech 1.1_ALPHA NetBSD 1.1_ALPHA (TGI) #1: Mon Nov 6 18:00:40 CST 1995 scottr@beech:/amd/aqua/usr/src/sys/arch/hp300/compile/TGI hp300
>Description:
In cd.c:94, the `dest' pointer gets the value of prevdir if it's
non-NULL, otherwise it gets the value of curdir. At line 97 this
pointer gets dereferenced. Unfortunately,
>How-To-Repeat:
1) Start /bin/sh
2) Before typing anything else, enter `cd -'
3) Watch.
>Fix:
This diff has two parts. The change to cd.c removes the fork/exec
to run /bin/pwd to get the current working directory (because I
wanted to minimize the amount of time at startup, and this just
seems ugly anyway). I instead used getcwd() from libc.
The change to main.c implements the actual fix by calling getpwd()
to initialize curdir after initializing everything else of interest,
but before /etc/profile and ~/.profile are run.
If there is a real reason to retain the /bin/pwd code, that
part of the diff can be ignored with the only ill effect being
the increase in startup time and the reliance on /bin/pwd.
*** bin/sh/cd.c-dist Fri Oct 13 18:43:57 1995
--- bin/sh/cd.c Mon Nov 13 12:09:47 1995
***************
*** 328,337 ****
/*
! * Run /bin/pwd to find out what the current directory is. We suppress
! * interrupts throughout most of this, but the user can still break out
! * of it by killing the pwd program. If we already know the current
! * directory, this routine returns immediately.
*/
#define MAXPWD 256
--- 328,335 ----
/*
! * If we already know the current directory, this routine returns
! * immediately.
*/
#define MAXPWD 256
***************
*** 347,382 ****
if (curdir)
return;
! INTOFF;
! if (pipe(pip) < 0)
! error("Pipe call failed");
! jp = makejob((union node *)NULL, 1);
! if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) {
! close(pip[0]);
! if (pip[1] != 1) {
! close(1);
! copyfd(pip[1], 1);
! close(pip[1]);
! }
! execl("/bin/pwd", "pwd", (char *)0);
! error("Cannot exec /bin/pwd");
! }
! close(pip[1]);
! pip[1] = -1;
! p = buf;
! while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
! || (i == -1 && errno == EINTR)) {
! if (i > 0)
! p += i;
! }
! close(pip[0]);
! pip[0] = -1;
! status = waitforjob(jp);
! if (status != 0)
! error((char *)0);
! if (i < 0 || p == buf || p[-1] != '\n')
! error("pwd command failed");
! p[-1] = '\0';
curdir = savestr(buf);
- INTON;
}
--- 345,351 ----
if (curdir)
return;
! if (getcwd(buf, sizeof(buf)) == NULL)
! error("getcwd() failed");
curdir = savestr(buf);
}
*** bin/sh/main.c-dist Sat Oct 14 00:44:09 1995
--- bin/sh/main.c Mon Nov 13 12:14:37 1995
***************
*** 91,96 ****
--- 91,97 ----
STATIC void read_profile __P((char *));
STATIC char *find_dot_file __P((char *));
+ STATIC void getpwd __P((void));
/*
* Main routine. We initialize things, parse the arguments, execute
***************
*** 159,164 ****
--- 160,166 ----
init();
setstackmark(&smark);
procargs(argc, argv);
+ getpwd();
if (argv[0] && argv[0][0] == '-') {
state = 1;
read_profile("/etc/profile");
>Audit-Trail:
>Unformatted: