X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fmisc.c;h=ba7ed051cd926c0c6be77e599ce75f44eef62b13;hb=250db35f17d7700f4d209fd086b7dbc5b7ebe88f;hp=328591ca4b77beb26b216a86499f82687e353282;hpb=9869d0ae1728827b68c71b33bc2a5cc2261bd35c;p=chaz%2Ftar diff --git a/src/misc.c b/src/misc.c index 328591c..ba7ed05 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,7 +1,7 @@ /* Miscellaneous functions, not really specific to GNU tar. Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -18,8 +18,6 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -#include -#include #include #include "common.h" #include @@ -577,41 +575,13 @@ chdir_arg (char const *dir) return wds++; } -/* Return maximum number of open files */ -int -get_max_open_files () -{ -#if defined _SC_OPEN_MAX - return sysconf (_SC_OPEN_MAX); -#elif defined RLIMIT_NOFILE - struct rlimit rlim; - - if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) - return rlim.rlim_max; -#elif defined HAVE_GETDTABLESIZE - return getdtablesize (); -#endif - return -1; -} - -/* Close all descriptors, except the first three */ -void -closeopen () -{ - int i; - - for (i = get_max_open_files () - 1; i > 2; i--) - close (i); -} - /* Change to directory I. If I is 0, change to the initial working directory; otherwise, I must be a value returned by chdir_arg. */ void chdir_do (int i) { static int previous; - static int saved_count; - + if (previous != i) { struct wd *prev = &wd[previous]; @@ -619,17 +589,30 @@ chdir_do (int i) if (! prev->saved) { + int err = 0; prev->saved = 1; - saved_count++; - /* Make sure we still have at least one descriptor available */ - if (saved_count >= get_max_open_files () - 4) + if (save_cwd (&prev->saved_cwd) != 0) + err = errno; + else if (0 <= prev->saved_cwd.desc) { - /* Force restore_cwd to use chdir_long */ - prev->saved_cwd.desc = -1; - prev->saved_cwd.name = xgetcwd (); + /* Make sure we still have at least one descriptor available. */ + int fd1 = prev->saved_cwd.desc; + int fd2 = dup (fd1); + if (0 <= fd2) + close (fd2); + else if (errno == EMFILE) + { + /* Force restore_cwd to use chdir_long. */ + close (fd1); + prev->saved_cwd.desc = -1; + prev->saved_cwd.name = xgetcwd (); + } + else + err = errno; } - else if (save_cwd (&prev->saved_cwd) != 0) - FATAL_ERROR ((0, 0, _("Cannot save working directory"))); + + if (err) + FATAL_ERROR ((0, err, _("Cannot save working directory"))); } if (curr->saved)