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