From yar@bsd.chem.msu.ru  Mon Oct 16 09:30:46 2006
Return-Path: <yar@bsd.chem.msu.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 9377D16A412
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Oct 2006 09:30:46 +0000 (UTC)
	(envelope-from yar@bsd.chem.msu.ru)
Received: from bsd.chem.msu.ru (bsd.chem.msu.ru [195.208.208.23])
	by mx1.FreeBSD.org (Postfix) with ESMTP id CD71843D6A
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Oct 2006 09:30:45 +0000 (GMT)
	(envelope-from yar@bsd.chem.msu.ru)
Received: from bsd.chem.msu.ru (localhost [127.0.0.1])
	by bsd.chem.msu.ru (8.13.4/8.13.3) with ESMTP id k9G9UgZO009632
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Oct 2006 13:30:42 +0400 (MSD)
	(envelope-from yar@bsd.chem.msu.ru)
Received: (from yar@localhost)
	by bsd.chem.msu.ru (8.13.4/8.13.3/Submit) id k9G9Uc7f009631;
	Mon, 16 Oct 2006 13:30:38 +0400 (MSD)
	(envelope-from yar)
Message-Id: <200610160930.k9G9Uc7f009631@bsd.chem.msu.ru>
Date: Mon, 16 Oct 2006 13:30:38 +0400 (MSD)
From: Yar Tikhiy <yar@comp.chem.msu.su>
To: FreeBSD-gnats-submit@freebsd.org
Subject: /bin/sh unable to enter deep directories
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         104456
>Category:       bin
>Synopsis:       sh(1): /bin/sh unable to enter deep directories
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    stefanf
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Oct 16 09:40:18 GMT 2006
>Closed-Date:    Sun May 16 10:03:00 UTC 2010
>Last-Modified:  Sun May 16 10:03:00 UTC 2010
>Originator:     Yar Tikhiy
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
None
>Environment:

	FreeBSD 7.0-CURRENT i386

>Description:

	/bin/sh will fail to cd to a subdirectory after the path
	to the current directory exceeds PATH_MAX.  This is not an
	unsolvable problem; /bin/csh doesn't suffer from it.

>How-To-Repeat:

Script started on Mon Oct 16 13:03:25 2006
$ pwd
/usr/home/yar
$ n=`printf %0255d 0`
$ mkdir $n && cd $n
$ mkdir $n && cd $n
$ mkdir $n && cd $n
$ mkdir $n && cd $n
cd: can't cd to 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
$ pwd
pwd: .: Result too large
$ exit

Script done on Mon Oct 16 13:04:05 2006

>Fix:
>Release-Note:
>Audit-Trail:

From: Yar Tikhiy <yar@comp.chem.msu.su>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/104456: /bin/sh unable to enter deep directories
Date: Tue, 17 Oct 2006 21:44:50 +0400

 At the same time, csh has another silly limit, as do all shells
 that export $PWD.  Even if they can pass the PATH_MAX border by
 constructing $PWD without help from getcwd(), the large string
 eventually overflows the environment due to the ARG_MAX limit,
 and external commands fail to run after that with E2BIG errno.
 
 -- 
 Yar
