]> Dogcows Code - chaz/tar/blob - src/misc.c
tar: don't assume O_NONBLOCK is benign on regular files
[chaz/tar] / src / misc.c
1 /* Miscellaneous functions, not really specific to GNU tar.
2
3 Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
4 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 #include <system.h>
21 #include <rmt.h>
22 #include "common.h"
23 #include <quotearg.h>
24 #include <xgetcwd.h>
25 #include <unlinkdir.h>
26 #include <utimens.h>
27
28 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
29 # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
30 #endif
31
32 \f
33 /* Handling strings. */
34
35 /* Assign STRING to a copy of VALUE if not zero, or to zero. If
36 STRING was nonzero, it is freed first. */
37 void
38 assign_string (char **string, const char *value)
39 {
40 free (*string);
41 *string = value ? xstrdup (value) : 0;
42 }
43
44 #if 0
45 /* This function is currently unused; perhaps it should be removed? */
46
47 /* Allocate a copy of the string quoted as in C, and returns that. If
48 the string does not have to be quoted, it returns a null pointer.
49 The allocated copy should normally be freed with free() after the
50 caller is done with it.
51
52 This is used in one context only: generating the directory file in
53 incremental dumps. The quoted string is not intended for human
54 consumption; it is intended only for unquote_string. The quoting
55 is locale-independent, so that users needn't worry about locale
56 when reading directory files. This means that we can't use
57 quotearg, as quotearg is locale-dependent and is meant for human
58 consumption. */
59 static char *
60 quote_copy_string (const char *string)
61 {
62 const char *source = string;
63 char *destination = 0;
64 char *buffer = 0;
65 int copying = 0;
66
67 while (*source)
68 {
69 int character = *source++;
70
71 switch (character)
72 {
73 case '\n': case '\\':
74 if (!copying)
75 {
76 size_t length = (source - string) - 1;
77
78 copying = 1;
79 buffer = xmalloc (length + 2 + 2 * strlen (source) + 1);
80 memcpy (buffer, string, length);
81 destination = buffer + length;
82 }
83 *destination++ = '\\';
84 *destination++ = character == '\\' ? '\\' : 'n';
85 break;
86
87 default:
88 if (copying)
89 *destination++ = character;
90 break;
91 }
92 }
93 if (copying)
94 {
95 *destination = '\0';
96 return buffer;
97 }
98 return 0;
99 }
100 #endif
101
102 /* Takes a quoted C string (like those produced by quote_copy_string)
103 and turns it back into the un-quoted original. This is done in
104 place. Returns 0 only if the string was not properly quoted, but
105 completes the unquoting anyway.
106
107 This is used for reading the saved directory file in incremental
108 dumps. It is used for decoding old `N' records (demangling names).
109 But also, it is used for decoding file arguments, would they come
110 from the shell or a -T file, and for decoding the --exclude
111 argument. */
112 int
113 unquote_string (char *string)
114 {
115 int result = 1;
116 char *source = string;
117 char *destination = string;
118
119 /* Escape sequences other than \\ and \n are no longer generated by
120 quote_copy_string, but accept them for backwards compatibility,
121 and also because unquote_string is used for purposes other than
122 parsing the output of quote_copy_string. */
123
124 while (*source)
125 if (*source == '\\')
126 switch (*++source)
127 {
128 case '\\':
129 *destination++ = '\\';
130 source++;
131 break;
132
133 case 'a':
134 *destination++ = '\a';
135 source++;
136 break;
137
138 case 'b':
139 *destination++ = '\b';
140 source++;
141 break;
142
143 case 'f':
144 *destination++ = '\f';
145 source++;
146 break;
147
148 case 'n':
149 *destination++ = '\n';
150 source++;
151 break;
152
153 case 'r':
154 *destination++ = '\r';
155 source++;
156 break;
157
158 case 't':
159 *destination++ = '\t';
160 source++;
161 break;
162
163 case 'v':
164 *destination++ = '\v';
165 source++;
166 break;
167
168 case '?':
169 *destination++ = 0177;
170 source++;
171 break;
172
173 case '0':
174 case '1':
175 case '2':
176 case '3':
177 case '4':
178 case '5':
179 case '6':
180 case '7':
181 {
182 int value = *source++ - '0';
183
184 if (*source < '0' || *source > '7')
185 {
186 *destination++ = value;
187 break;
188 }
189 value = value * 8 + *source++ - '0';
190 if (*source < '0' || *source > '7')
191 {
192 *destination++ = value;
193 break;
194 }
195 value = value * 8 + *source++ - '0';
196 *destination++ = value;
197 break;
198 }
199
200 default:
201 result = 0;
202 *destination++ = '\\';
203 if (*source)
204 *destination++ = *source++;
205 break;
206 }
207 else if (source != destination)
208 *destination++ = *source++;
209 else
210 source++, destination++;
211
212 if (source != destination)
213 *destination = '\0';
214 return result;
215 }
216
217 /* Zap trailing slashes. */
218 char *
219 zap_slashes (char *name)
220 {
221 char *q;
222
223 if (!name || *name == 0)
224 return name;
225 q = name + strlen (name) - 1;
226 while (q > name && ISSLASH (*q))
227 *q-- = '\0';
228 return name;
229 }
230
231 /* Normalize FILE_NAME by removing redundant slashes and "."
232 components, including redundant trailing slashes. Leave ".."
233 alone, as it may be significant in the presence of symlinks and on
234 platforms where "/.." != "/". Destructive version: modifies its
235 argument. */
236 static void
237 normalize_filename_x (char *file_name)
238 {
239 char *name = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
240 char *p;
241 char const *q;
242 char c;
243
244 /* Don't squeeze leading "//" to "/", on hosts where they're distinct. */
245 name += (DOUBLE_SLASH_IS_DISTINCT_ROOT
246 && ISSLASH (*name) && ISSLASH (name[1]) && ! ISSLASH (name[2]));
247
248 /* Omit redundant leading "." components. */
249 for (q = p = name; (*p = *q) == '.' && ISSLASH (q[1]); p += !*q)
250 for (q += 2; ISSLASH (*q); q++)
251 continue;
252
253 /* Copy components from Q to P, omitting redundant slashes and
254 internal "." components. */
255 while ((*p++ = c = *q++) != '\0')
256 if (ISSLASH (c))
257 while (ISSLASH (q[*q == '.']))
258 q += (*q == '.') + 1;
259
260 /* Omit redundant trailing "." component and slash. */
261 if (2 < p - name)
262 {
263 p -= p[-2] == '.' && ISSLASH (p[-3]);
264 p -= 2 < p - name && ISSLASH (p[-2]);
265 p[-1] = '\0';
266 }
267 }
268
269 /* Normalize NAME by removing redundant slashes and "." components,
270 including redundant trailing slashes. Return a normalized
271 newly-allocated copy. */
272
273 char *
274 normalize_filename (const char *name)
275 {
276 char *copy = NULL;
277
278 if (IS_RELATIVE_FILE_NAME (name))
279 {
280 /* Set COPY to the absolute file name if possible.
281
282 FIXME: There should be no need to get the absolute file name.
283 getcwd is slow, it might fail, and it does not necessarily
284 return a canonical name even when it succeeds. Perhaps we
285 can use dev+ino pairs instead of names? */
286 copy = xgetcwd ();
287 if (copy)
288 {
289 size_t copylen = strlen (copy);
290 bool need_separator = ! (DOUBLE_SLASH_IS_DISTINCT_ROOT
291 && copylen == 2 && ISSLASH (copy[1]));
292 copy = xrealloc (copy, copylen + need_separator + strlen (name) + 1);
293 copy[copylen] = DIRECTORY_SEPARATOR;
294 strcpy (copy + copylen + need_separator, name);
295 }
296 else
297 WARN ((0, errno, _("Cannot get working directory")));
298 }
299
300 if (! copy)
301 copy = xstrdup (name);
302 normalize_filename_x (copy);
303 return copy;
304 }
305
306 \f
307 void
308 replace_prefix (char **pname, const char *samp, size_t slen,
309 const char *repl, size_t rlen)
310 {
311 char *name = *pname;
312 size_t nlen = strlen (name);
313 if (nlen > slen && memcmp (name, samp, slen) == 0 && ISSLASH (name[slen]))
314 {
315 if (rlen > slen)
316 {
317 name = xrealloc (name, nlen - slen + rlen + 1);
318 *pname = name;
319 }
320 memmove (name + rlen, name + slen, nlen - slen + 1);
321 memcpy (name, repl, rlen);
322 }
323 }
324
325 \f
326 /* Handling numbers. */
327
328 /* Output fraction and trailing digits appropriate for a nanoseconds
329 count equal to NS, but don't output unnecessary '.' or trailing
330 zeros. */
331
332 void
333 code_ns_fraction (int ns, char *p)
334 {
335 if (ns == 0)
336 *p = '\0';
337 else
338 {
339 int i = 9;
340 *p++ = '.';
341
342 while (ns % 10 == 0)
343 {
344 ns /= 10;
345 i--;
346 }
347
348 p[i] = '\0';
349
350 for (;;)
351 {
352 p[--i] = '0' + ns % 10;
353 if (i == 0)
354 break;
355 ns /= 10;
356 }
357 }
358 }
359
360 char const *
361 code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
362 {
363 time_t s = t.tv_sec;
364 int ns = t.tv_nsec;
365 char *np;
366 bool negative = s < 0;
367
368 /* ignore invalid values of ns */
369 if (BILLION <= ns || ns < 0)
370 ns = 0;
371
372 if (negative && ns != 0)
373 {
374 s++;
375 ns = BILLION - ns;
376 }
377
378 np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1);
379 if (negative)
380 *--np = '-';
381 code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND);
382 return np;
383 }
384 \f
385 /* File handling. */
386
387 /* Saved names in case backup needs to be undone. */
388 static char *before_backup_name;
389 static char *after_backup_name;
390
391 /* Return 1 if FILE_NAME is obviously "." or "/". */
392 bool
393 must_be_dot_or_slash (char const *file_name)
394 {
395 file_name += FILE_SYSTEM_PREFIX_LEN (file_name);
396
397 if (ISSLASH (file_name[0]))
398 {
399 for (;;)
400 if (ISSLASH (file_name[1]))
401 file_name++;
402 else if (file_name[1] == '.'
403 && ISSLASH (file_name[2 + (file_name[2] == '.')]))
404 file_name += 2 + (file_name[2] == '.');
405 else
406 return ! file_name[1];
407 }
408 else
409 {
410 while (file_name[0] == '.' && ISSLASH (file_name[1]))
411 {
412 file_name += 2;
413 while (ISSLASH (*file_name))
414 file_name++;
415 }
416
417 return ! file_name[0] || (file_name[0] == '.' && ! file_name[1]);
418 }
419 }
420
421 /* Some implementations of rmdir let you remove '.' or '/'.
422 Report an error with errno set to zero for obvious cases of this;
423 otherwise call rmdir. */
424 static int
425 safer_rmdir (const char *file_name)
426 {
427 if (must_be_dot_or_slash (file_name))
428 {
429 errno = 0;
430 return -1;
431 }
432
433 return unlinkat (chdir_fd, file_name, AT_REMOVEDIR);
434 }
435
436 /* Remove FILE_NAME, returning 1 on success. If FILE_NAME is a directory,
437 then if OPTION is RECURSIVE_REMOVE_OPTION is set remove FILE_NAME
438 recursively; otherwise, remove it only if it is empty. If FILE_NAME is
439 a directory that cannot be removed (e.g., because it is nonempty)
440 and if OPTION is WANT_DIRECTORY_REMOVE_OPTION, then return -1.
441 Return 0 on error, with errno set; if FILE_NAME is obviously the working
442 directory return zero with errno set to zero. */
443 int
444 remove_any_file (const char *file_name, enum remove_option option)
445 {
446 /* Try unlink first if we cannot unlink directories, as this saves
447 us a system call in the common case where we're removing a
448 non-directory. */
449 bool try_unlink_first = cannot_unlink_dir ();
450
451 if (try_unlink_first)
452 {
453 if (unlinkat (chdir_fd, file_name, 0) == 0)
454 return 1;
455
456 /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a
457 directory without appropriate privileges, but many Linux
458 kernels return the more-sensible EISDIR. */
459 if (errno != EPERM && errno != EISDIR)
460 return 0;
461 }
462
463 if (safer_rmdir (file_name) == 0)
464 return 1;
465
466 switch (errno)
467 {
468 case ENOTDIR:
469 return !try_unlink_first && unlinkat (chdir_fd, file_name, 0) == 0;
470
471 case 0:
472 case EEXIST:
473 #if defined ENOTEMPTY && ENOTEMPTY != EEXIST
474 case ENOTEMPTY:
475 #endif
476 switch (option)
477 {
478 case ORDINARY_REMOVE_OPTION:
479 break;
480
481 case WANT_DIRECTORY_REMOVE_OPTION:
482 return -1;
483
484 case RECURSIVE_REMOVE_OPTION:
485 {
486 char *directory = savedir (file_name);
487 char const *entry;
488 size_t entrylen;
489
490 if (! directory)
491 return 0;
492
493 for (entry = directory;
494 (entrylen = strlen (entry)) != 0;
495 entry += entrylen + 1)
496 {
497 char *file_name_buffer = new_name (file_name, entry);
498 int r = remove_any_file (file_name_buffer,
499 RECURSIVE_REMOVE_OPTION);
500 int e = errno;
501 free (file_name_buffer);
502
503 if (! r)
504 {
505 free (directory);
506 errno = e;
507 return 0;
508 }
509 }
510
511 free (directory);
512 return safer_rmdir (file_name) == 0;
513 }
514 }
515 break;
516 }
517
518 return 0;
519 }
520
521 /* Check if FILE_NAME already exists and make a backup of it right now.
522 Return success (nonzero) only if the backup is either unneeded, or
523 successful. For now, directories are considered to never need
524 backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and
525 so, we do not have to backup block or character devices, nor remote
526 entities. */
527 bool
528 maybe_backup_file (const char *file_name, bool this_is_the_archive)
529 {
530 struct stat file_stat;
531
532 assign_string (&before_backup_name, file_name);
533
534 /* A run situation may exist between Emacs or other GNU programs trying to
535 make a backup for the same file simultaneously. If theoretically
536 possible, real problems are unlikely. Doing any better would require a
537 convention, GNU-wide, for all programs doing backups. */
538
539 assign_string (&after_backup_name, 0);
540
541 /* Check if we really need to backup the file. */
542
543 if (this_is_the_archive && _remdev (file_name))
544 return true;
545
546 if (deref_stat (file_name, &file_stat) != 0)
547 {
548 if (errno == ENOENT)
549 return true;
550
551 stat_error (file_name);
552 return false;
553 }
554
555 if (S_ISDIR (file_stat.st_mode))
556 return true;
557
558 if (this_is_the_archive
559 && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
560 return true;
561
562 after_backup_name = find_backup_file_name (file_name, backup_type);
563 if (! after_backup_name)
564 xalloc_die ();
565
566 if (renameat (chdir_fd, before_backup_name, chdir_fd, after_backup_name)
567 == 0)
568 {
569 if (verbose_option)
570 fprintf (stdlis, _("Renaming %s to %s\n"),
571 quote_n (0, before_backup_name),
572 quote_n (1, after_backup_name));
573 return true;
574 }
575 else
576 {
577 /* The backup operation failed. */
578 int e = errno;
579 ERROR ((0, e, _("%s: Cannot rename to %s"),
580 quotearg_colon (before_backup_name),
581 quote_n (1, after_backup_name)));
582 assign_string (&after_backup_name, 0);
583 return false;
584 }
585 }
586
587 /* Try to restore the recently backed up file to its original name.
588 This is usually only needed after a failed extraction. */
589 void
590 undo_last_backup (void)
591 {
592 if (after_backup_name)
593 {
594 if (renameat (chdir_fd, after_backup_name, chdir_fd, before_backup_name)
595 != 0)
596 {
597 int e = errno;
598 ERROR ((0, e, _("%s: Cannot rename to %s"),
599 quotearg_colon (after_backup_name),
600 quote_n (1, before_backup_name)));
601 }
602 if (verbose_option)
603 fprintf (stdlis, _("Renaming %s back to %s\n"),
604 quote_n (0, after_backup_name),
605 quote_n (1, before_backup_name));
606 assign_string (&after_backup_name, 0);
607 }
608 }
609
610 /* Apply either stat or lstat to (NAME, BUF), depending on the
611 presence of the --dereference option. NAME is relative to the
612 most-recent argument to chdir_do. */
613 int
614 deref_stat (char const *name, struct stat *buf)
615 {
616 return fstatat (chdir_fd, name, buf, fstatat_flags);
617 }
618
619 /* Read from FD into the buffer BUF with COUNT bytes. Attempt to fill
620 BUF. Wait until input is available; this matters because files are
621 opened O_NONBLOCK for security reasons, and on some file systems
622 this can cause read to fail with errno == EAGAIN. Return the
623 actual number of bytes read, zero for EOF, or
624 SAFE_READ_ERROR upon error. */
625 size_t
626 blocking_read (int fd, void *buf, size_t count)
627 {
628 size_t bytes = safe_read (fd, buf, count);
629
630 #if defined F_SETFL && O_NONBLOCK
631 if (bytes == SAFE_READ_ERROR && errno == EAGAIN)
632 {
633 int flags = fcntl (fd, F_GETFL);
634 if (0 <= flags && flags & O_NONBLOCK
635 && fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
636 bytes = safe_read (fd, buf, count);
637 }
638 #endif
639
640 return bytes;
641 }
642
643 /* Write to FD from the buffer BUF with COUNT bytes. Do a full write.
644 Wait until an output buffer is available; this matters because
645 files are opened O_NONBLOCK for security reasons, and on some file
646 systems this can cause write to fail with errno == EAGAIN. Return
647 the actual number of bytes written, setting errno if that is less
648 than COUNT. */
649 size_t
650 blocking_write (int fd, void const *buf, size_t count)
651 {
652 size_t bytes = full_write (fd, buf, count);
653
654 #if defined F_SETFL && O_NONBLOCK
655 if (bytes < count && errno == EAGAIN)
656 {
657 int flags = fcntl (fd, F_GETFL);
658 if (0 <= flags && flags & O_NONBLOCK
659 && fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) != -1)
660 {
661 char const *buffer = buf;
662 bytes += full_write (fd, buffer + bytes, count - bytes);
663 }
664 }
665 #endif
666
667 return bytes;
668 }
669
670 /* Set FD's (i.e., assuming the working directory is PARENTFD, FILE's)
671 access time to ATIME. */
672 int
673 set_file_atime (int fd, int parentfd, char const *file, struct timespec atime)
674 {
675 struct timespec ts[2];
676 ts[0] = atime;
677 ts[1].tv_nsec = UTIME_OMIT;
678 return fdutimensat (fd, parentfd, file, ts, fstatat_flags);
679 }
680
681 /* A description of a working directory. */
682 struct wd
683 {
684 /* The directory's name. */
685 char const *name;
686
687 /* If nonzero, the file descriptor of the directory, or AT_FDCWD if
688 the working directory. If zero, the directory needs to be opened
689 to be used. */
690 int fd;
691 };
692
693 /* A vector of chdir targets. wd[0] is the initial working directory. */
694 static struct wd *wd;
695
696 /* The number of working directories in the vector. */
697 static size_t wd_count;
698
699 /* The allocated size of the vector. */
700 static size_t wd_alloc;
701
702 /* The maximum number of chdir targets with open directories.
703 Don't make it too large, as many operating systems have a small
704 limit on the number of open file descriptors. Also, the current
705 implementation does not scale well. */
706 enum { CHDIR_CACHE_SIZE = 16 };
707
708 /* Indexes into WD of chdir targets with open file descriptors, sorted
709 most-recently used first. Zero indexes are unused. */
710 static int wdcache[CHDIR_CACHE_SIZE];
711
712 /* Number of nonzero entries in WDCACHE. */
713 static size_t wdcache_count;
714
715 int
716 chdir_count ()
717 {
718 if (wd_count == 0)
719 return wd_count;
720 return wd_count - 1;
721 }
722
723 /* DIR is the operand of a -C option; add it to vector of chdir targets,
724 and return the index of its location. */
725 int
726 chdir_arg (char const *dir)
727 {
728 if (wd_count == wd_alloc)
729 {
730 if (wd_alloc == 0)
731 {
732 wd_alloc = 2;
733 wd = xmalloc (sizeof *wd * wd_alloc);
734 }
735 else
736 wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
737
738 if (! wd_count)
739 {
740 wd[wd_count].name = ".";
741 wd[wd_count].fd = AT_FDCWD;
742 wd_count++;
743 }
744 }
745
746 /* Optimize the common special case of the working directory,
747 or the working directory as a prefix. */
748 if (dir[0])
749 {
750 while (dir[0] == '.' && ISSLASH (dir[1]))
751 for (dir += 2; ISSLASH (*dir); dir++)
752 continue;
753 if (! dir[dir[0] == '.'])
754 return wd_count - 1;
755 }
756
757 wd[wd_count].name = dir;
758 wd[wd_count].fd = 0;
759 return wd_count++;
760 }
761
762 /* Index of current directory. */
763 int chdir_current;
764
765 /* Value suitable for use as the first argument to openat, and in
766 similar locations for fstatat, etc. This is an open file
767 descriptor, or AT_FDCWD if the working directory is current. It is
768 valid until the next invocation of chdir_do. */
769 int chdir_fd = AT_FDCWD;
770
771 /* Change to directory I, in a virtual way. This does not actually
772 invoke chdir; it merely sets chdir_fd to an int suitable as the
773 first argument for openat, etc. If I is 0, change to the initial
774 working directory; otherwise, I must be a value returned by
775 chdir_arg. */
776 void
777 chdir_do (int i)
778 {
779 if (chdir_current != i)
780 {
781 struct wd *curr = &wd[i];
782 int fd = curr->fd;
783
784 if (! fd)
785 {
786 if (! IS_ABSOLUTE_FILE_NAME (curr->name))
787 chdir_do (i - 1);
788 fd = openat (chdir_fd, curr->name,
789 open_searchdir_flags & ~ O_NOFOLLOW);
790 if (fd < 0)
791 open_fatal (curr->name);
792
793 curr->fd = fd;
794
795 /* Add I to the cache, tossing out the lowest-ranking entry if the
796 cache is full. */
797 if (wdcache_count < CHDIR_CACHE_SIZE)
798 wdcache[wdcache_count++] = i;
799 else
800 {
801 struct wd *stale = &wd[wdcache[CHDIR_CACHE_SIZE - 1]];
802 if (close (stale->fd) != 0)
803 close_diag (stale->name);
804 stale->fd = 0;
805 wdcache[CHDIR_CACHE_SIZE - 1] = i;
806 }
807 }
808
809 if (0 < fd)
810 {
811 /* Move the i value to the front of the cache. This is
812 O(CHDIR_CACHE_SIZE), but the cache is small. */
813 size_t ci;
814 int prev = wdcache[0];
815 for (ci = 1; prev != i; ci++)
816 {
817 int curr = wdcache[ci];
818 wdcache[ci] = prev;
819 if (curr == i)
820 break;
821 prev = curr;
822 }
823 wdcache[0] = i;
824 }
825
826 chdir_current = i;
827 chdir_fd = fd;
828 }
829 }
830 \f
831 void
832 close_diag (char const *name)
833 {
834 if (ignore_failed_read_option)
835 close_warn (name);
836 else
837 close_error (name);
838 }
839
840 void
841 open_diag (char const *name)
842 {
843 if (ignore_failed_read_option)
844 open_warn (name);
845 else
846 open_error (name);
847 }
848
849 void
850 read_diag_details (char const *name, off_t offset, size_t size)
851 {
852 if (ignore_failed_read_option)
853 read_warn_details (name, offset, size);
854 else
855 read_error_details (name, offset, size);
856 }
857
858 void
859 readlink_diag (char const *name)
860 {
861 if (ignore_failed_read_option)
862 readlink_warn (name);
863 else
864 readlink_error (name);
865 }
866
867 void
868 savedir_diag (char const *name)
869 {
870 if (ignore_failed_read_option)
871 savedir_warn (name);
872 else
873 savedir_error (name);
874 }
875
876 void
877 seek_diag_details (char const *name, off_t offset)
878 {
879 if (ignore_failed_read_option)
880 seek_warn_details (name, offset);
881 else
882 seek_error_details (name, offset);
883 }
884
885 void
886 stat_diag (char const *name)
887 {
888 if (ignore_failed_read_option)
889 stat_warn (name);
890 else
891 stat_error (name);
892 }
893
894 void
895 file_removed_diag (const char *name, bool top_level,
896 void (*diagfn) (char const *name))
897 {
898 if (!top_level && errno == ENOENT)
899 {
900 WARNOPT (WARN_FILE_REMOVED,
901 (0, 0, _("%s: File removed before we read it"),
902 quotearg_colon (name)));
903 set_exit_status (TAREXIT_DIFFERS);
904 }
905 else
906 diagfn (name);
907 }
908
909 void
910 write_fatal_details (char const *name, ssize_t status, size_t size)
911 {
912 write_error_details (name, status, size);
913 fatal_exit ();
914 }
915
916 /* Fork, aborting if unsuccessful. */
917 pid_t
918 xfork (void)
919 {
920 pid_t p = fork ();
921 if (p == (pid_t) -1)
922 call_arg_fatal ("fork", _("child process"));
923 return p;
924 }
925
926 /* Create a pipe, aborting if unsuccessful. */
927 void
928 xpipe (int fd[2])
929 {
930 if (pipe (fd) < 0)
931 call_arg_fatal ("pipe", _("interprocess channel"));
932 }
933
934 /* Return PTR, aligned upward to the next multiple of ALIGNMENT.
935 ALIGNMENT must be nonzero. The caller must arrange for ((char *)
936 PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
937 locations. */
938
939 static inline void *
940 ptr_align (void *ptr, size_t alignment)
941 {
942 char *p0 = ptr;
943 char *p1 = p0 + alignment - 1;
944 return p1 - (size_t) p1 % alignment;
945 }
946
947 /* Return the address of a page-aligned buffer of at least SIZE bytes.
948 The caller should free *PTR when done with the buffer. */
949
950 void *
951 page_aligned_alloc (void **ptr, size_t size)
952 {
953 size_t alignment = getpagesize ();
954 size_t size1 = size + alignment;
955 if (size1 < size)
956 xalloc_die ();
957 *ptr = xmalloc (size1);
958 return ptr_align (*ptr, alignment);
959 }
960
961 \f
962
963 struct namebuf
964 {
965 char *buffer; /* directory, `/', and directory member */
966 size_t buffer_size; /* allocated size of name_buffer */
967 size_t dir_length; /* length of directory part in buffer */
968 };
969
970 namebuf_t
971 namebuf_create (const char *dir)
972 {
973 namebuf_t buf = xmalloc (sizeof (*buf));
974 buf->buffer_size = strlen (dir) + 2;
975 buf->buffer = xmalloc (buf->buffer_size);
976 strcpy (buf->buffer, dir);
977 buf->dir_length = strlen (buf->buffer);
978 if (!ISSLASH (buf->buffer[buf->dir_length - 1]))
979 buf->buffer[buf->dir_length++] = DIRECTORY_SEPARATOR;
980 return buf;
981 }
982
983 void
984 namebuf_free (namebuf_t buf)
985 {
986 free (buf->buffer);
987 free (buf);
988 }
989
990 char *
991 namebuf_name (namebuf_t buf, const char *name)
992 {
993 size_t len = strlen (name);
994 while (buf->dir_length + len + 1 >= buf->buffer_size)
995 buf->buffer = x2realloc (buf->buffer, &buf->buffer_size);
996 strcpy (buf->buffer + buf->dir_length, name);
997 return buf->buffer;
998 }
This page took 0.069752 seconds and 5 git commands to generate.