summaryrefslogtreecommitdiff
path: root/builtins/cd.def~
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/cd.def~')
-rw-r--r--builtins/cd.def~521
1 files changed, 0 insertions, 521 deletions
diff --git a/builtins/cd.def~ b/builtins/cd.def~
deleted file mode 100644
index 1e2f0d21..00000000
--- a/builtins/cd.def~
+++ /dev/null
@@ -1,521 +0,0 @@
-This file is cd.def, from which is created cd.c. It implements the
-builtins "cd" and "pwd" in Bash.
-
-Copyright (C) 1987-2005 Free Software Foundation, Inc.
-
-This file is part of GNU Bash, the Bourne Again SHell.
-
-Bash is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-Bash is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License along
-with Bash; see the file COPYING. If not, write to the Free Software
-Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
-
-$PRODUCES cd.c
-#include <config.h>
-
-#if defined (HAVE_UNISTD_H)
-# ifdef _MINIX
-# include <sys/types.h>
-# endif
-# include <unistd.h>
-#endif
-
-#include "../bashtypes.h"
-#include "posixdir.h"
-#include "posixstat.h"
-#ifndef _MINIX
-#include <sys/param.h>
-#endif
-
-#include <stdio.h>
-
-#include "../bashansi.h"
-#include "../bashintl.h"
-
-#include <errno.h>
-#include <tilde/tilde.h>
-
-#include "../shell.h"
-#include "../flags.h"
-#include "maxpath.h"
-#include "common.h"
-#include "bashgetopt.h"
-
-#if !defined (errno)
-extern int errno;
-#endif /* !errno */
-
-extern int posixly_correct;
-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 *));
-
-/* Change this to 1 to get cd spelling correction by default. */
-int cdspelling = 0;
-
-int cdable_vars;
-
-$BUILTIN cd
-$FUNCTION cd_builtin
-$SHORT_DOC cd [-L|-P] [dir]
-Change the current directory to DIR. The variable $HOME is the
-default DIR. The variable CDPATH defines the search path for
-the directory containing DIR. Alternative directory names in CDPATH
-are separated by a colon (:). A null directory name is the same as
-the current directory, i.e. `.'. If DIR begins with a slash (/),
-then CDPATH is not used. If the directory is not found, and the
-shell option `cdable_vars' is set, then try the word as a variable
-name. If that variable has a value, then cd to the value of that
-variable. The -P option says to use the physical directory structure
-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;
-{
- char *dirname, *pwdvar;
- int old_anm;
- SHELL_VAR *tvar;
-
-#define tcwd the_current_working_directory
- dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
- : get_working_directory ("cd");
-#undef tcwd
-
- old_anm = array_needs_making;
- pwdvar = get_string_value ("PWD");
-
- 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;
- }
-
- setpwd (dirname);
-
- if (dirname && dirname != the_current_working_directory)
- free (dirname);
-
- return (EXECUTION_SUCCESS);
-}
-
-/* Call get_working_directory to reset the value of
- the_current_working_directory () */
-static char *
-resetpwd (caller)
- char *caller;
-{
- char *tdir;
-
- FREE (the_current_working_directory);
- the_current_working_directory = (char *)NULL;
- tdir = get_working_directory (caller);
- return (tdir);
-}
-
-#define LCD_DOVARS 0x001
-#define LCD_DOSPELL 0x002
-#define LCD_PRINTPATH 0x004
-#define LCD_FREEDIRNAME 0x010
-
-/* This builtin is ultimately the way that all user-visible commands should
- change the current working directory. It is called by cd_to_string (),
- so the programming interface is simple, and it handles errors and
- restrictions properly. */
-int
-cd_builtin (list)
- WORD_LIST *list;
-{
- char *dirname, *cdpath, *path, *temp;
- int path_index, no_symlinks, opt, lflag;
-
-#if defined (RESTRICTED_SHELL)
- if (restricted)
- {
- sh_restricted ((char *)NULL);
- return (EXECUTION_FAILURE);
- }
-#endif /* RESTRICTED_SHELL */
-
- no_symlinks = no_symbolic_links;
- reset_internal_getopt ();
- while ((opt = internal_getopt (list, "LP")) != -1)
- {
- switch (opt)
- {
- case 'P':
- no_symlinks = 1;
- break;
- case 'L':
- no_symlinks = 0;
- break;
- default:
- builtin_usage ();
- return (EXECUTION_FAILURE);
- }
- }
- list = loptend;
-
- lflag = (cdable_vars ? LCD_DOVARS : 0) |
- ((interactive && cdspelling) ? LCD_DOSPELL : 0);
-
- if (list == 0)
- {
- /* `cd' without arguments is equivalent to `cd $HOME' */
- dirname = get_string_value ("HOME");
-
- if (dirname == 0)
- {
- builtin_error (_("HOME not set"));
- return (EXECUTION_FAILURE);
- }
- lflag = 0;
- }
- else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
- {
- /* This is `cd -', equivalent to `cd $OLDPWD' */
- dirname = get_string_value ("OLDPWD");
-
- if (dirname == 0)
- {
- builtin_error (_("OLDPWD not set"));
- return (EXECUTION_FAILURE);
- }
-#if 0
- lflag = interactive ? LCD_PRINTPATH : 0;
-#else
- lflag = LCD_PRINTPATH; /* According to SUSv3 */
-#endif
- }
- else if (absolute_pathname (list->word->word))
- dirname = list->word->word;
- else if (cdpath = get_string_value ("CDPATH"))
- {
- dirname = list->word->word;
-
- /* Find directory in $CDPATH. */
- path_index = 0;
- while (path = extract_colon_unit (cdpath, &path_index))
- {
- /* OPT is 1 if the path element is non-empty */
- opt = path[0] != '\0';
- temp = sh_makepath (path, dirname, MP_DOTILDE);
- free (path);
-
- if (change_to_directory (temp, no_symlinks))
- {
- /* POSIX.2 says that if a nonempty directory from CDPATH
- is used to find the directory to change to, the new
- directory name is echoed to stdout, whether or not
- the shell is interactive. */
- if (opt && (path = no_symlinks ? temp : the_current_working_directory))
- 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);
- }
-
- /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
- try the current directory, so we just punt now with an error
- message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
- is so we don't mistakenly treat a CDPATH value of "" as not
- specifying the current directory. */
- if (posixly_correct && cdpath[0])
- {
- builtin_error ("%s: %s", dirname, strerror (ENOENT));
- return (EXECUTION_FAILURE);
- }
- }
- else
- dirname = list->word->word;
-
- /* When we get here, DIRNAME is the directory to change to. If we
- chdir successfully, just return. */
- if (change_to_directory (dirname, no_symlinks))
- {
- if (lflag & LCD_PRINTPATH)
- printf ("%s\n", dirname);
- return (bindpwd (no_symlinks));
- }
-
- /* If the user requests it, then perhaps this is the name of
- a shell variable, whose value contains the directory to
- change to. */
- if (lflag & LCD_DOVARS)
- {
- temp = get_string_value (dirname);
- if (temp && change_to_directory (temp, no_symlinks))
- {
- printf ("%s\n", temp);
- return (bindpwd (no_symlinks));
- }
- }
-
- /* If the user requests it, try to find a directory name similar in
- spelling to the one requested, in case the user made a simple
- typo. This is similar to the UNIX 8th and 9th Edition shells. */
- if (lflag & LCD_DOSPELL)
- {
- temp = cdspell (dirname);
- if (temp && change_to_directory (temp, no_symlinks))
- {
- printf ("%s\n", temp);
- return (bindpwd (no_symlinks));
- }
- else
- FREE (temp);
- }
-
- builtin_error ("%s: %s", dirname, strerror (errno));
- return (EXECUTION_FAILURE);
-}
-
-$BUILTIN pwd
-$FUNCTION pwd_builtin
-$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.
-$END
-
-/* Non-zero means that pwd always prints the physical directory, without
- symbolic links. */
-static int verbatim_pwd;
-
-/* Print the name of the current working directory. */
-int
-pwd_builtin (list)
- WORD_LIST *list;
-{
- char *directory;
- 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 = pflag = 1;
- break;
- case 'L':
- verbatim_pwd = 0;
- break;
- default:
- builtin_usage ();
- return (EXECUTION_FAILURE);
- }
- }
- list = loptend;
-
-#define tcwd the_current_working_directory
-
- directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
- : get_working_directory ("pwd");
-
- /* Try again using getcwd() if canonicalization fails (for instance, if
- the file system has changed state underneath bash). */
- if ((tcwd && directory == 0) ||
- (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
- directory = resetpwd ("pwd");
-
-#undef tcwd
-
- 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))
- {
- sh_wrerror ();
- clearerr (stdout);
- return (EXECUTION_FAILURE);
- }
-
- return (EXECUTION_SUCCESS);
- }
- else
- return (EXECUTION_FAILURE);
-}
-
-/* Do the work of changing to the directory NEWDIR. Handle symbolic
- link following, etc. This function *must* return with
- the_current_working_directory either set to NULL (in which case
- getcwd() will eventually be called), or set to a string corresponding
- to the working directory. Return 1 on success, 0 on failure. */
-
-static int
-change_to_directory (newdir, nolinks)
- char *newdir;
- int nolinks;
-{
- char *t, *tdir;
- int err, canon_failed, r, ndlen, dlen;
-
- tdir = (char *)NULL;
-
- if (the_current_working_directory == 0)
- {
- t = get_working_directory ("chdir");
- FREE (t);
- }
-
- t = make_absolute (newdir, the_current_working_directory);
-
- /* TDIR is either the canonicalized absolute pathname of NEWDIR
- (nolinks == 0) or the absolute physical pathname of NEWDIR
- (nolinks != 0). */
- 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;
- if (tdir && *tdir)
- free (t);
- else
- {
- FREE (tdir);
- tdir = t;
- canon_failed = 1;
- }
-
- /* 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 && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
- {
-#if defined ENAMETOOLONG
- if (errno != ENOENT && errno != ENAMETOOLONG)
-#else
- if (errno != ENOENT)
-#endif
- errno = ENOTDIR;
- return (0);
- }
-
- /* If the chdir succeeds, update the_current_working_directory. */
- if (chdir (nolinks ? newdir : tdir) == 0)
- {
- /* If canonicalization failed, but the chdir succeeded, reset the
- shell's idea of the_current_working_directory. */
- if (canon_failed)
- {
- t = resetpwd ("cd");
- if (t == 0)
- set_working_directory (tdir);
- }
- 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);
-
- err = errno;
-
- /* We're not in physical mode (nolinks == 0), but we failed to change to
- the canonicalized directory name (TDIR). Try what the user passed
- verbatim. If we succeed, reinitialize the_current_working_directory. */
- if (chdir (newdir) == 0)
- {
- t = resetpwd ("cd");
- if (t == 0)
- set_working_directory (tdir);
- else
- free (t);
-
- r = 1;
- }
- else
- {
- errno = err;
- r = 0;
- }
-
- free (tdir);
- return r;
-}
-
-/* Code for cd spelling correction. Original patch submitted by
- Neil Russel (caret@c-side.com). */
-
-static char *
-cdspell (dirname)
- char *dirname;
-{
- int n;
- char *guess;
-
- n = (strlen (dirname) * 3 + 1) / 2 + 1;
- guess = (char *)xmalloc (n);
-
- switch (spname (dirname, guess))
- {
- case -1:
- default:
- free (guess);
- return (char *)NULL;
- case 0:
- case 1:
- return guess;
- }
-}