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