mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-08-20 00:06:19 +00:00
Cache parent directories
Although this might help (or hurt) performance, the main motivation is to make it easier in future commits to prevent tarballs from escaping the extraction directory. * src/common.h: (BADFD): New constant. (struct fdbase): New type. * src/create.c (dump_file0): Use parent->fd instead of caching it into a local, as the latter approach is now awkward. * src/extract.c (extract_link): Don’t save errno unless needed. * src/misc.c (safer_rmdir): New arg F. All callers changed. (maybe_backup_file): Construct full after_backup_name, now that find_backup_file_name no longer does that for us. (chdir_fd): Now static not extern, as other modules now use fdbase. (fdbase_cache): New static var. (fdbase_clear): New function. Call it whenever removing or renaming directories or symlinks to directories. (fdbase_opendir): New static function. (fdbase, fdbase1): New functions. Call them whenever the code formerly passed chdir_fd to a syscall.
This commit is contained in:
+14
-7
@@ -106,7 +106,10 @@ flush_deferred_unlinks (bool force)
|
||||
else
|
||||
fname = p->file_name;
|
||||
|
||||
if (unlinkat (chdir_fd, fname, AT_REMOVEDIR) < 0)
|
||||
struct fdbase f = fdbase (fname);
|
||||
if (f.fd != BADFD && unlinkat (f.fd, f.base, AT_REMOVEDIR) == 0)
|
||||
fdbase_clear ();
|
||||
else
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
@@ -132,7 +135,10 @@ flush_deferred_unlinks (bool force)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unlinkat (chdir_fd, p->file_name, 0) < 0 && errno != ENOENT)
|
||||
struct fdbase f = fdbase (p->file_name);
|
||||
if (f.fd != BADFD && unlinkat (f.fd, f.base, 0) == 0)
|
||||
fdbase_clear ();
|
||||
else if (errno != ENOENT)
|
||||
unlink_error (p->file_name);
|
||||
}
|
||||
dunlink_reclaim (p);
|
||||
@@ -166,11 +172,12 @@ flush_deferred_unlinks (bool force)
|
||||
else
|
||||
fname = p->file_name;
|
||||
|
||||
if (unlinkat (chdir_fd, fname, AT_REMOVEDIR) < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
rmdir_error (fname);
|
||||
}
|
||||
struct fdbase f = fdbase (fname);
|
||||
if (f.fd != BADFD && unlinkat (f.fd, f.base, AT_REMOVEDIR) == 0)
|
||||
fdbase_clear ();
|
||||
else if (errno != ENOENT)
|
||||
rmdir_error (fname);
|
||||
|
||||
dunlink_reclaim (p);
|
||||
p = next;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user