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