Import upstream version 1.26
[debian/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 /* Set FD's (i.e., assuming the working directory is PARENTFD, FILE's)
620    access time to ATIME.  */
621 int
622 set_file_atime (int fd, int parentfd, char const *file, struct timespec atime)
623 {
624   struct timespec ts[2];
625   ts[0] = atime;
626   ts[1].tv_nsec = UTIME_OMIT;
627   return fdutimensat (fd, parentfd, file, ts, fstatat_flags);
628 }
629
630 /* A description of a working directory.  */
631 struct wd
632 {
633   /* The directory's name.  */
634   char const *name;
635
636   /* If nonzero, the file descriptor of the directory, or AT_FDCWD if
637      the working directory.  If zero, the directory needs to be opened
638      to be used.  */
639   int fd;
640 };
641
642 /* A vector of chdir targets.  wd[0] is the initial working directory.  */
643 static struct wd *wd;
644
645 /* The number of working directories in the vector.  */
646 static size_t wd_count;
647
648 /* The allocated size of the vector.  */
649 static size_t wd_alloc;
650
651 /* The maximum number of chdir targets with open directories.
652    Don't make it too large, as many operating systems have a small
653    limit on the number of open file descriptors.  Also, the current
654    implementation does not scale well.  */
655 enum { CHDIR_CACHE_SIZE = 16 };
656
657 /* Indexes into WD of chdir targets with open file descriptors, sorted
658    most-recently used first.  Zero indexes are unused.  */
659 static int wdcache[CHDIR_CACHE_SIZE];
660
661 /* Number of nonzero entries in WDCACHE.  */
662 static size_t wdcache_count;
663
664 int
665 chdir_count ()
666 {
667   if (wd_count == 0)
668     return wd_count;
669   return wd_count - 1;
670 }
671
672 /* DIR is the operand of a -C option; add it to vector of chdir targets,
673    and return the index of its location.  */
674 int
675 chdir_arg (char const *dir)
676 {
677   if (wd_count == wd_alloc)
678     {
679       if (wd_alloc == 0)
680         {
681           wd_alloc = 2;
682           wd = xmalloc (sizeof *wd * wd_alloc);
683         }
684       else
685         wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
686
687       if (! wd_count)
688         {
689           wd[wd_count].name = ".";
690           wd[wd_count].fd = AT_FDCWD;
691           wd_count++;
692         }
693     }
694
695   /* Optimize the common special case of the working directory,
696      or the working directory as a prefix.  */
697   if (dir[0])
698     {
699       while (dir[0] == '.' && ISSLASH (dir[1]))
700         for (dir += 2;  ISSLASH (*dir);  dir++)
701           continue;
702       if (! dir[dir[0] == '.'])
703         return wd_count - 1;
704     }
705
706   wd[wd_count].name = dir;
707   wd[wd_count].fd = 0;
708   return wd_count++;
709 }
710
711 /* Index of current directory.  */
712 int chdir_current;
713
714 /* Value suitable for use as the first argument to openat, and in
715    similar locations for fstatat, etc.  This is an open file
716    descriptor, or AT_FDCWD if the working directory is current.  It is
717    valid until the next invocation of chdir_do.  */
718 int chdir_fd = AT_FDCWD;
719
720 /* Change to directory I, in a virtual way.  This does not actually
721    invoke chdir; it merely sets chdir_fd to an int suitable as the
722    first argument for openat, etc.  If I is 0, change to the initial
723    working directory; otherwise, I must be a value returned by
724    chdir_arg.  */
725 void
726 chdir_do (int i)
727 {
728   if (chdir_current != i)
729     {
730       struct wd *curr = &wd[i];
731       int fd = curr->fd;
732
733       if (! fd)
734         {
735           if (! IS_ABSOLUTE_FILE_NAME (curr->name))
736             chdir_do (i - 1);
737           fd = openat (chdir_fd, curr->name,
738                        open_searchdir_flags & ~ O_NOFOLLOW);
739           if (fd < 0)
740             open_fatal (curr->name);
741
742           curr->fd = fd;
743
744           /* Add I to the cache, tossing out the lowest-ranking entry if the
745              cache is full.  */
746           if (wdcache_count < CHDIR_CACHE_SIZE)
747             wdcache[wdcache_count++] = i;
748           else
749             {
750               struct wd *stale = &wd[wdcache[CHDIR_CACHE_SIZE - 1]];
751               if (close (stale->fd) != 0)
752                 close_diag (stale->name);
753               stale->fd = 0;
754               wdcache[CHDIR_CACHE_SIZE - 1] = i;
755             }
756         }
757
758       if (0 < fd)
759         {
760           /* Move the i value to the front of the cache.  This is
761              O(CHDIR_CACHE_SIZE), but the cache is small.  */
762           size_t ci;
763           int prev = wdcache[0];
764           for (ci = 1; prev != i; ci++)
765             {
766               int curr = wdcache[ci];
767               wdcache[ci] = prev;
768               if (curr == i)
769                 break;
770               prev = curr;
771             }
772           wdcache[0] = i;
773         }
774
775       chdir_current = i;
776       chdir_fd = fd;
777     }
778 }
779 \f
780 void
781 close_diag (char const *name)
782 {
783   if (ignore_failed_read_option)
784     close_warn (name);
785   else
786     close_error (name);
787 }
788
789 void
790 open_diag (char const *name)
791 {
792   if (ignore_failed_read_option)
793     open_warn (name);
794   else
795     open_error (name);
796 }
797
798 void
799 read_diag_details (char const *name, off_t offset, size_t size)
800 {
801   if (ignore_failed_read_option)
802     read_warn_details (name, offset, size);
803   else
804     read_error_details (name, offset, size);
805 }
806
807 void
808 readlink_diag (char const *name)
809 {
810   if (ignore_failed_read_option)
811     readlink_warn (name);
812   else
813     readlink_error (name);
814 }
815
816 void
817 savedir_diag (char const *name)
818 {
819   if (ignore_failed_read_option)
820     savedir_warn (name);
821   else
822     savedir_error (name);
823 }
824
825 void
826 seek_diag_details (char const *name, off_t offset)
827 {
828   if (ignore_failed_read_option)
829     seek_warn_details (name, offset);
830   else
831     seek_error_details (name, offset);
832 }
833
834 void
835 stat_diag (char const *name)
836 {
837   if (ignore_failed_read_option)
838     stat_warn (name);
839   else
840     stat_error (name);
841 }
842
843 void
844 file_removed_diag (const char *name, bool top_level,
845                    void (*diagfn) (char const *name))
846 {
847   if (!top_level && errno == ENOENT)
848     {
849       WARNOPT (WARN_FILE_REMOVED,
850                (0, 0, _("%s: File removed before we read it"),
851                 quotearg_colon (name)));
852       set_exit_status (TAREXIT_DIFFERS);
853     }
854   else
855     diagfn (name);
856 }
857
858 void
859 write_fatal_details (char const *name, ssize_t status, size_t size)
860 {
861   write_error_details (name, status, size);
862   fatal_exit ();
863 }
864
865 /* Fork, aborting if unsuccessful.  */
866 pid_t
867 xfork (void)
868 {
869   pid_t p = fork ();
870   if (p == (pid_t) -1)
871     call_arg_fatal ("fork", _("child process"));
872   return p;
873 }
874
875 /* Create a pipe, aborting if unsuccessful.  */
876 void
877 xpipe (int fd[2])
878 {
879   if (pipe (fd) < 0)
880     call_arg_fatal ("pipe", _("interprocess channel"));
881 }
882
883 /* Return PTR, aligned upward to the next multiple of ALIGNMENT.
884    ALIGNMENT must be nonzero.  The caller must arrange for ((char *)
885    PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
886    locations.  */
887
888 static inline void *
889 ptr_align (void *ptr, size_t alignment)
890 {
891   char *p0 = ptr;
892   char *p1 = p0 + alignment - 1;
893   return p1 - (size_t) p1 % alignment;
894 }
895
896 /* Return the address of a page-aligned buffer of at least SIZE bytes.
897    The caller should free *PTR when done with the buffer.  */
898
899 void *
900 page_aligned_alloc (void **ptr, size_t size)
901 {
902   size_t alignment = getpagesize ();
903   size_t size1 = size + alignment;
904   if (size1 < size)
905     xalloc_die ();
906   *ptr = xmalloc (size1);
907   return ptr_align (*ptr, alignment);
908 }
909
910 \f
911
912 struct namebuf
913 {
914   char *buffer;         /* directory, `/', and directory member */
915   size_t buffer_size;   /* allocated size of name_buffer */
916   size_t dir_length;    /* length of directory part in buffer */
917 };
918
919 namebuf_t
920 namebuf_create (const char *dir)
921 {
922   namebuf_t buf = xmalloc (sizeof (*buf));
923   buf->buffer_size = strlen (dir) + 2;
924   buf->buffer = xmalloc (buf->buffer_size);
925   strcpy (buf->buffer, dir);
926   buf->dir_length = strlen (buf->buffer);
927   if (!ISSLASH (buf->buffer[buf->dir_length - 1]))
928     buf->buffer[buf->dir_length++] = DIRECTORY_SEPARATOR;
929   return buf;
930 }
931
932 void
933 namebuf_free (namebuf_t buf)
934 {
935   free (buf->buffer);
936   free (buf);
937 }
938
939 char *
940 namebuf_name (namebuf_t buf, const char *name)
941 {
942   size_t len = strlen (name);
943   while (buf->dir_length + len + 1 >= buf->buffer_size)
944     buf->buffer = x2realloc (buf->buffer, &buf->buffer_size);
945   strcpy (buf->buffer + buf->dir_length, name);
946   return buf->buffer;
947 }