tar/tar-1.24-openat-partial-revert.patch

112 lines
2.9 KiB
Diff

From fd137d96707d776fb2541e3d362825bb650dc786 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 26 Sep 2011 15:36:13 +0200
Subject: [PATCH 2/2] misc: partially revert upstream commit 4bde4f3
---
src/misc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/src/misc.c b/src/misc.c
index b75f2ab..a6e5294 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -21,6 +21,7 @@
#include <rmt.h>
#include "common.h"
#include <quotearg.h>
+#include <save-cwd.h>
#include <xgetcwd.h>
#include <unlinkdir.h>
#include <utimens.h>
@@ -633,6 +634,14 @@ struct wd
/* The directory's name. */
char const *name;
+ /* A negative value if no attempt has been made to save the
+ directory, 0 if it was saved successfully, and a positive errno
+ value if it was not saved successfully. */
+ int err;
+
+ /* The saved version of the directory, if ERR == 0. */
+ struct saved_cwd saved_cwd;
+
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
the working directory. If zero, the directory needs to be opened
to be used. */
@@ -687,6 +696,7 @@ chdir_arg (char const *dir)
if (! wd_count)
{
wd[wd_count].name = ".";
+ wd[wd_count].err = -1;
wd[wd_count].fd = AT_FDCWD;
wd_count++;
}
@@ -704,6 +714,7 @@ chdir_arg (char const *dir)
}
wd[wd_count].name = dir;
+ wd[wd_count].err = -1;
wd[wd_count].fd = 0;
return wd_count++;
}
@@ -728,9 +739,44 @@ chdir_do (int i)
if (chdir_current != i)
{
struct wd *curr = &wd[i];
+ struct wd *prev = &wd[chdir_current];
int fd = curr->fd;
- if (! fd)
+ if (prev->err < 0)
+ {
+ prev->err = 0;
+ if (save_cwd (&prev->saved_cwd) != 0)
+ prev->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 ();
+ if (! prev->saved_cwd.name)
+ prev->err = errno;
+ }
+ else
+ prev->err = errno;
+ }
+ }
+
+ if (0 <= curr->err)
+ {
+ int err = curr->err;
+ if (err == 0 && restore_cwd (&curr->saved_cwd) != 0)
+ err = errno;
+ if (err)
+ FATAL_ERROR ((0, err, _("Cannot restore working directory")));
+ }
+ else if (! fd)
{
if (! IS_ABSOLUTE_FILE_NAME (curr->name))
chdir_do (i - 1);
@@ -741,6 +787,9 @@ chdir_do (int i)
curr->fd = fd;
+ if (chdir (curr->name) != 0)
+ chdir_fatal (curr->name);
+
/* Add I to the cache, tossing out the lowest-ranking entry if the
cache is full. */
if (wdcache_count < CHDIR_CACHE_SIZE)
--
1.7.4.4