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