system.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. /* System-dependent calls for tar.
  2. Copyright (C) 2003, 2004, 2005, 2006, 2007,
  3. 2008 Free Software Foundation, Inc.
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. This program is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  11. Public License for more details.
  12. You should have received a copy of the GNU General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  15. #include <system.h>
  16. #include "common.h"
  17. #include <rmt.h>
  18. #include <signal.h>
  19. #if MSDOS
  20. bool
  21. sys_get_archive_stat (void)
  22. {
  23. return 0;
  24. }
  25. bool
  26. sys_file_is_archive (struct tar_stat_info *p)
  27. {
  28. return false;
  29. }
  30. void
  31. sys_save_archive_dev_ino (void)
  32. {
  33. }
  34. void
  35. sys_detect_dev_null_output (void)
  36. {
  37. static char const dev_null[] = "nul";
  38. dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
  39. || (! _isrmt (archive)));
  40. }
  41. void
  42. sys_wait_for_child (pid_t child_pid, bool eof)
  43. {
  44. }
  45. void
  46. sys_spawn_shell (void)
  47. {
  48. spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
  49. }
  50. /* stat() in djgpp's C library gives a constant number of 42 as the
  51. uid and gid of a file. So, comparing an FTP'ed archive just after
  52. unpack would fail on MSDOS. */
  53. bool
  54. sys_compare_uid (struct stat *a, struct stat *b)
  55. {
  56. return true;
  57. }
  58. bool
  59. sys_compare_gid (struct stat *a, struct stat *b)
  60. {
  61. return true;
  62. }
  63. void
  64. sys_compare_links (struct stat *link_data, struct stat *stat_data)
  65. {
  66. return true;
  67. }
  68. int
  69. sys_truncate (int fd)
  70. {
  71. return write (fd, "", 0);
  72. }
  73. size_t
  74. sys_write_archive_buffer (void)
  75. {
  76. return full_write (archive, record_start->buffer, record_size);
  77. }
  78. /* Set ARCHIVE for writing, then compressing an archive. */
  79. void
  80. sys_child_open_for_compress (void)
  81. {
  82. FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  83. }
  84. /* Set ARCHIVE for uncompressing, then reading an archive. */
  85. void
  86. sys_child_open_for_uncompress (void)
  87. {
  88. FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  89. }
  90. #else
  91. extern union block *record_start; /* FIXME */
  92. static struct stat archive_stat; /* stat block for archive file */
  93. bool
  94. sys_get_archive_stat (void)
  95. {
  96. return fstat (archive, &archive_stat) == 0;
  97. }
  98. bool
  99. sys_file_is_archive (struct tar_stat_info *p)
  100. {
  101. return (ar_dev && p->stat.st_dev == ar_dev && p->stat.st_ino == ar_ino);
  102. }
  103. /* Save archive file inode and device numbers */
  104. void
  105. sys_save_archive_dev_ino (void)
  106. {
  107. if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode))
  108. {
  109. ar_dev = archive_stat.st_dev;
  110. ar_ino = archive_stat.st_ino;
  111. }
  112. else
  113. ar_dev = 0;
  114. }
  115. /* Detect if outputting to "/dev/null". */
  116. void
  117. sys_detect_dev_null_output (void)
  118. {
  119. static char const dev_null[] = "/dev/null";
  120. struct stat dev_null_stat;
  121. dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
  122. || (! _isrmt (archive)
  123. && S_ISCHR (archive_stat.st_mode)
  124. && stat (dev_null, &dev_null_stat) == 0
  125. && archive_stat.st_dev == dev_null_stat.st_dev
  126. && archive_stat.st_ino == dev_null_stat.st_ino));
  127. }
  128. void
  129. sys_wait_for_child (pid_t child_pid, bool eof)
  130. {
  131. if (child_pid)
  132. {
  133. int wait_status;
  134. while (waitpid (child_pid, &wait_status, 0) == -1)
  135. if (errno != EINTR)
  136. {
  137. waitpid_error (use_compress_program_option);
  138. break;
  139. }
  140. if (WIFSIGNALED (wait_status))
  141. {
  142. int sig = WTERMSIG (wait_status);
  143. if (!(!eof && sig == SIGPIPE))
  144. FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig));
  145. }
  146. else if (WEXITSTATUS (wait_status) != 0)
  147. FATAL_ERROR ((0, 0, _("Child returned status %d"),
  148. WEXITSTATUS (wait_status)));
  149. }
  150. }
  151. void
  152. sys_spawn_shell (void)
  153. {
  154. pid_t child;
  155. const char *shell = getenv ("SHELL");
  156. if (! shell)
  157. shell = "/bin/sh";
  158. child = xfork ();
  159. if (child == 0)
  160. {
  161. execlp (shell, "-sh", "-i", (char *) 0);
  162. exec_fatal (shell);
  163. }
  164. else
  165. {
  166. int wait_status;
  167. while (waitpid (child, &wait_status, 0) == -1)
  168. if (errno != EINTR)
  169. {
  170. waitpid_error (shell);
  171. break;
  172. }
  173. }
  174. }
  175. bool
  176. sys_compare_uid (struct stat *a, struct stat *b)
  177. {
  178. return a->st_uid == b->st_uid;
  179. }
  180. bool
  181. sys_compare_gid (struct stat *a, struct stat *b)
  182. {
  183. return a->st_gid == b->st_gid;
  184. }
  185. bool
  186. sys_compare_links (struct stat *link_data, struct stat *stat_data)
  187. {
  188. return stat_data->st_dev == link_data->st_dev
  189. && stat_data->st_ino == link_data->st_ino;
  190. }
  191. int
  192. sys_truncate (int fd)
  193. {
  194. off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
  195. return pos < 0 ? -1 : ftruncate (fd, pos);
  196. }
  197. /* Return nonzero if NAME is the name of a regular file, or if the file
  198. does not exist (so it would be created as a regular file). */
  199. static int
  200. is_regular_file (const char *name)
  201. {
  202. struct stat stbuf;
  203. if (stat (name, &stbuf) == 0)
  204. return S_ISREG (stbuf.st_mode);
  205. else
  206. return errno == ENOENT;
  207. }
  208. size_t
  209. sys_write_archive_buffer (void)
  210. {
  211. return rmtwrite (archive, record_start->buffer, record_size);
  212. }
  213. #define PREAD 0 /* read file descriptor from pipe() */
  214. #define PWRITE 1 /* write file descriptor from pipe() */
  215. /* Duplicate file descriptor FROM into becoming INTO.
  216. INTO is closed first and has to be the next available slot. */
  217. static void
  218. xdup2 (int from, int into)
  219. {
  220. if (from != into)
  221. {
  222. int status = close (into);
  223. if (status != 0 && errno != EBADF)
  224. {
  225. int e = errno;
  226. FATAL_ERROR ((0, e, _("Cannot close")));
  227. }
  228. status = dup (from);
  229. if (status != into)
  230. {
  231. if (status < 0)
  232. {
  233. int e = errno;
  234. FATAL_ERROR ((0, e, _("Cannot dup")));
  235. }
  236. abort ();
  237. }
  238. xclose (from);
  239. }
  240. }
  241. void wait_for_grandchild (pid_t pid) __attribute__ ((__noreturn__));
  242. /* Propagate any failure of the grandchild back to the parent. */
  243. void
  244. wait_for_grandchild (pid_t pid)
  245. {
  246. int wait_status;
  247. int exit_code = 0;
  248. while (waitpid (pid, &wait_status, 0) == -1)
  249. if (errno != EINTR)
  250. {
  251. waitpid_error (use_compress_program_option);
  252. break;
  253. }
  254. if (WIFSIGNALED (wait_status))
  255. raise (WTERMSIG (wait_status));
  256. else if (WEXITSTATUS (wait_status) != 0)
  257. exit_code = WEXITSTATUS (wait_status);
  258. exit (exit_code);
  259. }
  260. /* Set ARCHIVE for writing, then compressing an archive. */
  261. pid_t
  262. sys_child_open_for_compress (void)
  263. {
  264. int parent_pipe[2];
  265. int child_pipe[2];
  266. pid_t grandchild_pid;
  267. pid_t child_pid;
  268. xpipe (parent_pipe);
  269. child_pid = xfork ();
  270. if (child_pid > 0)
  271. {
  272. /* The parent tar is still here! Just clean up. */
  273. archive = parent_pipe[PWRITE];
  274. xclose (parent_pipe[PREAD]);
  275. return child_pid;
  276. }
  277. /* The new born child tar is here! */
  278. set_program_name (_("tar (child)"));
  279. signal (SIGPIPE, SIG_DFL);
  280. xdup2 (parent_pipe[PREAD], STDIN_FILENO);
  281. xclose (parent_pipe[PWRITE]);
  282. /* Check if we need a grandchild tar. This happens only if either:
  283. a) the file is to be accessed by rmt: compressor doesn't know how;
  284. b) the file is not a plain file. */
  285. if (!_remdev (archive_name_array[0])
  286. && is_regular_file (archive_name_array[0]))
  287. {
  288. if (backup_option)
  289. maybe_backup_file (archive_name_array[0], 1);
  290. /* We don't need a grandchild tar. Open the archive and launch the
  291. compressor. */
  292. if (strcmp (archive_name_array[0], "-"))
  293. {
  294. archive = creat (archive_name_array[0], MODE_RW);
  295. if (archive < 0)
  296. {
  297. int saved_errno = errno;
  298. if (backup_option)
  299. undo_last_backup ();
  300. errno = saved_errno;
  301. open_fatal (archive_name_array[0]);
  302. }
  303. xdup2 (archive, STDOUT_FILENO);
  304. }
  305. execlp (use_compress_program_option, use_compress_program_option, NULL);
  306. exec_fatal (use_compress_program_option);
  307. }
  308. /* We do need a grandchild tar. */
  309. xpipe (child_pipe);
  310. grandchild_pid = xfork ();
  311. if (grandchild_pid == 0)
  312. {
  313. /* The newborn grandchild tar is here! Launch the compressor. */
  314. set_program_name (_("tar (grandchild)"));
  315. xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
  316. xclose (child_pipe[PREAD]);
  317. execlp (use_compress_program_option, use_compress_program_option,
  318. (char *) 0);
  319. exec_fatal (use_compress_program_option);
  320. }
  321. /* The child tar is still here! */
  322. /* Prepare for reblocking the data from the compressor into the archive. */
  323. xdup2 (child_pipe[PREAD], STDIN_FILENO);
  324. xclose (child_pipe[PWRITE]);
  325. if (strcmp (archive_name_array[0], "-") == 0)
  326. archive = STDOUT_FILENO;
  327. else
  328. {
  329. archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option);
  330. if (archive < 0)
  331. open_fatal (archive_name_array[0]);
  332. }
  333. /* Let's read out of the stdin pipe and write an archive. */
  334. while (1)
  335. {
  336. size_t status = 0;
  337. char *cursor;
  338. size_t length;
  339. /* Assemble a record. */
  340. for (length = 0, cursor = record_start->buffer;
  341. length < record_size;
  342. length += status, cursor += status)
  343. {
  344. size_t size = record_size - length;
  345. status = safe_read (STDIN_FILENO, cursor, size);
  346. if (status == SAFE_READ_ERROR)
  347. read_fatal (use_compress_program_option);
  348. if (status == 0)
  349. break;
  350. }
  351. /* Copy the record. */
  352. if (status == 0)
  353. {
  354. /* We hit the end of the file. Write last record at
  355. full length, as the only role of the grandchild is
  356. doing proper reblocking. */
  357. if (length > 0)
  358. {
  359. memset (record_start->buffer + length, 0, record_size - length);
  360. status = sys_write_archive_buffer ();
  361. if (status != record_size)
  362. archive_write_error (status);
  363. }
  364. /* There is nothing else to read, break out. */
  365. break;
  366. }
  367. status = sys_write_archive_buffer ();
  368. if (status != record_size)
  369. archive_write_error (status);
  370. }
  371. wait_for_grandchild (grandchild_pid);
  372. }
  373. /* Set ARCHIVE for uncompressing, then reading an archive. */
  374. pid_t
  375. sys_child_open_for_uncompress (void)
  376. {
  377. int parent_pipe[2];
  378. int child_pipe[2];
  379. pid_t grandchild_pid;
  380. pid_t child_pid;
  381. xpipe (parent_pipe);
  382. child_pid = xfork ();
  383. if (child_pid > 0)
  384. {
  385. /* The parent tar is still here! Just clean up. */
  386. archive = parent_pipe[PREAD];
  387. xclose (parent_pipe[PWRITE]);
  388. return child_pid;
  389. }
  390. /* The newborn child tar is here! */
  391. set_program_name (_("tar (child)"));
  392. signal (SIGPIPE, SIG_DFL);
  393. xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
  394. xclose (parent_pipe[PREAD]);
  395. /* Check if we need a grandchild tar. This happens only if either:
  396. a) we're reading stdin: to force unblocking;
  397. b) the file is to be accessed by rmt: compressor doesn't know how;
  398. c) the file is not a plain file. */
  399. if (strcmp (archive_name_array[0], "-") != 0
  400. && !_remdev (archive_name_array[0])
  401. && is_regular_file (archive_name_array[0]))
  402. {
  403. /* We don't need a grandchild tar. Open the archive and lauch the
  404. uncompressor. */
  405. archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
  406. if (archive < 0)
  407. open_fatal (archive_name_array[0]);
  408. xdup2 (archive, STDIN_FILENO);
  409. execlp (use_compress_program_option, use_compress_program_option,
  410. "-d", (char *) 0);
  411. exec_fatal (use_compress_program_option);
  412. }
  413. /* We do need a grandchild tar. */
  414. xpipe (child_pipe);
  415. grandchild_pid = xfork ();
  416. if (grandchild_pid == 0)
  417. {
  418. /* The newborn grandchild tar is here! Launch the uncompressor. */
  419. set_program_name (_("tar (grandchild)"));
  420. xdup2 (child_pipe[PREAD], STDIN_FILENO);
  421. xclose (child_pipe[PWRITE]);
  422. execlp (use_compress_program_option, use_compress_program_option,
  423. "-d", (char *) 0);
  424. exec_fatal (use_compress_program_option);
  425. }
  426. /* The child tar is still here! */
  427. /* Prepare for unblocking the data from the archive into the
  428. uncompressor. */
  429. xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
  430. xclose (child_pipe[PREAD]);
  431. if (strcmp (archive_name_array[0], "-") == 0)
  432. archive = STDIN_FILENO;
  433. else
  434. archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
  435. MODE_RW, rsh_command_option);
  436. if (archive < 0)
  437. open_fatal (archive_name_array[0]);
  438. /* Let's read the archive and pipe it into stdout. */
  439. while (1)
  440. {
  441. char *cursor;
  442. size_t maximum;
  443. size_t count;
  444. size_t status;
  445. clear_read_error_count ();
  446. error_loop:
  447. status = rmtread (archive, record_start->buffer, record_size);
  448. if (status == SAFE_READ_ERROR)
  449. {
  450. archive_read_error ();
  451. goto error_loop;
  452. }
  453. if (status == 0)
  454. break;
  455. cursor = record_start->buffer;
  456. maximum = status;
  457. while (maximum)
  458. {
  459. count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
  460. if (full_write (STDOUT_FILENO, cursor, count) != count)
  461. write_error (use_compress_program_option);
  462. cursor += count;
  463. maximum -= count;
  464. }
  465. }
  466. xclose (STDOUT_FILENO);
  467. wait_for_grandchild (grandchild_pid);
  468. }
  469. static void
  470. dec_to_env (char *envar, uintmax_t num)
  471. {
  472. char buf[UINTMAX_STRSIZE_BOUND];
  473. char *numstr;
  474. numstr = STRINGIFY_BIGINT (num, buf);
  475. if (setenv (envar, numstr, 1) != 0)
  476. xalloc_die ();
  477. }
  478. static void
  479. time_to_env (char *envar, struct timespec t)
  480. {
  481. char buf[TIMESPEC_STRSIZE_BOUND];
  482. if (setenv (envar, code_timespec (t, buf), 1) != 0)
  483. xalloc_die ();
  484. }
  485. static void
  486. oct_to_env (char *envar, unsigned long num)
  487. {
  488. char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
  489. snprintf (buf, sizeof buf, "0%lo", num);
  490. if (setenv (envar, buf, 1) != 0)
  491. xalloc_die ();
  492. }
  493. static void
  494. str_to_env (char *envar, char const *str)
  495. {
  496. if (str)
  497. {
  498. if (setenv (envar, str, 1) != 0)
  499. xalloc_die ();
  500. }
  501. else
  502. unsetenv (envar);
  503. }
  504. static void
  505. chr_to_env (char *envar, char c)
  506. {
  507. char buf[2];
  508. buf[0] = c;
  509. buf[1] = 0;
  510. if (setenv (envar, buf, 1) != 0)
  511. xalloc_die ();
  512. }
  513. static void
  514. stat_to_env (char *name, char type, struct tar_stat_info *st)
  515. {
  516. str_to_env ("TAR_VERSION", PACKAGE_VERSION);
  517. chr_to_env ("TAR_FILETYPE", type);
  518. oct_to_env ("TAR_MODE", st->stat.st_mode);
  519. str_to_env ("TAR_FILENAME", name);
  520. str_to_env ("TAR_REALNAME", st->file_name);
  521. str_to_env ("TAR_UNAME", st->uname);
  522. str_to_env ("TAR_GNAME", st->gname);
  523. time_to_env ("TAR_ATIME", st->atime);
  524. time_to_env ("TAR_MTIME", st->mtime);
  525. time_to_env ("TAR_CTIME", st->ctime);
  526. dec_to_env ("TAR_SIZE", st->stat.st_size);
  527. dec_to_env ("TAR_UID", st->stat.st_uid);
  528. dec_to_env ("TAR_GID", st->stat.st_gid);
  529. switch (type)
  530. {
  531. case 'b':
  532. case 'c':
  533. dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev));
  534. dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev));
  535. unsetenv ("TAR_LINKNAME");
  536. break;
  537. case 'l':
  538. case 'h':
  539. unsetenv ("TAR_MINOR");
  540. unsetenv ("TAR_MAJOR");
  541. str_to_env ("TAR_LINKNAME", st->link_name);
  542. break;
  543. default:
  544. unsetenv ("TAR_MINOR");
  545. unsetenv ("TAR_MAJOR");
  546. unsetenv ("TAR_LINKNAME");
  547. break;
  548. }
  549. }
  550. static pid_t global_pid;
  551. static RETSIGTYPE (*pipe_handler) (int sig);
  552. int
  553. sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
  554. {
  555. int p[2];
  556. char *argv[4];
  557. xpipe (p);
  558. pipe_handler = signal (SIGPIPE, SIG_IGN);
  559. global_pid = xfork ();
  560. if (global_pid != 0)
  561. {
  562. xclose (p[PREAD]);
  563. return p[PWRITE];
  564. }
  565. /* Child */
  566. xdup2 (p[PREAD], STDIN_FILENO);
  567. xclose (p[PWRITE]);
  568. stat_to_env (file_name, typechar, st);
  569. argv[0] = "/bin/sh";
  570. argv[1] = "-c";
  571. argv[2] = to_command_option;
  572. argv[3] = NULL;
  573. execv ("/bin/sh", argv);
  574. exec_fatal (file_name);
  575. }
  576. void
  577. sys_wait_command (void)
  578. {
  579. int status;
  580. if (global_pid < 0)
  581. return;
  582. signal (SIGPIPE, pipe_handler);
  583. while (waitpid (global_pid, &status, 0) == -1)
  584. if (errno != EINTR)
  585. {
  586. global_pid = -1;
  587. waitpid_error (to_command_option);
  588. return;
  589. }
  590. if (WIFEXITED (status))
  591. {
  592. if (!ignore_command_error_option && WEXITSTATUS (status))
  593. ERROR ((0, 0, _("%lu: Child returned status %d"),
  594. (unsigned long) global_pid, WEXITSTATUS (status)));
  595. }
  596. else if (WIFSIGNALED (status))
  597. {
  598. WARN ((0, 0, _("%lu: Child terminated on signal %d"),
  599. (unsigned long) global_pid, WTERMSIG (status)));
  600. }
  601. else
  602. ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
  603. (unsigned long) global_pid));
  604. global_pid = -1;
  605. }
  606. int
  607. sys_exec_info_script (const char **archive_name, int volume_number)
  608. {
  609. pid_t pid;
  610. char *argv[4];
  611. char uintbuf[UINTMAX_STRSIZE_BOUND];
  612. int p[2];
  613. static RETSIGTYPE (*saved_handler) (int sig);
  614. xpipe (p);
  615. saved_handler = signal (SIGPIPE, SIG_IGN);
  616. pid = xfork ();
  617. if (pid != 0)
  618. {
  619. /* Master */
  620. int rc;
  621. int status;
  622. char *buf = NULL;
  623. size_t size = 0;
  624. FILE *fp;
  625. xclose (p[PWRITE]);
  626. fp = fdopen (p[PREAD], "r");
  627. rc = getline (&buf, &size, fp);
  628. fclose (fp);
  629. if (rc > 0 && buf[rc-1] == '\n')
  630. buf[--rc] = 0;
  631. while (waitpid (pid, &status, 0) == -1)
  632. if (errno != EINTR)
  633. {
  634. signal (SIGPIPE, saved_handler);
  635. waitpid_error (info_script_option);
  636. return -1;
  637. }
  638. signal (SIGPIPE, saved_handler);
  639. if (WIFEXITED (status))
  640. {
  641. if (WEXITSTATUS (status) == 0 && rc > 0)
  642. *archive_name = buf;
  643. else
  644. free (buf);
  645. return WEXITSTATUS (status);
  646. }
  647. free (buf);
  648. return -1;
  649. }
  650. /* Child */
  651. setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  652. setenv ("TAR_ARCHIVE", *archive_name, 1);
  653. setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
  654. setenv ("TAR_BLOCKING_FACTOR",
  655. STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  656. setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  657. setenv ("TAR_FORMAT",
  658. archive_format_string (current_format == DEFAULT_FORMAT ?
  659. archive_format : current_format), 1);
  660. setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
  661. xclose (p[PREAD]);
  662. argv[0] = "/bin/sh";
  663. argv[1] = "-c";
  664. argv[2] = (char*) info_script_option;
  665. argv[3] = NULL;
  666. execv (argv[0], argv);
  667. exec_fatal (info_script_option);
  668. }
  669. void
  670. sys_exec_checkpoint_script (const char *script_name,
  671. const char *archive_name,
  672. int checkpoint_number)
  673. {
  674. pid_t pid;
  675. char *argv[4];
  676. char uintbuf[UINTMAX_STRSIZE_BOUND];
  677. pid = xfork ();
  678. if (pid != 0)
  679. {
  680. /* Master */
  681. int status;
  682. while (waitpid (pid, &status, 0) == -1)
  683. if (errno != EINTR)
  684. {
  685. waitpid_error (script_name);
  686. break;
  687. }
  688. return;
  689. }
  690. /* Child */
  691. setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  692. setenv ("TAR_ARCHIVE", archive_name, 1);
  693. setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
  694. setenv ("TAR_BLOCKING_FACTOR",
  695. STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  696. setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  697. setenv ("TAR_FORMAT",
  698. archive_format_string (current_format == DEFAULT_FORMAT ?
  699. archive_format : current_format), 1);
  700. argv[0] = "/bin/sh";
  701. argv[1] = "-c";
  702. argv[2] = (char*) script_name;
  703. argv[3] = NULL;
  704. execv (argv[0], argv);
  705. exec_fatal (script_name);
  706. }
  707. #endif /* not MSDOS */