1 /* System-dependent calls for tar.
2
3 Copyright 2003-2023 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <system.h>
19 #include <system-ioctl.h>
20
21 #include "common.h"
22 #include <priv-set.h>
23 #include <rmt.h>
24 #include <signal.h>
25 #include <wordsplit.h>
26
27 static _Noreturn void
28 xexec (const char *cmd)
29 {
30 char *argv[4];
31
32 argv[0] = (char *) "/bin/sh";
33 argv[1] = (char *) "-c";
34 argv[2] = (char *) cmd;
35 argv[3] = NULL;
36
37 execv ("/bin/sh", argv);
38 exec_fatal (cmd);
39 }
40
41 /* True if the archive is seekable via ioctl and MTIOCTOP,
42 or if it is not known whether it is seekable.
43 False if it is known to be not seekable. */
44 static bool mtioseekable_archive;
45
46 bool
47 mtioseek (bool count_files, off_t count)
48 {
49 if (mtioseekable_archive)
50 {
51 #ifdef MTIOCTOP
52 struct mtop operation;
53 operation.mt_op = (count_files
54 ? (count < 0 ? MTBSF : MTFSF)
55 : (count < 0 ? MTBSR : MTFSR));
56 if (! (count < 0
57 ? INT_SUBTRACT_WRAPV (0, count, &operation.mt_count)
58 : INT_ADD_WRAPV (count, 0, &operation.mt_count))
59 && (0 <= rmtioctl (archive, MTIOCTOP, &operation)
60 || (errno == EIO
61 && 0 <= rmtioctl (archive, MTIOCTOP, &operation))))
62 return true;
63 #endif
64
65 mtioseekable_archive = false;
66 }
67 return false;
68 }
69
70 #if MSDOS
71
72 bool
73 sys_get_archive_stat (void)
74 {
75 return 0;
76 }
77
78 bool
79 sys_file_is_archive (struct tar_stat_info *p)
80 {
81 return false;
82 }
83
84 void
85 sys_detect_dev_null_output (void)
86 {
87 static char const dev_null[] = "nul";
88
89 dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
90 || (! _isrmt (archive)));
91 }
92
93 void
94 sys_wait_for_child (pid_t child_pid, bool eof)
95 {
96 }
97
98 void
99 sys_spawn_shell (void)
100 {
101 spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
102 }
103
104 /* stat() in djgpp's C library gives a constant number of 42 as the
105 uid and gid of a file. So, comparing an FTP'ed archive just after
106 unpack would fail on MSDOS. */
107
108 bool
109 sys_compare_uid (struct stat *a, struct stat *b)
110 {
111 return true;
112 }
113
114 bool
115 sys_compare_gid (struct stat *a, struct stat *b)
116 {
117 return true;
118 }
119
120 void
121 sys_compare_links (struct stat *link_data, struct stat *stat_data)
122 {
123 return true;
124 }
125
126 int
127 sys_truncate (int fd)
128 {
129 return write (fd, "", 0);
130 }
131
132 size_t
133 sys_write_archive_buffer (void)
134 {
135 return full_write (archive, record_start->buffer, record_size);
136 }
137
138 /* Set ARCHIVE for writing, then compressing an archive. */
139 void
140 sys_child_open_for_compress (void)
141 {
142 FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
143 }
144
145 /* Set ARCHIVE for uncompressing, then reading an archive. */
146 void
147 sys_child_open_for_uncompress (void)
148 {
149 FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
150 }
151
152 #else
153
154 extern union block *record_start; /* FIXME */
155
156 bool
157 sys_get_archive_stat (void)
158 {
159 bool remote = _isrmt (archive);
160 mtioseekable_archive = true;
161 if (!remote && 0 <= archive && fstat (archive, &archive_stat) == 0)
162 {
163 if (!S_ISCHR (archive_stat.st_mode))
164 mtioseekable_archive = false;
165 return true;
166 }
167 else
168 {
169 /* FIXME: This memset should not be needed. It is present only
170 because other parts of tar may incorrectly access
171 archive_stat even if it's not the archive status. */
172 memset (&archive_stat, 0, sizeof archive_stat);
173
174 return remote;
175 }
176 }
177
178 bool
179 sys_file_is_archive (struct tar_stat_info *p)
180 {
181 return (!dev_null_output && !_isrmt (archive)
182 && p->stat.st_dev == archive_stat.st_dev
183 && p->stat.st_ino == archive_stat.st_ino);
184 }
185
186 /* Detect if outputting to "/dev/null". */
187 void
188 sys_detect_dev_null_output (void)
189 {
190 static char const dev_null[] = "/dev/null";
191 static struct stat dev_null_stat;
192
193 dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
194 || (! _isrmt (archive)
195 && S_ISCHR (archive_stat.st_mode)
196 && (dev_null_stat.st_ino != 0
197 || stat (dev_null, &dev_null_stat) == 0)
198 && archive_stat.st_ino == dev_null_stat.st_ino
199 && archive_stat.st_dev == dev_null_stat.st_dev));
200 }
201
202 void
203 sys_wait_for_child (pid_t child_pid, bool eof)
204 {
205 if (child_pid)
206 {
207 int wait_status;
208
209 while (waitpid (child_pid, &wait_status, 0) == -1)
210 if (errno != EINTR)
211 {
212 waitpid_error (use_compress_program_option);
213 break;
214 }
215
216 if (WIFSIGNALED (wait_status))
217 {
218 int sig = WTERMSIG (wait_status);
219 if (!(!eof && sig == SIGPIPE))
220 FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig));
221 }
222 else if (WEXITSTATUS (wait_status) != 0)
223 FATAL_ERROR ((0, 0, _("Child returned status %d"),
224 WEXITSTATUS (wait_status)));
225 }
226 }
227
228 void
229 sys_spawn_shell (void)
230 {
231 pid_t child;
232 const char *shell = getenv ("SHELL");
233 if (! shell)
234 shell = "/bin/sh";
235 child = xfork ();
236 if (child == 0)
237 {
238 priv_set_restore_linkdir ();
239 execlp (shell, "-sh", "-i", NULL);
240 exec_fatal (shell);
241 }
242 else
243 {
244 int wait_status;
245 while (waitpid (child, &wait_status, 0) == -1)
246 if (errno != EINTR)
247 {
248 waitpid_error (shell);
249 break;
250 }
251 }
252 }
253
254 bool
255 sys_compare_uid (struct stat *a, struct stat *b)
256 {
257 return a->st_uid == b->st_uid;
258 }
259
260 bool
261 sys_compare_gid (struct stat *a, struct stat *b)
262 {
263 return a->st_gid == b->st_gid;
264 }
265
266 bool
267 sys_compare_links (struct stat *link_data, struct stat *stat_data)
268 {
269 return stat_data->st_dev == link_data->st_dev
270 && stat_data->st_ino == link_data->st_ino;
271 }
272
273 int
274 sys_truncate (int fd)
275 {
276 off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
277 return pos < 0 ? -1 : ftruncate (fd, pos);
278 }
279
280 /* Return nonzero if NAME is the name of a regular file, or if the file
281 does not exist (so it would be created as a regular file). */
282 static int
283 is_regular_file (const char *name)
284 {
285 struct stat stbuf;
286
287 if (stat (name, &stbuf) == 0)
288 return S_ISREG (stbuf.st_mode);
289 else
290 return errno == ENOENT;
291 }
292
293 size_t
294 sys_write_archive_buffer (void)
295 {
296 return rmtwrite (archive, record_start->buffer, record_size);
297 }
298
299 #define PREAD 0 /* read file descriptor from pipe() */
300 #define PWRITE 1 /* write file descriptor from pipe() */
301
302 /* Work around GCC bug 109839. */
303 #if 13 <= __GNUC__
304 # pragma GCC diagnostic ignored "-Wanalyzer-fd-leak"
305 #endif
306
307 /* Duplicate file descriptor FROM into becoming INTO.
308 INTO is closed first and has to be the next available slot. */
309 static void
310 xdup2 (int from, int into)
311 {
312 if (from != into)
313 {
314 if (dup2 (from, into) < 0)
315 {
316 int e = errno;
317 FATAL_ERROR ((0, e, _("Cannot dup2")));
318 }
319 xclose (from);
320 }
321 }
322
323 /* Propagate any failure of the grandchild back to the parent. */
324 static _Noreturn void
325 wait_for_grandchild (pid_t pid)
326 {
327 int wait_status;
328 int exit_code = 0;
329
330 while (waitpid (pid, &wait_status, 0) == -1)
331 if (errno != EINTR)
332 {
333 waitpid_error (use_compress_program_option);
334 break;
335 }
336
337 if (WIFSIGNALED (wait_status))
338 raise (WTERMSIG (wait_status));
339 else if (WEXITSTATUS (wait_status) != 0)
340 exit_code = WEXITSTATUS (wait_status);
341
342 exit (exit_code);
343 }
344
345 /* Set ARCHIVE for writing, then compressing an archive. */
346 pid_t
347 sys_child_open_for_compress (void)
348 {
349 int parent_pipe[2];
350 int child_pipe[2];
351 pid_t grandchild_pid;
352 pid_t child_pid;
353
354 signal (SIGPIPE, SIG_IGN);
355 xpipe (parent_pipe);
356 child_pid = xfork ();
357
358 if (child_pid > 0)
359 {
360 /* The parent tar is still here! Just clean up. */
361
362 archive = parent_pipe[PWRITE];
363 xclose (parent_pipe[PREAD]);
364 return child_pid;
365 }
366
367 /* The new born child tar is here! */
368
369 set_program_name (_("tar (child)"));
370 signal (SIGPIPE, SIG_DFL);
371
372 xdup2 (parent_pipe[PREAD], STDIN_FILENO);
373 xclose (parent_pipe[PWRITE]);
374
375 /* Check if we need a grandchild tar. This happens only if either:
376 a) the file is to be accessed by rmt: compressor doesn't know how;
377 b) the file is not a plain file. */
378
379 if (!_remdev (archive_name_array[0])
380 && is_regular_file (archive_name_array[0]))
381 {
382 if (backup_option)
383 maybe_backup_file (archive_name_array[0], 1);
384
385 /* We don't need a grandchild tar. Open the archive and launch the
386 compressor. */
387 if (strcmp (archive_name_array[0], "-"))
388 {
389 archive = creat (archive_name_array[0], MODE_RW);
390 if (archive < 0)
391 {
392 int saved_errno = errno;
393
394 if (backup_option)
395 undo_last_backup ();
396 errno = saved_errno;
397 open_fatal (archive_name_array[0]);
398 }
399 xdup2 (archive, STDOUT_FILENO);
400 }
401 priv_set_restore_linkdir ();
402 xexec (use_compress_program_option);
403 }
404
405 /* We do need a grandchild tar. */
406
407 xpipe (child_pipe);
408 grandchild_pid = xfork ();
409
410 if (grandchild_pid == 0)
411 {
412 /* The newborn grandchild tar is here! Launch the compressor. */
413
414 set_program_name (_("tar (grandchild)"));
415
416 xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
417 xclose (child_pipe[PREAD]);
418 priv_set_restore_linkdir ();
419 xexec (use_compress_program_option);
420 }
421
422 /* The child tar is still here! */
423
424 /* Prepare for reblocking the data from the compressor into the archive. */
425
426 xdup2 (child_pipe[PREAD], STDIN_FILENO);
427 xclose (child_pipe[PWRITE]);
428
429 if (strcmp (archive_name_array[0], "-") == 0)
430 archive = STDOUT_FILENO;
431 else
432 {
433 archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option);
434 if (archive < 0)
435 open_fatal (archive_name_array[0]);
436 }
437
438 /* Let's read out of the stdin pipe and write an archive. */
439
440 while (1)
441 {
442 size_t status = 0;
443 char *cursor;
444 size_t length;
445
446 /* Assemble a record. */
447
448 for (length = 0, cursor = record_start->buffer;
449 length < record_size;
450 length += status, cursor += status)
451 {
452 size_t size = record_size - length;
453
454 status = safe_read (STDIN_FILENO, cursor, size);
455 if (status == SAFE_READ_ERROR)
456 read_fatal (use_compress_program_option);
457 if (status == 0)
458 break;
459 }
460
461 /* Copy the record. */
462
463 if (status == 0)
464 {
465 /* We hit the end of the file. Write last record at
466 full length, as the only role of the grandchild is
467 doing proper reblocking. */
468
469 if (length > 0)
470 {
471 memset (record_start->buffer + length, 0, record_size - length);
472 status = sys_write_archive_buffer ();
473 if (status != record_size)
474 archive_write_error (status);
475 }
476
477 /* There is nothing else to read, break out. */
478 break;
479 }
480
481 status = sys_write_archive_buffer ();
482 if (status != record_size)
483 archive_write_error (status);
484 }
485
486 wait_for_grandchild (grandchild_pid);
487 }
488
489 static void
490 run_decompress_program (void)
491 {
492 int i;
493 const char *p, *prog = NULL;
494 struct wordsplit ws;
495 int wsflags = (WRDSF_DEFFLAGS | WRDSF_ENV | WRDSF_DOOFFS) & ~WRDSF_NOVAR;
496
497 ws.ws_env = (const char **) environ;
498 ws.ws_offs = 1;
499
500 for (p = first_decompress_program (&i); p; p = next_decompress_program (&i))
501 {
502 if (prog)
503 {
504 WARNOPT (WARN_DECOMPRESS_PROGRAM,
505 (0, errno, _("cannot run %s"), prog));
506 WARNOPT (WARN_DECOMPRESS_PROGRAM,
507 (0, 0, _("trying %s"), p));
508 }
509 if (wordsplit (p, &ws, wsflags))
510 FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
511 p, wordsplit_strerror (&ws)));
512 wsflags |= WRDSF_REUSE;
513 memmove(ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
514 sizeof(ws.ws_wordv[0])*ws.ws_wordc);
515 ws.ws_wordv[ws.ws_wordc] = (char *) "-d";
516 prog = p;
517 execvp (ws.ws_wordv[0], ws.ws_wordv);
518 ws.ws_wordv[ws.ws_wordc] = NULL;
519 }
520 if (!prog)
521 FATAL_ERROR ((0, 0, _("unable to run decompression program")));
522 exec_fatal (prog);
523 }
524
525 /* Set ARCHIVE for uncompressing, then reading an archive. */
526 pid_t
527 sys_child_open_for_uncompress (void)
528 {
529 int parent_pipe[2];
530 int child_pipe[2];
531 pid_t grandchild_pid;
532 pid_t child_pid;
533
534 xpipe (parent_pipe);
535 child_pid = xfork ();
536
537 if (child_pid > 0)
538 {
539 /* The parent tar is still here! Just clean up. */
540
541 archive = parent_pipe[PREAD];
542 xclose (parent_pipe[PWRITE]);
543 return child_pid;
544 }
545
546 /* The newborn child tar is here! */
547
548 set_program_name (_("tar (child)"));
549 signal (SIGPIPE, SIG_DFL);
550
551 xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
552 xclose (parent_pipe[PREAD]);
553
554 /* Check if we need a grandchild tar. This happens only if either:
555 a) we're reading stdin: to force unblocking;
556 b) the file is to be accessed by rmt: compressor doesn't know how;
557 c) the file is not a plain file. */
558
559 if (strcmp (archive_name_array[0], "-") != 0
560 && !_remdev (archive_name_array[0])
561 && is_regular_file (archive_name_array[0]))
562 {
563 /* We don't need a grandchild tar. Open the archive and launch the
564 uncompressor. */
565
566 archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
567 if (archive < 0)
568 open_fatal (archive_name_array[0]);
569 xdup2 (archive, STDIN_FILENO);
570 priv_set_restore_linkdir ();
571 run_decompress_program ();
572 }
573
574 /* We do need a grandchild tar. */
575
576 xpipe (child_pipe);
577 grandchild_pid = xfork ();
578
579 if (grandchild_pid == 0)
580 {
581 /* The newborn grandchild tar is here! Launch the uncompressor. */
582
583 set_program_name (_("tar (grandchild)"));
584
585 xdup2 (child_pipe[PREAD], STDIN_FILENO);
586 xclose (child_pipe[PWRITE]);
587 priv_set_restore_linkdir ();
588 run_decompress_program ();
589 }
590
591 /* The child tar is still here! */
592
593 /* Prepare for unblocking the data from the archive into the
594 uncompressor. */
595
596 xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
597 xclose (child_pipe[PREAD]);
598
599 if (strcmp (archive_name_array[0], "-") == 0)
600 archive = STDIN_FILENO;
601 else
602 archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
603 MODE_RW, rsh_command_option);
604 if (archive < 0)
605 open_fatal (archive_name_array[0]);
606
607 /* Let's read the archive and pipe it into stdout. */
608
609 while (1)
610 {
611 char *cursor;
612 size_t maximum;
613 size_t count;
614 size_t status;
615
616 clear_read_error_count ();
617
618 error_loop:
619 status = rmtread (archive, record_start->buffer, record_size);
620 if (status == SAFE_READ_ERROR)
621 {
622 archive_read_error ();
623 goto error_loop;
624 }
625 if (status == 0)
626 break;
627 cursor = record_start->buffer;
628 maximum = status;
629 while (maximum)
630 {
631 count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
632 if (full_write (STDOUT_FILENO, cursor, count) != count)
633 write_error (use_compress_program_option);
634 cursor += count;
635 maximum -= count;
636 }
637 }
638
639 xclose (STDOUT_FILENO);
640
641 wait_for_grandchild (grandchild_pid);
642 }
643
644
645
646 static void
647 dec_to_env (char const *envar, uintmax_t num)
648 {
649 char buf[UINTMAX_STRSIZE_BOUND];
650 char *numstr;
651
652 numstr = STRINGIFY_BIGINT (num, buf);
653 if (setenv (envar, numstr, 1) != 0)
654 xalloc_die ();
655 }
656
657 static void
658 time_to_env (char const *envar, struct timespec t)
659 {
660 char buf[TIMESPEC_STRSIZE_BOUND];
661 if (setenv (envar, code_timespec (t, buf), 1) != 0)
662 xalloc_die ();
663 }
664
665 static void
666 oct_to_env (char const *envar, unsigned long num)
667 {
668 char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
669
670 snprintf (buf, sizeof buf, "0%lo", num);
671 if (setenv (envar, buf, 1) != 0)
672 xalloc_die ();
673 }
674
675 static void
676 str_to_env (char const *envar, char const *str)
677 {
678 if (str)
679 {
680 if (setenv (envar, str, 1) != 0)
681 xalloc_die ();
682 }
683 else
684 unsetenv (envar);
685 }
686
687 static void
688 chr_to_env (char const *envar, char c)
689 {
690 char buf[2];
691 buf[0] = c;
692 buf[1] = 0;
693 if (setenv (envar, buf, 1) != 0)
694 xalloc_die ();
695 }
696
697 static void
698 stat_to_env (char *name, char type, struct tar_stat_info *st)
699 {
700 str_to_env ("TAR_VERSION", PACKAGE_VERSION);
701 str_to_env ("TAR_ARCHIVE", *archive_name_cursor);
702 dec_to_env ("TAR_VOLUME", archive_name_cursor - archive_name_array + 1);
703 dec_to_env ("TAR_BLOCKING_FACTOR", blocking_factor);
704 str_to_env ("TAR_FORMAT",
705 archive_format_string (current_format == DEFAULT_FORMAT ?
706 archive_format : current_format));
707 chr_to_env ("TAR_FILETYPE", type);
708 oct_to_env ("TAR_MODE", st->stat.st_mode);
709 str_to_env ("TAR_FILENAME", name);
710 str_to_env ("TAR_REALNAME", st->file_name);
711 str_to_env ("TAR_UNAME", st->uname);
712 str_to_env ("TAR_GNAME", st->gname);
713 time_to_env ("TAR_ATIME", st->atime);
714 time_to_env ("TAR_MTIME", st->mtime);
715 time_to_env ("TAR_CTIME", st->ctime);
716 dec_to_env ("TAR_SIZE", st->stat.st_size);
717 dec_to_env ("TAR_UID", st->stat.st_uid);
718 dec_to_env ("TAR_GID", st->stat.st_gid);
719
720 switch (type)
721 {
722 case 'b':
723 case 'c':
724 dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev));
725 dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev));
726 unsetenv ("TAR_LINKNAME");
727 break;
728
729 case 'l':
730 case 'h':
731 unsetenv ("TAR_MINOR");
732 unsetenv ("TAR_MAJOR");
733 str_to_env ("TAR_LINKNAME", st->link_name);
734 break;
735
736 default:
737 unsetenv ("TAR_MINOR");
738 unsetenv ("TAR_MAJOR");
739 unsetenv ("TAR_LINKNAME");
740 break;
741 }
742 }
743
744 static pid_t global_pid;
745 static void (*pipe_handler) (int sig);
746
747 int
748 sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
749 {
750 int p[2];
751
752 xpipe (p);
753 pipe_handler = signal (SIGPIPE, SIG_IGN);
754 global_pid = xfork ();
755
756 if (global_pid != 0)
757 {
758 xclose (p[PREAD]);
759 return p[PWRITE];
760 }
761
762 /* Child */
763 xdup2 (p[PREAD], STDIN_FILENO);
764 xclose (p[PWRITE]);
765
766 stat_to_env (file_name, typechar, st);
767
768 priv_set_restore_linkdir ();
769 xexec (to_command_option);
770 }
771
772 void
773 sys_wait_command (void)
774 {
775 int status;
776
777 if (global_pid < 0)
778 return;
779
780 signal (SIGPIPE, pipe_handler);
781 while (waitpid (global_pid, &status, 0) == -1)
782 if (errno != EINTR)
783 {
784 global_pid = -1;
785 waitpid_error (to_command_option);
786 return;
787 }
788
789 if (WIFEXITED (status))
790 {
791 if (!ignore_command_error_option && WEXITSTATUS (status))
792 ERROR ((0, 0, _("%lu: Child returned status %d"),
793 (unsigned long) global_pid, WEXITSTATUS (status)));
794 }
795 else if (WIFSIGNALED (status))
796 {
797 WARN ((0, 0, _("%lu: Child terminated on signal %d"),
798 (unsigned long) global_pid, WTERMSIG (status)));
799 }
800 else
801 ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
802 (unsigned long) global_pid));
803
804 global_pid = -1;
805 }
806
807 int
808 sys_exec_info_script (const char **archive_name, int volume_number)
809 {
810 pid_t pid;
811 char uintbuf[UINTMAX_STRSIZE_BOUND];
812 int p[2];
813 static void (*saved_handler) (int sig);
814
815 xpipe (p);
816 saved_handler = signal (SIGPIPE, SIG_IGN);
817
818 pid = xfork ();
819
820 if (pid != 0)
821 {
822 /* Master */
823
824 int rc;
825 int status;
826 char *buf = NULL;
827 size_t size = 0;
828 FILE *fp;
829
830 xclose (p[PWRITE]);
831 fp = fdopen (p[PREAD], "r");
832 rc = getline (&buf, &size, fp);
833 fclose (fp);
834
835 if (rc > 0 && buf[rc-1] == '\n')
836 buf[--rc] = 0;
837
838 while (waitpid (pid, &status, 0) == -1)
839 if (errno != EINTR)
840 {
841 signal (SIGPIPE, saved_handler);
842 waitpid_error (info_script_option);
843 return -1;
844 }
845
846 signal (SIGPIPE, saved_handler);
847
848 if (WIFEXITED (status))
849 {
850 if (WEXITSTATUS (status) == 0 && rc > 0)
851 *archive_name = buf;
852 else
853 free (buf);
854 return WEXITSTATUS (status);
855 }
856
857 free (buf);
858 return -1;
859 }
860
861 /* Child */
862 setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
863 setenv ("TAR_ARCHIVE", *archive_name, 1);
864 setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
865 setenv ("TAR_BLOCKING_FACTOR",
866 STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
867 setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
868 setenv ("TAR_FORMAT",
869 archive_format_string (current_format == DEFAULT_FORMAT ?
870 archive_format : current_format), 1);
871 setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
872
873 xclose (p[PREAD]);
874
875 priv_set_restore_linkdir ();
876 xexec (info_script_option);
877 }
878
879 void
880 sys_exec_checkpoint_script (const char *script_name,
881 const char *archive_name,
882 int checkpoint_number)
883 {
884 pid_t pid;
885 char uintbuf[UINTMAX_STRSIZE_BOUND];
886
887 pid = xfork ();
888
889 if (pid != 0)
890 {
891 /* Master */
892
893 int status;
894
895 while (waitpid (pid, &status, 0) == -1)
896 if (errno != EINTR)
897 {
898 waitpid_error (script_name);
899 break;
900 }
901
902 return;
903 }
904
905 /* Child */
906 setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
907 setenv ("TAR_ARCHIVE", archive_name, 1);
908 setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
909 setenv ("TAR_BLOCKING_FACTOR",
910 STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
911 setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
912 setenv ("TAR_FORMAT",
913 archive_format_string (current_format == DEFAULT_FORMAT ?
914 archive_format : current_format), 1);
915 priv_set_restore_linkdir ();
916 xexec (script_name);
917 }
918
919 #endif /* not MSDOS */