If open + fchdir fails, fall back on xgetcwd + chdir.

The old code tested for this at compile-time,
	but SunOS 4.1.4 fchdir can fail at run-time.

	* find/defs.h (fchdir): Define to -1 if not available.
	* find/defs.h (starting_dir, starting_desc):
	Always declare.  starting_dir now points to const.
	* find/find.c (starting_dir, starting_desc): Likewise.
	* find/find.c (starting_dir):
	Now "." if starting_desc is nonnegative, for benefit of diagnostics.
	(main, process_top_path, process_dir):
	If open + fchdir fails, fall back on xgetcwd + chdir.
	* find/pred.c (launch): Likewise.
This commit is contained in:
Kevin Dalley 2000-10-21 21:21:12 +00:00
parent 06f089eee6
commit c5cbe82e70
3 changed files with 36 additions and 43 deletions

View File

@ -403,10 +403,10 @@ extern boolean stay_on_filesystem;
extern boolean stop_at_current_level;
extern boolean have_stat;
extern char *rel_pathname;
#ifndef HAVE_FCHDIR
extern char *starting_dir;
#else
extern char const *starting_dir;
extern int starting_desc;
#if ! defined HAVE_FCHDIR && ! defined fchdir
# define fchdir(fd) (-1)
#endif
extern int exit_status;
extern int path_length;

View File

@ -107,15 +107,14 @@ boolean stay_on_filesystem;
Can be set by -prune, -maxdepth, and -xdev/-mount. */
boolean stop_at_current_level;
#ifndef HAVE_FCHDIR
/* The full path of the initial working directory. */
char *starting_dir;
#else
/* The full path of the initial working directory, or "." if
STARTING_DESC is nonnegative. */
char const *starting_dir = ".";
/* A file descriptor open to the initial working directory.
Doing it this way allows us to work when the i.w.d. has
unreadable parents. */
int starting_desc;
#endif
/* If true, we have called stat on the current path. */
boolean have_stat;
@ -262,15 +261,18 @@ main (int argc, char **argv)
print_tree (eval_tree, 0);
#endif /* DEBUG */
#ifndef HAVE_FCHDIR
starting_dir = xgetcwd ();
if (starting_dir == NULL)
error (1, errno, _("cannot get current directory"));
#else
starting_desc = open (".", O_RDONLY);
if (0 <= starting_desc && fchdir (starting_desc) != 0)
{
close (starting_desc);
starting_desc = -1;
}
if (starting_desc < 0)
error (1, errno, _("cannot open current directory"));
#endif
{
starting_dir = xgetcwd ();
if (! starting_dir)
error (1, errno, _("cannot get current directory"));
}
/* If no paths are given, default to ".". */
for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
@ -304,13 +306,10 @@ process_top_path (char *pathname)
return;
}
process_path (pathname, ".", false, ".");
#ifndef HAVE_FCHDIR
if (chdir (starting_dir) < 0)
if (starting_desc < 0
? chdir (starting_dir) != 0
: fchdir (starting_desc) != 0)
error (1, errno, "%s", starting_dir);
#else
if (fchdir (starting_desc))
error (1, errno, _("cannot return to starting directory"));
#endif
}
else
process_path (pathname, pathname, false, ".");
@ -521,23 +520,23 @@ process_dir (char *pathname, char *name, int pathlen, struct stat *statp, char *
if (strcmp (name, "."))
{
/* We could go back and do the next command-line arg
instead, maybe using longjmp. */
char const *dir;
if (!dereference)
{
if (chdir ("..") < 0)
/* We could go back and do the next command-line arg instead,
maybe using longjmp. */
error (1, errno, "%s", parent);
}
dir = "..";
else
{
#ifndef HAVE_FCHDIR
if (chdir (starting_dir) || chdir (parent))
error (1, errno, "%s", parent);
#else
if (fchdir (starting_desc) || chdir (parent))
error (1, errno, "%s", parent);
#endif
if (starting_desc < 0
? chdir (starting_dir) != 0
: fchdir (starting_desc) != 0)
error (1, errno, "%s", starting_dir);
dir = parent;
}
if (chdir (dir) != 0)
error (1, errno, "%s", parent);
}
if (cur_path)

View File

@ -1263,19 +1263,13 @@ launch (struct predicate *pred_ptr)
if (child_pid == 0)
{
/* We be the child. */
#ifndef HAVE_FCHDIR
if (chdir (starting_dir) < 0)
if (starting_desc < 0
? chdir (starting_dir) != 0
: fchdir (starting_desc) != 0)
{
error (0, errno, "%s", starting_dir);
_exit (1);
}
#else
if (fchdir (starting_desc) < 0)
{
error (0, errno, _("cannot return to starting directory"));
_exit (1);
}
#endif
execvp (execp->vec[0], execp->vec);
error (0, errno, "%s", execp->vec[0]);
_exit (1);