]>
Dogcows Code - chaz/tar/blob - src/unlink.c
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
);
90 && (p
->file_name
[0] == 0
91 || strcmp (p
->file_name
, ".") == 0))
93 fname
= tar_dirname ();
94 chdir_do (p
->dir_idx
- 1);
99 if (unlinkat (chdir_fd
, fname
, AT_REMOVEDIR
) != 0)
104 /* nothing to worry about */
109 /* Keep the record in list, in the hope we'll
110 be able to remove it later */
123 if (unlinkat (chdir_fd
, p
->file_name
, 0) != 0 && errno
!= ENOENT
)
124 unlink_error (p
->file_name
);
142 chdir_do (saved_chdir
);
146 finish_deferred_unlinks (void)
148 flush_deferred_unlinks (true);
149 while (dunlink_avail
)
151 struct deferred_unlink
*next
= dunlink_avail
->next
;
152 free (dunlink_avail
);
153 dunlink_avail
= next
;
158 queue_deferred_unlink (const char *name
, bool is_dir
)
160 struct deferred_unlink
*p
;
163 && records_written
> dunlink_head
->records_written
+ deferred_unlink_delay
)
164 flush_deferred_unlinks (false);
166 p
= dunlink_alloc ();
168 p
->dir_idx
= chdir_current
;
169 p
->file_name
= xstrdup (name
);
170 normalize_filename_x (p
->file_name
);
172 p
->records_written
= records_written
;
175 dunlink_tail
->next
= p
;
This page took 0.040351 seconds and 5 git commands to generate.