Responsible-Changed-From-To: freebsd-bugs->stefanf 
Responsible-Changed-By: stefanf 
Responsible-Changed-When: Sun Feb 24 21:01:32 UTC 2008 
Responsible-Changed-Why:  
Grab. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=104456 
State-Changed-From-To: open->patched 
State-Changed-By: stefanf 
State-Changed-When: Sat Nov 21 14:55:01 UTC 2009 
State-Changed-Why:  
Fixed in head. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=104456 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/104456: commit references a PR
Date: Sat, 21 Nov 2009 14:53:39 +0000 (UTC)

 Author: stefanf
 Date: Sat Nov 21 14:53:22 2009
 New Revision: 199631
 URL: http://svn.freebsd.org/changeset/base/199631
 
 Log:
   Handle current work directories of arbitrary length.  The argument to cd
   continues to be limited by PATH_MAX (1024).
   
   Obtained from:	NetBSD
   PR:		104456
 
 Modified:
   head/bin/sh/cd.c
 
 Modified: head/bin/sh/cd.c
 ==============================================================================
 --- head/bin/sh/cd.c	Sat Nov 21 14:53:08 2009	(r199630)
 +++ head/bin/sh/cd.c	Sat Nov 21 14:53:22 2009	(r199631)
 @@ -70,7 +70,7 @@ STATIC int docd(char *, int, int);
  STATIC char *getcomponent(void);
  STATIC char *findcwd(char *);
  STATIC void updatepwd(char *);
 -STATIC char *getpwd2(char *, size_t);
 +STATIC char *getpwd2(void);
  
  STATIC char *curdir = NULL;	/* current working directory */
  STATIC char *prevdir;		/* previous working directory */
 @@ -263,10 +263,8 @@ findcwd(char *dir)
  	 * any more because we traversed a symbolic link or something
  	 * we couldn't stat().
  	 */
 -	if (dir == NULL || curdir == NULL)  {
 -		p = stalloc(PATH_MAX);
 -		return getpwd2(p, PATH_MAX);
 -	}
 +	if (dir == NULL || curdir == NULL)
 +		return getpwd2();
  	cdcomppath = stalloc(strlen(dir) + 1);
  	scopy(dir, cdcomppath);
  	STARTSTACKSTR(new);
 @@ -313,7 +311,7 @@ updatepwd(char *dir)
  int
  pwdcmd(int argc, char **argv)
  {
 -	char buf[PATH_MAX];
 +	char *p;
  	int ch, phys;
  
  	optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
 @@ -341,9 +339,9 @@ pwdcmd(int argc, char **argv)
  		out1str(curdir);
  		out1c('\n');
  	} else {
 -		if (getcwd(buf, sizeof(buf)) == NULL)
 +		if ((p = getpwd2()) == NULL)
  			error(".: %s", strerror(errno));
 -		out1str(buf);
 +		out1str(p);
  		out1c('\n');
  	}
  
 @@ -356,36 +354,45 @@ pwdcmd(int argc, char **argv)
  char *
  getpwd(void)
  {
 -	char buf[PATH_MAX];
  	char *p;
  
  	if (curdir)
  		return curdir;
  
 -	p = getpwd2(buf, sizeof(buf));
 +	p = getpwd2();
  	if (p != NULL)
  		curdir = savestr(p);
  
  	return curdir;
  }
  
 +#define MAXPWD 256
 +
  /*
   * Return the current directory.
   */
  STATIC char *
 -getpwd2(char *buf, size_t size)
 +getpwd2(void)
  {
 -	if (getcwd(buf, size) == NULL) {
 -		char *pwd = getenv("PWD");
 -		struct stat stdot, stpwd;
 -
 -		if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
 -		    stat(pwd, &stpwd) != -1 &&
 -		    stdot.st_dev == stpwd.st_dev &&
 -		    stdot.st_ino == stpwd.st_ino) {
 +	struct stat stdot, stpwd;
 +	char *pwd;
 +	int i;
 +
 +	for (i = MAXPWD;; i *= 2) {
 +		pwd = stalloc(i);
 +		if (getcwd(pwd, i) != NULL)
  			return pwd;
 -		}
 -		return NULL;
 +		stunalloc(pwd);
 +		if (errno != ERANGE)
 +			break;
 +	}
 +
 +	pwd = getenv("PWD");
 +	if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
 +	    stat(pwd, &stpwd) != -1 &&
 +	    stdot.st_dev == stpwd.st_dev &&
 +	    stdot.st_ino == stpwd.st_ino) {
 +		return pwd;
  	}
 -	return buf;
 +	return NULL;
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: stefanf 
State-Changed-When: Sun May 16 10:01:33 UTC 2010 
State-Changed-Why:  
This has been merged into 7 and 8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=104456 
>Unformatted:
