pex-common.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /* Common code for executing a program in a sub-process.
  2. Copyright (C) 2005-2022 Free Software Foundation, Inc.
  3. Written by Ian Lance Taylor <ian@airs.com>.
  4. This file is part of the libiberty library.
  5. Libiberty is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. Libiberty is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with libiberty; see the file COPYING.LIB. If not,
  15. write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
  16. Boston, MA 02110-1301, USA. */
  17. #include "config.h"
  18. #include "libiberty.h"
  19. #include "pex-common.h"
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #ifdef NEED_DECLARATION_ERRNO
  23. extern int errno;
  24. #endif
  25. #ifdef HAVE_STDLIB_H
  26. #include <stdlib.h>
  27. #endif
  28. #ifdef HAVE_STRING_H
  29. #include <string.h>
  30. #endif
  31. #ifdef HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34. extern int mkstemps (char *, int);
  35. /* This file contains subroutines for the program execution routines
  36. (pex_init, pex_run, etc.). This file is compiled on all
  37. systems. */
  38. static void pex_add_remove (struct pex_obj *, const char *, int);
  39. static int pex_get_status_and_time (struct pex_obj *, int, const char **,
  40. int *);
  41. /* Initialize a pex_obj structure. */
  42. struct pex_obj *
  43. pex_init_common (int flags, const char *pname, const char *tempbase,
  44. const struct pex_funcs *funcs)
  45. {
  46. struct pex_obj *obj;
  47. obj = XNEW (struct pex_obj);
  48. obj->flags = flags;
  49. obj->pname = pname;
  50. obj->tempbase = tempbase;
  51. obj->next_input = STDIN_FILE_NO;
  52. obj->next_input_name = NULL;
  53. obj->next_input_name_allocated = 0;
  54. obj->stderr_pipe = -1;
  55. obj->count = 0;
  56. obj->children = NULL;
  57. obj->status = NULL;
  58. obj->time = NULL;
  59. obj->number_waited = 0;
  60. obj->input_file = NULL;
  61. obj->read_output = NULL;
  62. obj->read_err = NULL;
  63. obj->remove_count = 0;
  64. obj->remove = NULL;
  65. obj->funcs = funcs;
  66. obj->sysdep = NULL;
  67. return obj;
  68. }
  69. /* Add a file to be removed when we are done. */
  70. static void
  71. pex_add_remove (struct pex_obj *obj, const char *name, int allocated)
  72. {
  73. char *add;
  74. ++obj->remove_count;
  75. obj->remove = XRESIZEVEC (char *, obj->remove, obj->remove_count);
  76. if (allocated)
  77. add = (char *) name;
  78. else
  79. add = xstrdup (name);
  80. obj->remove[obj->remove_count - 1] = add;
  81. }
  82. /* Generate a temporary file name based on OBJ, FLAGS, and NAME.
  83. Return NULL if we were unable to reserve a temporary filename.
  84. If non-NULL, the result is either allocated with malloc, or the
  85. same pointer as NAME. */
  86. static char *
  87. temp_file (struct pex_obj *obj, int flags, char *name)
  88. {
  89. if (name == NULL)
  90. {
  91. if (obj->tempbase == NULL)
  92. {
  93. name = make_temp_file (NULL);
  94. }
  95. else
  96. {
  97. int len = strlen (obj->tempbase);
  98. int out;
  99. if (len >= 6
  100. && strcmp (obj->tempbase + len - 6, "XXXXXX") == 0)
  101. name = xstrdup (obj->tempbase);
  102. else
  103. name = concat (obj->tempbase, "XXXXXX", NULL);
  104. out = mkstemps (name, 0);
  105. if (out < 0)
  106. {
  107. free (name);
  108. return NULL;
  109. }
  110. /* This isn't obj->funcs->close because we got the
  111. descriptor from mkstemps, not from a function in
  112. obj->funcs. Calling close here is just like what
  113. make_temp_file does. */
  114. close (out);
  115. }
  116. }
  117. else if ((flags & PEX_SUFFIX) != 0)
  118. {
  119. if (obj->tempbase == NULL)
  120. name = make_temp_file (name);
  121. else
  122. name = concat (obj->tempbase, name, NULL);
  123. }
  124. return name;
  125. }
  126. /* As for pex_run (), but permits the environment for the child process
  127. to be specified. */
  128. const char *
  129. pex_run_in_environment (struct pex_obj *obj, int flags, const char *executable,
  130. char * const * argv, char * const * env,
  131. const char *orig_outname, const char *errname,
  132. int *err)
  133. {
  134. const char *errmsg;
  135. int in, out, errdes;
  136. char *outname;
  137. int outname_allocated;
  138. int p[2];
  139. int toclose;
  140. pid_t pid;
  141. in = -1;
  142. out = -1;
  143. errdes = -1;
  144. outname = (char *) orig_outname;
  145. outname_allocated = 0;
  146. /* If the user called pex_input_file, close the file now. */
  147. if (obj->input_file)
  148. {
  149. if (fclose (obj->input_file) == EOF)
  150. {
  151. errmsg = "closing pipeline input file";
  152. goto error_exit;
  153. }
  154. obj->input_file = NULL;
  155. }
  156. /* Set IN. */
  157. if (obj->next_input_name != NULL)
  158. {
  159. /* We have to make sure that the previous process has completed
  160. before we try to read the file. */
  161. if (!pex_get_status_and_time (obj, 0, &errmsg, err))
  162. goto error_exit;
  163. in = obj->funcs->open_read (obj, obj->next_input_name,
  164. (flags & PEX_BINARY_INPUT) != 0);
  165. if (in < 0)
  166. {
  167. *err = errno;
  168. errmsg = "open temporary file";
  169. goto error_exit;
  170. }
  171. if (obj->next_input_name_allocated)
  172. {
  173. free (obj->next_input_name);
  174. obj->next_input_name_allocated = 0;
  175. }
  176. obj->next_input_name = NULL;
  177. }
  178. else
  179. {
  180. in = obj->next_input;
  181. if (in < 0)
  182. {
  183. *err = 0;
  184. errmsg = "pipeline already complete";
  185. goto error_exit;
  186. }
  187. }
  188. /* Set OUT and OBJ->NEXT_INPUT/OBJ->NEXT_INPUT_NAME. */
  189. if ((flags & PEX_LAST) != 0)
  190. {
  191. if (outname == NULL)
  192. out = STDOUT_FILE_NO;
  193. else if ((flags & PEX_SUFFIX) != 0)
  194. {
  195. outname = concat (obj->tempbase, outname, NULL);
  196. outname_allocated = 1;
  197. }
  198. obj->next_input = -1;
  199. }
  200. else if ((obj->flags & PEX_USE_PIPES) == 0)
  201. {
  202. outname = temp_file (obj, flags, outname);
  203. if (! outname)
  204. {
  205. *err = 0;
  206. errmsg = "could not create temporary file";
  207. goto error_exit;
  208. }
  209. if (outname != orig_outname)
  210. outname_allocated = 1;
  211. if ((obj->flags & PEX_SAVE_TEMPS) == 0)
  212. {
  213. pex_add_remove (obj, outname, outname_allocated);
  214. outname_allocated = 0;
  215. }
  216. /* Hand off ownership of outname to the next stage. */
  217. obj->next_input_name = outname;
  218. obj->next_input_name_allocated = outname_allocated;
  219. outname_allocated = 0;
  220. }
  221. else
  222. {
  223. if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_OUTPUT) != 0) < 0)
  224. {
  225. *err = errno;
  226. errmsg = "pipe";
  227. goto error_exit;
  228. }
  229. out = p[WRITE_PORT];
  230. obj->next_input = p[READ_PORT];
  231. }
  232. if (out < 0)
  233. {
  234. out = obj->funcs->open_write (obj, outname,
  235. (flags & PEX_BINARY_OUTPUT) != 0,
  236. (flags & PEX_STDOUT_APPEND) != 0);
  237. if (out < 0)
  238. {
  239. *err = errno;
  240. errmsg = "open temporary output file";
  241. goto error_exit;
  242. }
  243. }
  244. if (outname_allocated)
  245. {
  246. free (outname);
  247. outname_allocated = 0;
  248. }
  249. /* Set ERRDES. */
  250. if (errname != NULL && (flags & PEX_STDERR_TO_PIPE) != 0)
  251. {
  252. *err = 0;
  253. errmsg = "both ERRNAME and PEX_STDERR_TO_PIPE specified.";
  254. goto error_exit;
  255. }
  256. if (obj->stderr_pipe != -1)
  257. {
  258. *err = 0;
  259. errmsg = "PEX_STDERR_TO_PIPE used in the middle of pipeline";
  260. goto error_exit;
  261. }
  262. if (errname == NULL)
  263. {
  264. if (flags & PEX_STDERR_TO_PIPE)
  265. {
  266. if (obj->funcs->pipe (obj, p, (flags & PEX_BINARY_ERROR) != 0) < 0)
  267. {
  268. *err = errno;
  269. errmsg = "pipe";
  270. goto error_exit;
  271. }
  272. errdes = p[WRITE_PORT];
  273. obj->stderr_pipe = p[READ_PORT];
  274. }
  275. else
  276. {
  277. errdes = STDERR_FILE_NO;
  278. }
  279. }
  280. else
  281. {
  282. errdes = obj->funcs->open_write (obj, errname,
  283. (flags & PEX_BINARY_ERROR) != 0,
  284. (flags & PEX_STDERR_APPEND) != 0);
  285. if (errdes < 0)
  286. {
  287. *err = errno;
  288. errmsg = "open error file";
  289. goto error_exit;
  290. }
  291. }
  292. /* If we are using pipes, the child process has to close the next
  293. input pipe. */
  294. if ((obj->flags & PEX_USE_PIPES) == 0)
  295. toclose = -1;
  296. else
  297. toclose = obj->next_input;
  298. /* Run the program. */
  299. pid = obj->funcs->exec_child (obj, flags, executable, argv, env,
  300. in, out, errdes, toclose, &errmsg, err);
  301. if (pid < 0)
  302. goto error_exit;
  303. ++obj->count;
  304. obj->children = XRESIZEVEC (pid_t, obj->children, obj->count);
  305. obj->children[obj->count - 1] = pid;
  306. return NULL;
  307. error_exit:
  308. if (in >= 0 && in != STDIN_FILE_NO)
  309. obj->funcs->close (obj, in);
  310. if (out >= 0 && out != STDOUT_FILE_NO)
  311. obj->funcs->close (obj, out);
  312. if (errdes >= 0 && errdes != STDERR_FILE_NO)
  313. obj->funcs->close (obj, errdes);
  314. if (outname_allocated)
  315. free (outname);
  316. return errmsg;
  317. }
  318. /* Run a program. */
  319. const char *
  320. pex_run (struct pex_obj *obj, int flags, const char *executable,
  321. char * const * argv, const char *orig_outname, const char *errname,
  322. int *err)
  323. {
  324. return pex_run_in_environment (obj, flags, executable, argv, NULL,
  325. orig_outname, errname, err);
  326. }
  327. /* Return a FILE pointer for a temporary file to fill with input for
  328. the pipeline. */
  329. FILE *
  330. pex_input_file (struct pex_obj *obj, int flags, const char *in_name)
  331. {
  332. char *name = (char *) in_name;
  333. FILE *f;
  334. /* This must be called before the first pipeline stage is run, and
  335. there must not have been any other input selected. */
  336. if (obj->count != 0
  337. || (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
  338. || obj->next_input_name)
  339. {
  340. errno = EINVAL;
  341. return NULL;
  342. }
  343. name = temp_file (obj, flags, name);
  344. if (! name)
  345. return NULL;
  346. f = fopen (name, (flags & PEX_BINARY_OUTPUT) ? "wb" : "w");
  347. if (! f)
  348. {
  349. free (name);
  350. return NULL;
  351. }
  352. obj->input_file = f;
  353. obj->next_input_name = name;
  354. obj->next_input_name_allocated = (name != in_name);
  355. return f;
  356. }
  357. /* Return a stream for a pipe connected to the standard input of the
  358. first stage of the pipeline. */
  359. FILE *
  360. pex_input_pipe (struct pex_obj *obj, int binary)
  361. {
  362. int p[2];
  363. FILE *f;
  364. /* You must call pex_input_pipe before the first pex_run or pex_one. */
  365. if (obj->count > 0)
  366. goto usage_error;
  367. /* You must be using pipes. Implementations that don't support
  368. pipes clear this flag before calling pex_init_common. */
  369. if (! (obj->flags & PEX_USE_PIPES))
  370. goto usage_error;
  371. /* If we have somehow already selected other input, that's a
  372. mistake. */
  373. if ((obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
  374. || obj->next_input_name)
  375. goto usage_error;
  376. if (obj->funcs->pipe (obj, p, binary != 0) < 0)
  377. return NULL;
  378. f = obj->funcs->fdopenw (obj, p[WRITE_PORT], binary != 0);
  379. if (! f)
  380. {
  381. int saved_errno = errno;
  382. obj->funcs->close (obj, p[READ_PORT]);
  383. obj->funcs->close (obj, p[WRITE_PORT]);
  384. errno = saved_errno;
  385. return NULL;
  386. }
  387. obj->next_input = p[READ_PORT];
  388. return f;
  389. usage_error:
  390. errno = EINVAL;
  391. return NULL;
  392. }
  393. /* Return a FILE pointer for the output of the last program
  394. executed. */
  395. FILE *
  396. pex_read_output (struct pex_obj *obj, int binary)
  397. {
  398. if (obj->next_input_name != NULL)
  399. {
  400. const char *errmsg;
  401. int err;
  402. /* We have to make sure that the process has completed before we
  403. try to read the file. */
  404. if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
  405. {
  406. errno = err;
  407. return NULL;
  408. }
  409. obj->read_output = fopen (obj->next_input_name, binary ? "rb" : "r");
  410. if (obj->next_input_name_allocated)
  411. {
  412. free (obj->next_input_name);
  413. obj->next_input_name_allocated = 0;
  414. }
  415. obj->next_input_name = NULL;
  416. }
  417. else
  418. {
  419. int o;
  420. o = obj->next_input;
  421. if (o < 0 || o == STDIN_FILE_NO)
  422. return NULL;
  423. obj->read_output = obj->funcs->fdopenr (obj, o, binary);
  424. obj->next_input = -1;
  425. }
  426. return obj->read_output;
  427. }
  428. FILE *
  429. pex_read_err (struct pex_obj *obj, int binary)
  430. {
  431. int o;
  432. o = obj->stderr_pipe;
  433. if (o < 0 || o == STDIN_FILE_NO)
  434. return NULL;
  435. obj->read_err = obj->funcs->fdopenr (obj, o, binary);
  436. obj->stderr_pipe = -1;
  437. return obj->read_err;
  438. }
  439. /* Get the exit status and, if requested, the resource time for all
  440. the child processes. Return 0 on failure, 1 on success. */
  441. static int
  442. pex_get_status_and_time (struct pex_obj *obj, int done, const char **errmsg,
  443. int *err)
  444. {
  445. int ret;
  446. int i;
  447. if (obj->number_waited == obj->count)
  448. return 1;
  449. obj->status = XRESIZEVEC (int, obj->status, obj->count);
  450. if ((obj->flags & PEX_RECORD_TIMES) != 0)
  451. obj->time = XRESIZEVEC (struct pex_time, obj->time, obj->count);
  452. ret = 1;
  453. for (i = obj->number_waited; i < obj->count; ++i)
  454. {
  455. if (obj->funcs->wait (obj, obj->children[i], &obj->status[i],
  456. obj->time == NULL ? NULL : &obj->time[i],
  457. done, errmsg, err) < 0)
  458. ret = 0;
  459. }
  460. obj->number_waited = i;
  461. return ret;
  462. }
  463. /* Get exit status of executed programs. */
  464. int
  465. pex_get_status (struct pex_obj *obj, int count, int *vector)
  466. {
  467. if (obj->status == NULL)
  468. {
  469. const char *errmsg;
  470. int err;
  471. if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
  472. return 0;
  473. }
  474. if (count > obj->count)
  475. {
  476. memset (vector + obj->count, 0, (count - obj->count) * sizeof (int));
  477. count = obj->count;
  478. }
  479. memcpy (vector, obj->status, count * sizeof (int));
  480. return 1;
  481. }
  482. /* Get process times of executed programs. */
  483. int
  484. pex_get_times (struct pex_obj *obj, int count, struct pex_time *vector)
  485. {
  486. if (obj->status == NULL)
  487. {
  488. const char *errmsg;
  489. int err;
  490. if (!pex_get_status_and_time (obj, 0, &errmsg, &err))
  491. return 0;
  492. }
  493. if (obj->time == NULL)
  494. return 0;
  495. if (count > obj->count)
  496. {
  497. memset (vector + obj->count, 0,
  498. (count - obj->count) * sizeof (struct pex_time));
  499. count = obj->count;
  500. }
  501. memcpy (vector, obj->time, count * sizeof (struct pex_time));
  502. return 1;
  503. }
  504. /* Free a pex_obj structure. */
  505. void
  506. pex_free (struct pex_obj *obj)
  507. {
  508. /* Close pipe file descriptors corresponding to child's stdout and
  509. stderr so that the child does not hang trying to output something
  510. while we're waiting for it. */
  511. if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
  512. obj->funcs->close (obj, obj->next_input);
  513. if (obj->stderr_pipe >= 0 && obj->stderr_pipe != STDIN_FILE_NO)
  514. obj->funcs->close (obj, obj->stderr_pipe);
  515. if (obj->read_output != NULL)
  516. fclose (obj->read_output);
  517. if (obj->read_err != NULL)
  518. fclose (obj->read_err);
  519. /* If the caller forgot to wait for the children, we do it here, to
  520. avoid zombies. */
  521. if (obj->status == NULL)
  522. {
  523. const char *errmsg;
  524. int err;
  525. obj->flags &= ~ PEX_RECORD_TIMES;
  526. pex_get_status_and_time (obj, 1, &errmsg, &err);
  527. }
  528. if (obj->next_input_name_allocated)
  529. free (obj->next_input_name);
  530. free (obj->children);
  531. free (obj->status);
  532. free (obj->time);
  533. if (obj->remove_count > 0)
  534. {
  535. int i;
  536. for (i = 0; i < obj->remove_count; ++i)
  537. {
  538. remove (obj->remove[i]);
  539. free (obj->remove[i]);
  540. }
  541. free (obj->remove);
  542. }
  543. if (obj->funcs->cleanup != NULL)
  544. obj->funcs->cleanup (obj);
  545. free (obj);
  546. }