]> Dogcows Code - chaz/tar/blob - src/misc.c
(remove_any_file): Fix typo in previous change.
[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, 2005 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 bool try_unlink_first = cannot_unlink_dir ();
276
277 if (try_unlink_first)
278 {
279 if (unlink (file_name) == 0)
280 return 1;
281
282 /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a
283 directory without appropriate privileges, but many Linux
284 kernels return the more-sensible EISDIR. */
285 if (errno != EPERM && errno != EISDIR)
286 return 0;
287 }
288
289 if (safer_rmdir (file_name) == 0)
290 return 1;
291
292 switch (errno)
293 {
294 case ENOTDIR:
295 return !try_unlink_first && unlink (file_name) == 0;
296
297 case 0:
298 case EEXIST:
299 #if defined ENOTEMPTY && ENOTEMPTY != EEXIST
300 case ENOTEMPTY:
301 #endif
302 switch (option)
303 {
304 case ORDINARY_REMOVE_OPTION:
305 break;
306
307 case WANT_DIRECTORY_REMOVE_OPTION:
308 return -1;
309
310 case RECURSIVE_REMOVE_OPTION:
311 {
312 char *directory = savedir (file_name);
313 char const *entry;
314 size_t entrylen;
315
316 if (! directory)
317 return 0;
318
319 for (entry = directory;
320 (entrylen = strlen (entry)) != 0;
321 entry += entrylen + 1)
322 {
323 char *file_name_buffer = new_name (file_name, entry);
324 int r = remove_any_file (file_name_buffer,
325 RECURSIVE_REMOVE_OPTION);
326 int e = errno;
327 free (file_name_buffer);
328
329 if (! r)
330 {
331 free (directory);
332 errno = e;
333 return 0;
334 }
335 }
336
337 free (directory);
338 return safer_rmdir (file_name) == 0;
339 }
340 }
341 break;
342 }
343
344 return 0;
345 }
346
347 /* Check if FILE_NAME already exists and make a backup of it right now.
348 Return success (nonzero) only if the backup is either unneeded, or
349 successful. For now, directories are considered to never need
350 backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and
351 so, we do not have to backup block or character devices, nor remote
352 entities. */
353 bool
354 maybe_backup_file (const char *file_name, int this_is_the_archive)
355 {
356 struct stat file_stat;
357
358 /* Check if we really need to backup the file. */
359
360 if (this_is_the_archive && _remdev (file_name))
361 return true;
362
363 if (stat (file_name, &file_stat))
364 {
365 if (errno == ENOENT)
366 return true;
367
368 stat_error (file_name);
369 return false;
370 }
371
372 if (S_ISDIR (file_stat.st_mode))
373 return true;
374
375 if (this_is_the_archive
376 && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
377 return true;
378
379 assign_string (&before_backup_name, file_name);
380
381 /* A run situation may exist between Emacs or other GNU programs trying to
382 make a backup for the same file simultaneously. If theoretically
383 possible, real problems are unlikely. Doing any better would require a
384 convention, GNU-wide, for all programs doing backups. */
385
386 assign_string (&after_backup_name, 0);
387 after_backup_name = find_backup_file_name (file_name, backup_type);
388 if (! after_backup_name)
389 xalloc_die ();
390
391 if (rename (before_backup_name, after_backup_name) == 0)
392 {
393 if (verbose_option)
394 fprintf (stdlis, _("Renaming %s to %s\n"),
395 quote_n (0, before_backup_name),
396 quote_n (1, after_backup_name));
397 return true;
398 }
399 else
400 {
401 /* The backup operation failed. */
402 int e = errno;
403 ERROR ((0, e, _("%s: Cannot rename to %s"),
404 quotearg_colon (before_backup_name),
405 quote_n (1, after_backup_name)));
406 assign_string (&after_backup_name, 0);
407 return false;
408 }
409 }
410
411 /* Try to restore the recently backed up file to its original name.
412 This is usually only needed after a failed extraction. */
413 void
414 undo_last_backup (void)
415 {
416 if (after_backup_name)
417 {
418 if (rename (after_backup_name, before_backup_name) != 0)
419 {
420 int e = errno;
421 ERROR ((0, e, _("%s: Cannot rename to %s"),
422 quotearg_colon (after_backup_name),
423 quote_n (1, before_backup_name)));
424 }
425 if (verbose_option)
426 fprintf (stdlis, _("Renaming %s back to %s\n"),
427 quote_n (0, after_backup_name),
428 quote_n (1, before_backup_name));
429 assign_string (&after_backup_name, 0);
430 }
431 }
432
433 /* Depending on DEREF, apply either stat or lstat to (NAME, BUF). */
434 int
435 deref_stat (bool deref, char const *name, struct stat *buf)
436 {
437 return deref ? stat (name, buf) : lstat (name, buf);
438 }
439
440 /* A description of a working directory. */
441 struct wd
442 {
443 char const *name;
444 int saved;
445 struct saved_cwd saved_cwd;
446 };
447
448 /* A vector of chdir targets. wd[0] is the initial working directory. */
449 static struct wd *wd;
450
451 /* The number of working directories in the vector. */
452 static size_t wds;
453
454 /* The allocated size of the vector. */
455 static size_t wd_alloc;
456
457 /* DIR is the operand of a -C option; add it to vector of chdir targets,
458 and return the index of its location. */
459 int
460 chdir_arg (char const *dir)
461 {
462 if (wds == wd_alloc)
463 {
464 wd_alloc = 2 * (wd_alloc + 1);
465 wd = xrealloc (wd, sizeof *wd * wd_alloc);
466 if (! wds)
467 {
468 wd[wds].name = ".";
469 wd[wds].saved = 0;
470 wds++;
471 }
472 }
473
474 /* Optimize the common special case of the working directory,
475 or the working directory as a prefix. */
476 if (dir[0])
477 {
478 while (dir[0] == '.' && ISSLASH (dir[1]))
479 for (dir += 2; ISSLASH (*dir); dir++)
480 continue;
481 if (! dir[dir[0] == '.'])
482 return wds - 1;
483 }
484
485 wd[wds].name = dir;
486 wd[wds].saved = 0;
487 return wds++;
488 }
489
490 /* Change to directory I. If I is 0, change to the initial working
491 directory; otherwise, I must be a value returned by chdir_arg. */
492 void
493 chdir_do (int i)
494 {
495 static int previous;
496
497 if (previous != i)
498 {
499 struct wd *prev = &wd[previous];
500 struct wd *curr = &wd[i];
501
502 if (! prev->saved)
503 {
504 prev->saved = 1;
505 if (save_cwd (&prev->saved_cwd) != 0)
506 FATAL_ERROR ((0, 0, _("Cannot save working directory")));
507 }
508
509 if (curr->saved)
510 {
511 if (restore_cwd (&curr->saved_cwd))
512 FATAL_ERROR ((0, 0, _("Cannot change working directory")));
513 }
514 else
515 {
516 if (i && ! ISSLASH (curr->name[0]))
517 chdir_do (i - 1);
518 if (chdir (curr->name) != 0)
519 chdir_fatal (curr->name);
520 }
521
522 previous = i;
523 }
524 }
525 \f
526 /* Decode MODE from its binary form in a stat structure, and encode it
527 into a 9-byte string STRING, terminated with a NUL. */
528
529 void
530 decode_mode (mode_t mode, char *string)
531 {
532 *string++ = mode & S_IRUSR ? 'r' : '-';
533 *string++ = mode & S_IWUSR ? 'w' : '-';
534 *string++ = (mode & S_ISUID
535 ? (mode & S_IXUSR ? 's' : 'S')
536 : (mode & S_IXUSR ? 'x' : '-'));
537 *string++ = mode & S_IRGRP ? 'r' : '-';
538 *string++ = mode & S_IWGRP ? 'w' : '-';
539 *string++ = (mode & S_ISGID
540 ? (mode & S_IXGRP ? 's' : 'S')
541 : (mode & S_IXGRP ? 'x' : '-'));
542 *string++ = mode & S_IROTH ? 'r' : '-';
543 *string++ = mode & S_IWOTH ? 'w' : '-';
544 *string++ = (mode & S_ISVTX
545 ? (mode & S_IXOTH ? 't' : 'T')
546 : (mode & S_IXOTH ? 'x' : '-'));
547 *string = '\0';
548 }
549
550 /* Report an error associated with the system call CALL and the
551 optional name NAME. */
552 static void
553 call_arg_error (char const *call, char const *name)
554 {
555 int e = errno;
556 /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
557 Directly translating this to another language will not work, first because
558 %s itself is not translated.
559 Translate it as `%s: Function %s failed'. */
560 ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
561 }
562
563 /* Report a fatal error associated with the system call CALL and
564 the optional file name NAME. */
565 static void
566 call_arg_fatal (char const *call, char const *name)
567 {
568 int e = errno;
569 /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
570 Directly translating this to another language will not work, first because
571 %s itself is not translated.
572 Translate it as `%s: Function %s failed'. */
573 FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call));
574 }
575
576 /* Report a warning associated with the system call CALL and
577 the optional file name NAME. */
578 static void
579 call_arg_warn (char const *call, char const *name)
580 {
581 int e = errno;
582 /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'.
583 Directly translating this to another language will not work, first because
584 %s itself is not translated.
585 Translate it as `%s: Function %s failed'. */
586 WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call));
587 }
588
589 void
590 chdir_fatal (char const *name)
591 {
592 call_arg_fatal ("chdir", name);
593 }
594
595 void
596 chmod_error_details (char const *name, mode_t mode)
597 {
598 int e = errno;
599 char buf[10];
600 decode_mode (mode, buf);
601 ERROR ((0, e, _("%s: Cannot change mode to %s"),
602 quotearg_colon (name), buf));
603 }
604
605 void
606 chown_error_details (char const *name, uid_t uid, gid_t gid)
607 {
608 int e = errno;
609 ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"),
610 quotearg_colon (name), (unsigned long) uid, (unsigned long) gid));
611 }
612
613 void
614 close_error (char const *name)
615 {
616 call_arg_error ("close", name);
617 }
618
619 void
620 close_warn (char const *name)
621 {
622 call_arg_warn ("close", name);
623 }
624
625 void
626 close_diag (char const *name)
627 {
628 if (ignore_failed_read_option)
629 close_warn (name);
630 else
631 close_error (name);
632 }
633
634 void
635 exec_fatal (char const *name)
636 {
637 call_arg_fatal ("exec", name);
638 }
639
640 void
641 link_error (char const *target, char const *source)
642 {
643 int e = errno;
644 ERROR ((0, e, _("%s: Cannot hard link to %s"),
645 quotearg_colon (source), quote_n (1, target)));
646 }
647
648 void
649 mkdir_error (char const *name)
650 {
651 call_arg_error ("mkdir", name);
652 }
653
654 void
655 mkfifo_error (char const *name)
656 {
657 call_arg_error ("mkfifo", name);
658 }
659
660 void
661 mknod_error (char const *name)
662 {
663 call_arg_error ("mknod", name);
664 }
665
666 void
667 open_error (char const *name)
668 {
669 call_arg_error ("open", name);
670 }
671
672 void
673 open_fatal (char const *name)
674 {
675 call_arg_fatal ("open", name);
676 }
677
678 void
679 open_warn (char const *name)
680 {
681 call_arg_warn ("open", name);
682 }
683
684 void
685 open_diag (char const *name)
686 {
687 if (ignore_failed_read_option)
688 open_warn (name);
689 else
690 open_error (name);
691 }
692
693 void
694 read_error (char const *name)
695 {
696 call_arg_error ("read", name);
697 }
698
699 void
700 read_error_details (char const *name, off_t offset, size_t size)
701 {
702 char buf[UINTMAX_STRSIZE_BOUND];
703 int e = errno;
704 ERROR ((0, e,
705 ngettext ("%s: Read error at byte %s, while reading %lu byte",
706 "%s: Read error at byte %s, while reading %lu bytes",
707 size),
708 quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
709 (unsigned long) size));
710 }
711
712 void
713 read_warn_details (char const *name, off_t offset, size_t size)
714 {
715 char buf[UINTMAX_STRSIZE_BOUND];
716 int e = errno;
717 WARN ((0, e,
718 ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte",
719 "%s: Warning: Read error at byte %s, while reading %lu bytes",
720 size),
721 quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
722 (unsigned long) size));
723 }
724
725 void
726 read_diag_details (char const *name, off_t offset, size_t size)
727 {
728 if (ignore_failed_read_option)
729 read_warn_details (name, offset, size);
730 else
731 read_error_details (name, offset, size);
732 }
733
734 void
735 read_fatal (char const *name)
736 {
737 call_arg_fatal ("read", name);
738 }
739
740 void
741 read_fatal_details (char const *name, off_t offset, size_t size)
742 {
743 char buf[UINTMAX_STRSIZE_BOUND];
744 int e = errno;
745 FATAL_ERROR ((0, e,
746 ngettext ("%s: Read error at byte %s, reading %lu byte",
747 "%s: Read error at byte %s, reading %lu bytes",
748 size),
749 quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
750 (unsigned long) size));
751 }
752
753 void
754 readlink_error (char const *name)
755 {
756 call_arg_error ("readlink", name);
757 }
758
759 void
760 readlink_warn (char const *name)
761 {
762 call_arg_warn ("readlink", name);
763 }
764
765 void
766 readlink_diag (char const *name)
767 {
768 if (ignore_failed_read_option)
769 readlink_warn (name);
770 else
771 readlink_error (name);
772 }
773
774 void
775 savedir_error (char const *name)
776 {
777 call_arg_error ("savedir", name);
778 }
779
780 void
781 savedir_warn (char const *name)
782 {
783 call_arg_warn ("savedir", name);
784 }
785
786 void
787 savedir_diag (char const *name)
788 {
789 if (ignore_failed_read_option)
790 savedir_warn (name);
791 else
792 savedir_error (name);
793 }
794
795 void
796 seek_error (char const *name)
797 {
798 call_arg_error ("seek", name);
799 }
800
801 void
802 seek_error_details (char const *name, off_t offset)
803 {
804 char buf[UINTMAX_STRSIZE_BOUND];
805 int e = errno;
806 ERROR ((0, e, _("%s: Cannot seek to %s"),
807 quotearg_colon (name),
808 STRINGIFY_BIGINT (offset, buf)));
809 }
810
811 void
812 seek_warn (char const *name)
813 {
814 call_arg_warn ("seek", name);
815 }
816
817 void
818 seek_warn_details (char const *name, off_t offset)
819 {
820 char buf[UINTMAX_STRSIZE_BOUND];
821 int e = errno;
822 WARN ((0, e, _("%s: Warning: Cannot seek to %s"),
823 quotearg_colon (name),
824 STRINGIFY_BIGINT (offset, buf)));
825 }
826
827 void
828 seek_diag_details (char const *name, off_t offset)
829 {
830 if (ignore_failed_read_option)
831 seek_warn_details (name, offset);
832 else
833 seek_error_details (name, offset);
834 }
835
836 void
837 symlink_error (char const *contents, char const *name)
838 {
839 int e = errno;
840 ERROR ((0, e, _("%s: Cannot create symlink to %s"),
841 quotearg_colon (name), quote_n (1, contents)));
842 }
843
844 void
845 stat_fatal (char const *name)
846 {
847 call_arg_fatal ("stat", name);
848 }
849
850 void
851 stat_error (char const *name)
852 {
853 call_arg_error ("stat", name);
854 }
855
856 void
857 stat_warn (char const *name)
858 {
859 call_arg_warn ("stat", name);
860 }
861
862 void
863 stat_diag (char const *name)
864 {
865 if (ignore_failed_read_option)
866 stat_warn (name);
867 else
868 stat_error (name);
869 }
870
871 void
872 truncate_error (char const *name)
873 {
874 call_arg_error ("truncate", name);
875 }
876
877 void
878 truncate_warn (char const *name)
879 {
880 call_arg_warn ("truncate", name);
881 }
882
883 void
884 unlink_error (char const *name)
885 {
886 call_arg_error ("unlink", name);
887 }
888
889 void
890 utime_error (char const *name)
891 {
892 call_arg_error ("utime", name);
893 }
894
895 void
896 waitpid_error (char const *name)
897 {
898 call_arg_error ("waitpid", name);
899 }
900
901 void
902 write_error (char const *name)
903 {
904 call_arg_error ("write", name);
905 }
906
907 void
908 write_error_details (char const *name, size_t status, size_t size)
909 {
910 if (status == 0)
911 write_error (name);
912 else
913 ERROR ((0, 0,
914 ngettext ("%s: Wrote only %lu of %lu byte",
915 "%s: Wrote only %lu of %lu bytes",
916 size),
917 name, (unsigned long int) status, (unsigned long int) size));
918 }
919
920 void
921 write_fatal (char const *name)
922 {
923 call_arg_fatal ("write", name);
924 }
925
926 void
927 write_fatal_details (char const *name, ssize_t status, size_t size)
928 {
929 write_error_details (name, status, size);
930 fatal_exit ();
931 }
932
933
934 /* Fork, aborting if unsuccessful. */
935 pid_t
936 xfork (void)
937 {
938 pid_t p = fork ();
939 if (p == (pid_t) -1)
940 call_arg_fatal ("fork", _("child process"));
941 return p;
942 }
943
944 /* Create a pipe, aborting if unsuccessful. */
945 void
946 xpipe (int fd[2])
947 {
948 if (pipe (fd) < 0)
949 call_arg_fatal ("pipe", _("interprocess channel"));
950 }
951
952 /* Return PTR, aligned upward to the next multiple of ALIGNMENT.
953 ALIGNMENT must be nonzero. The caller must arrange for ((char *)
954 PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
955 locations. */
956
957 static inline void *
958 ptr_align (void *ptr, size_t alignment)
959 {
960 char *p0 = ptr;
961 char *p1 = p0 + alignment - 1;
962 return p1 - (size_t) p1 % alignment;
963 }
964
965 /* Return the address of a page-aligned buffer of at least SIZE bytes.
966 The caller should free *PTR when done with the buffer. */
967
968 void *
969 page_aligned_alloc (void **ptr, size_t size)
970 {
971 size_t alignment = getpagesize ();
972 size_t size1 = size + alignment;
973 if (size1 < size)
974 xalloc_die ();
975 *ptr = xmalloc (size1);
976 return ptr_align (*ptr, alignment);
977 }
This page took 0.069482 seconds and 5 git commands to generate.