/* 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
#include "common.h"
#include <quotearg.h>
#include <save-cwd.h>
+#include <xgetcwd.h>
#include <unlinkdir.h>
#include <utimens.h>
so, we do not have to backup block or character devices, nor remote
entities. */
bool
-maybe_backup_file (const char *file_name, int this_is_the_archive)
+maybe_backup_file (const char *file_name, bool this_is_the_archive)
{
struct stat file_stat;
{
if (wds == wd_alloc)
{
- wd_alloc = 2 * (wd_alloc + 1);
- wd = xrealloc (wd, sizeof *wd * wd_alloc);
+ if (wd_alloc == 0)
+ {
+ wd_alloc = 2;
+ wd = xmalloc (sizeof *wd * wd_alloc);
+ }
+ else
+ wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
+
if (! wds)
{
wd[wds].name = ".";
if (! prev->saved)
{
+ int err = 0;
prev->saved = 1;
if (save_cwd (&prev->saved_cwd) != 0)
- FATAL_ERROR ((0, 0, _("Cannot save working directory")));
+ err = errno;
+ else if (0 <= prev->saved_cwd.desc)
+ {
+ /* 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;
+ }
+
+ if (err)
+ FATAL_ERROR ((0, err, _("Cannot save working directory")));
}
if (curr->saved)