system.c 20 KB

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