Imported from ../bash-3.1.tar.gz.
This commit is contained in:
parent
eb87367179
commit
95732b497d
267 changed files with 24541 additions and 18843 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue