/* 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, 2007 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
- Free Software Foundation; either version 2, or (at your option) any later
+ Free Software Foundation; either version 3, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <system.h>
-#include <sys/time.h>
-#include <sys/resource.h>
#include <rmt.h>
#include "common.h"
#include <quotearg.h>
}
#endif
- return futimens (fd, file, timespec);
+ return gl_futimens (fd, file, timespec);
}
/* A description of a working directory. */
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];
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)