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