Imported from ../bash-3.1.tar.gz.

This commit is contained in:
Jari Aalto 2005-12-07 14:08:12 +00:00
commit 95732b497d
267 changed files with 24541 additions and 18843 deletions

View file

@ -1,7 +1,7 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
Copyright (C) 1987-2003 Free Software Foundation, Inc.
Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -59,6 +59,7 @@ extern int array_needs_making;
extern char *bash_getcwd_errstr;
static int bindpwd __P((int));
static void setpwd __P((char *));
static int change_to_directory __P((char *, int));
static char *cdspell __P((char *));
@ -84,6 +85,23 @@ instead of following symbolic links; the -L option forces symbolic links
to be followed.
$END
/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */
static void
setpwd (dirname)
char *dirname;
{
int old_anm;
SHELL_VAR *tvar;
old_anm = array_needs_making;
tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
array_needs_making = 0;
}
}
static int
bindpwd (no_symlinks)
int no_symlinks;
@ -100,19 +118,14 @@ bindpwd (no_symlinks)
old_anm = array_needs_making;
pwdvar = get_string_value ("PWD");
tvar = bind_variable ("OLDPWD", pwdvar);
tvar = bind_variable ("OLDPWD", pwdvar, 0);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
array_needs_making = 0;
}
tvar = bind_variable ("PWD", dirname ? dirname : "");
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
array_needs_making = 0;
}
setpwd (dirname);
if (dirname && dirname != the_current_working_directory)
free (dirname);
@ -233,9 +246,13 @@ cd_builtin (list)
printf ("%s\n", path);
free (temp);
#if 0
/* Posix.2 says that after using CDPATH, the resultant
value of $PWD will not contain `.' or `..'. */
return (bindpwd (posixly_correct || no_symlinks));
#else
return (bindpwd (no_symlinks));
#endif
}
else
free (temp);
@ -298,7 +315,7 @@ cd_builtin (list)
$BUILTIN pwd
$FUNCTION pwd_builtin
$SHORT_DOC pwd [-PL]
$SHORT_DOC pwd [-LP]
Print the current working directory. With the -P option, pwd prints
the physical directory, without any symbolic links; the -L option
makes pwd follow symbolic links.
@ -314,16 +331,17 @@ pwd_builtin (list)
WORD_LIST *list;
{
char *directory;
int opt;
int opt, pflag;
verbatim_pwd = no_symbolic_links;
pflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
verbatim_pwd = 1;
verbatim_pwd = pflag = 1;
break;
case 'L':
verbatim_pwd = 0;
@ -342,7 +360,8 @@ pwd_builtin (list)
/* Try again using getcwd() if canonicalization fails (for instance, if
the file system has changed state underneath bash). */
if (tcwd && directory == 0)
if ((tcwd && directory == 0) ||
(posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
directory = resetpwd ("pwd");
#undef tcwd
@ -350,12 +369,15 @@ pwd_builtin (list)
if (directory)
{
printf ("%s\n", directory);
/* This is dumb but posix-mandated. */
if (posixly_correct && pflag)
setpwd (directory);
if (directory != the_current_working_directory)
free (directory);
fflush (stdout);
if (ferror (stdout))
{
builtin_error (_("write error: %s"), strerror (errno));
sh_wrerror ();
clearerr (stdout);
return (EXECUTION_FAILURE);
}
@ -378,7 +400,7 @@ change_to_directory (newdir, nolinks)
int nolinks;
{
char *t, *tdir;
int err, canon_failed, r;
int err, canon_failed, r, ndlen, dlen;
tdir = (char *)NULL;
@ -396,6 +418,9 @@ change_to_directory (newdir, nolinks)
tdir = nolinks ? sh_physpath (t, 0)
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
ndlen = strlen (newdir);
dlen = strlen (t);
/* Use the canonicalized version of NEWDIR, or, if canonicalization
failed, use the non-canonical form. */
canon_failed = 0;
@ -411,7 +436,7 @@ change_to_directory (newdir, nolinks)
/* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
returns NULL (because it checks the path, it will return NULL if the
resolved path doesn't exist), fail immediately. */
if (posixly_correct && nolinks == 0 && canon_failed)
if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
{
#if defined ENAMETOOLONG
if (errno != ENOENT && errno != ENAMETOOLONG)
@ -419,6 +444,7 @@ change_to_directory (newdir, nolinks)
if (errno != ENOENT)
#endif
errno = ENOTDIR;
free (tdir);
return (0);
}
@ -436,13 +462,17 @@ change_to_directory (newdir, nolinks)
else
set_working_directory (tdir);
free (tdir);
return (1);
}
/* We failed to change to the appropriate directory name. If we tried
what the user passed (nolinks != 0), punt now. */
if (nolinks)
return (0);
{
free (tdir);
return (0);
}
err = errno;