]>
Dogcows Code - chaz/tar/blob - src/unlink.c
225d49b1bf2654ae8b08e769e41cc85d9ee09256
3 Copyright 2009, 2013-2014 Free Software Foundation, Inc.
5 This file is part of GNU tar.
7 GNU tar is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 GNU tar is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 struct deferred_unlink
26 struct deferred_unlink
*next
; /* Next unlink in the queue */
27 int dir_idx
; /* Directory index in wd */
28 char *file_name
; /* Name of the file to unlink, relative
30 bool is_dir
; /* True if file_name is a directory */
31 off_t records_written
; /* Number of records written when this
32 entry got added to the queue */
35 /* The unlink queue */
36 static struct deferred_unlink
*dunlink_head
, *dunlink_tail
;
38 /* Number of entries in the queue */
39 static size_t dunlink_count
;
41 /* List of entries available for allocation */
42 static struct deferred_unlink
*dunlink_avail
;
44 /* Delay (number of records written) between adding entry to the
45 list and its actual removal. */
46 static size_t deferred_unlink_delay
= 0;
48 static struct deferred_unlink
*
51 struct deferred_unlink
*p
;
55 dunlink_avail
= p
->next
;
59 p
= xmalloc (sizeof (*p
));
64 dunlink_reclaim (struct deferred_unlink
*p
)
67 p
->next
= dunlink_avail
;
72 flush_deferred_unlinks (bool force
)
74 struct deferred_unlink
*p
, *prev
= NULL
;
75 int saved_chdir
= chdir_current
;
77 for (p
= dunlink_head
; p
; )
79 struct deferred_unlink
*next
= p
->next
;
82 || records_written
> p
->records_written
+ deferred_unlink_delay
)
84 chdir_do (p
->dir_idx
);
89 if (p
->file_name
[0] == 0 ||
90 strcmp (p
->file_name
, ".") == 0)
92 fname
= tar_dirname ();
93 chdir_do (p
->dir_idx
- 1);
98 if (unlinkat (chdir_fd
, fname
, AT_REMOVEDIR
) != 0)
103 /* nothing to worry about */
108 /* Keep the record in list, in the hope we'll
109 be able to remove it later */
122 if (unlinkat (chdir_fd
, p
->file_name
, 0) != 0 && errno
!= ENOENT
)
123 unlink_error (p
->file_name
);
141 chdir_do (saved_chdir
);
145 finish_deferred_unlinks (void)
147 flush_deferred_unlinks (true);
148 while (dunlink_avail
)
150 struct deferred_unlink
*next
= dunlink_avail
->next
;
151 free (dunlink_avail
);
152 dunlink_avail
= next
;
157 queue_deferred_unlink (const char *name
, bool is_dir
)
159 struct deferred_unlink
*p
;
162 && records_written
> dunlink_head
->records_written
+ deferred_unlink_delay
)
163 flush_deferred_unlinks (false);
165 p
= dunlink_alloc ();
167 p
->dir_idx
= chdir_current
;
168 p
->file_name
= xstrdup (name
);
169 normalize_filename_x (p
->file_name
);
171 p
->records_written
= records_written
;
174 dunlink_tail
->next
= p
;
This page took 0.038547 seconds and 3 git commands to generate.