posix_spawn.m4 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. # posix_spawn.m4 serial 22
  2. dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
  3. dnl This file is free software; the Free Software Foundation
  4. dnl gives unlimited permission to copy and/or distribute it,
  5. dnl with or without modifications, as long as this notice is preserved.
  6. dnl Tests whether the entire posix_spawn facility is available.
  7. AC_DEFUN([gl_POSIX_SPAWN],
  8. [
  9. AC_REQUIRE([gl_POSIX_SPAWN_BODY])
  10. ])
  11. AC_DEFUN([gl_POSIX_SPAWN_BODY],
  12. [
  13. AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
  14. AC_REQUIRE([gl_HAVE_POSIX_SPAWN])
  15. dnl Assume that when the main function exists, all the others,
  16. dnl except posix_spawnattr_{get,set}sched*, are available as well.
  17. dnl AC_CHECK_FUNCS_ONCE([posix_spawnp])
  18. dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_init])
  19. dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addclose])
  20. dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_adddup2])
  21. dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addopen])
  22. dnl AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_destroy])
  23. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_init])
  24. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getflags])
  25. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setflags])
  26. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getpgroup])
  27. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setpgroup])
  28. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getsigdefault])
  29. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setsigdefault])
  30. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getsigmask])
  31. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setsigmask])
  32. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_destroy])
  33. AC_CHECK_DECLS([posix_spawn], , , [[#include <spawn.h>]])
  34. if test $ac_cv_func_posix_spawn = yes; then
  35. m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR],
  36. [dnl Module 'posix_spawn_file_actions_addchdir' is present.
  37. AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addchdir_np])
  38. if test $ac_cv_func_posix_spawn_file_actions_addchdir_np = no; then
  39. dnl In order to implement the posix_spawn_file_actions_addchdir
  40. dnl function, we need to replace the entire posix_spawn facility.
  41. REPLACE_POSIX_SPAWN=1
  42. fi
  43. ])
  44. m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR],
  45. [dnl Module 'posix_spawn_file_actions_addfchdir' is present.
  46. AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir_np])
  47. if test $ac_cv_func_posix_spawn_file_actions_addfchdir_np = no; then
  48. dnl In order to implement the posix_spawn_file_actions_addfchdir
  49. dnl function, we need to replace the entire posix_spawn facility.
  50. REPLACE_POSIX_SPAWN=1
  51. fi
  52. ])
  53. if test $REPLACE_POSIX_SPAWN = 0; then
  54. gl_POSIX_SPAWN_WORKS
  55. case "$gl_cv_func_posix_spawn_works" in
  56. *yes) ;;
  57. *) REPLACE_POSIX_SPAWN=1 ;;
  58. esac
  59. fi
  60. if test $REPLACE_POSIX_SPAWN = 0; then
  61. gl_POSIX_SPAWN_SECURE
  62. case "$gl_cv_func_posix_spawn_secure_exec" in
  63. *yes) ;;
  64. *) REPLACE_POSIX_SPAWN=1 ;;
  65. esac
  66. case "$gl_cv_func_posix_spawnp_secure_exec" in
  67. *yes) ;;
  68. *) REPLACE_POSIX_SPAWN=1 ;;
  69. esac
  70. fi
  71. if test $REPLACE_POSIX_SPAWN = 0; then
  72. dnl Assume that these functions are available if POSIX_SPAWN_SETSCHEDULER
  73. dnl evaluates to nonzero.
  74. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getschedpolicy])
  75. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setschedpolicy])
  76. AC_CACHE_CHECK([whether posix_spawnattr_setschedpolicy is supported],
  77. [gl_cv_func_spawnattr_setschedpolicy],
  78. [AC_EGREP_CPP([POSIX scheduling supported], [
  79. #include <spawn.h>
  80. #if POSIX_SPAWN_SETSCHEDULER
  81. POSIX scheduling supported
  82. #endif
  83. ],
  84. [gl_cv_func_spawnattr_setschedpolicy=yes],
  85. [gl_cv_func_spawnattr_setschedpolicy=no])
  86. ])
  87. dnl Assume that these functions are available if POSIX_SPAWN_SETSCHEDPARAM
  88. dnl evaluates to nonzero.
  89. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_getschedparam])
  90. dnl AC_CHECK_FUNCS_ONCE([posix_spawnattr_setschedparam])
  91. AC_CACHE_CHECK([whether posix_spawnattr_setschedparam is supported],
  92. [gl_cv_func_spawnattr_setschedparam],
  93. [AC_EGREP_CPP([POSIX scheduling supported], [
  94. #include <spawn.h>
  95. #if POSIX_SPAWN_SETSCHEDPARAM
  96. POSIX scheduling supported
  97. #endif
  98. ],
  99. [gl_cv_func_spawnattr_setschedparam=yes],
  100. [gl_cv_func_spawnattr_setschedparam=no])
  101. ])
  102. fi
  103. else
  104. dnl The system does not have the main function. Therefore we have to
  105. dnl provide our own implementation. This implies to define our own
  106. dnl posix_spawn_file_actions_t and posix_spawnattr_t types.
  107. if test $ac_cv_have_decl_posix_spawn = yes; then
  108. dnl The system declares posix_spawn() already. This declaration uses
  109. dnl the original posix_spawn_file_actions_t and posix_spawnattr_t types.
  110. dnl But we need a declaration with our own posix_spawn_file_actions_t and
  111. dnl posix_spawnattr_t types.
  112. REPLACE_POSIX_SPAWN=1
  113. fi
  114. fi
  115. if test $ac_cv_func_posix_spawn != yes || test $REPLACE_POSIX_SPAWN = 1; then
  116. AC_DEFINE([REPLACE_POSIX_SPAWN], [1],
  117. [Define if gnulib uses its own posix_spawn and posix_spawnp functions.])
  118. fi
  119. ])
  120. dnl Test whether posix_spawn actually works.
  121. dnl posix_spawn on AIX 5.3..6.1 has two bugs:
  122. dnl 1) When it fails to execute the program, the child process exits with
  123. dnl exit() rather than _exit(), which causes the stdio buffers to be
  124. dnl flushed. Reported by Rainer Tammer.
  125. dnl 2) The posix_spawn_file_actions_addopen function does not support file
  126. dnl names that contain a '*'.
  127. dnl posix_spawn on AIX 5.3..6.1 has also a third bug: It does not work
  128. dnl when POSIX threads are used. But we don't test against this bug here.
  129. AC_DEFUN([gl_POSIX_SPAWN_WORKS],
  130. [
  131. AC_REQUIRE([AC_PROG_CC])
  132. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  133. AC_CACHE_CHECK([whether posix_spawn works], [gl_cv_func_posix_spawn_works],
  134. [if test $cross_compiling = no; then
  135. AC_LINK_IFELSE([AC_LANG_SOURCE([[
  136. #include <errno.h>
  137. #include <fcntl.h>
  138. #include <signal.h>
  139. #include <spawn.h>
  140. #include <stdbool.h>
  141. #include <stdio.h>
  142. #include <stdlib.h>
  143. #include <string.h>
  144. #include <unistd.h>
  145. #include <sys/types.h>
  146. #include <sys/wait.h>
  147. ]GL_MDA_DEFINES[
  148. extern char **environ;
  149. #ifndef STDIN_FILENO
  150. # define STDIN_FILENO 0
  151. #endif
  152. #ifndef STDOUT_FILENO
  153. # define STDOUT_FILENO 1
  154. #endif
  155. #ifndef STDERR_FILENO
  156. # define STDERR_FILENO 2
  157. #endif
  158. #ifndef WTERMSIG
  159. # define WTERMSIG(x) ((x) & 0x7f)
  160. #endif
  161. #ifndef WIFEXITED
  162. # define WIFEXITED(x) (WTERMSIG (x) == 0)
  163. #endif
  164. #ifndef WEXITSTATUS
  165. # define WEXITSTATUS(x) (((x) >> 8) & 0xff)
  166. #endif
  167. #define CHILD_PROGRAM_FILENAME "/non/exist/ent"
  168. static int
  169. fd_safer (int fd)
  170. {
  171. if (0 <= fd && fd <= 2)
  172. {
  173. int f = fd_safer (dup (fd));
  174. int e = errno;
  175. close (fd);
  176. errno = e;
  177. fd = f;
  178. }
  179. return fd;
  180. }
  181. int
  182. main ()
  183. {
  184. char *argv[2] = { CHILD_PROGRAM_FILENAME, NULL };
  185. int ofd[2];
  186. sigset_t blocked_signals;
  187. sigset_t fatal_signal_set;
  188. posix_spawn_file_actions_t actions;
  189. bool actions_allocated;
  190. posix_spawnattr_t attrs;
  191. bool attrs_allocated;
  192. int err;
  193. pid_t child;
  194. int status;
  195. int exitstatus;
  196. setvbuf (stdout, NULL, _IOFBF, 0);
  197. puts ("This should be seen only once.");
  198. if (pipe (ofd) < 0 || (ofd[1] = fd_safer (ofd[1])) < 0)
  199. {
  200. perror ("cannot create pipe");
  201. exit (1);
  202. }
  203. sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
  204. sigemptyset (&fatal_signal_set);
  205. sigaddset (&fatal_signal_set, SIGINT);
  206. sigaddset (&fatal_signal_set, SIGTERM);
  207. sigaddset (&fatal_signal_set, SIGHUP);
  208. sigaddset (&fatal_signal_set, SIGPIPE);
  209. sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
  210. actions_allocated = false;
  211. attrs_allocated = false;
  212. if ((err = posix_spawn_file_actions_init (&actions)) != 0
  213. || (actions_allocated = true,
  214. (err = posix_spawn_file_actions_adddup2 (&actions, ofd[0], STDIN_FILENO)) != 0
  215. || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0
  216. || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
  217. || (err = posix_spawnattr_init (&attrs)) != 0
  218. || (attrs_allocated = true,
  219. (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
  220. || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
  221. || (err = posix_spawnp (&child, CHILD_PROGRAM_FILENAME, &actions, &attrs, argv, environ)) != 0))
  222. {
  223. if (actions_allocated)
  224. posix_spawn_file_actions_destroy (&actions);
  225. if (attrs_allocated)
  226. posix_spawnattr_destroy (&attrs);
  227. sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
  228. if (err == ENOENT)
  229. return 0;
  230. else
  231. {
  232. errno = err;
  233. perror ("subprocess failed");
  234. exit (1);
  235. }
  236. }
  237. posix_spawn_file_actions_destroy (&actions);
  238. posix_spawnattr_destroy (&attrs);
  239. sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
  240. close (ofd[0]);
  241. close (ofd[1]);
  242. status = 0;
  243. while (waitpid (child, &status, 0) != child)
  244. ;
  245. if (!WIFEXITED (status))
  246. {
  247. fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
  248. exit (1);
  249. }
  250. exitstatus = WEXITSTATUS (status);
  251. if (exitstatus != 127)
  252. {
  253. fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
  254. exit (1);
  255. }
  256. return 0;
  257. }
  258. ]])],
  259. [if test -s conftest$ac_exeext \
  260. && ./conftest$ac_exeext > conftest.out \
  261. && echo 'This should be seen only once.' > conftest.ok \
  262. && cmp conftest.out conftest.ok >/dev/null 2>&1; then
  263. gl_cv_func_posix_spawn_works=yes
  264. else
  265. gl_cv_func_posix_spawn_works=no
  266. fi],
  267. [gl_cv_func_posix_spawn_works=no])
  268. if test $gl_cv_func_posix_spawn_works = yes; then
  269. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  270. /* Test whether posix_spawn_file_actions_addopen supports filename arguments
  271. that contain special characters such as '*'. */
  272. #include <errno.h>
  273. #include <fcntl.h>
  274. #include <signal.h>
  275. #include <spawn.h>
  276. #include <stdbool.h>
  277. #include <stdio.h>
  278. #include <string.h>
  279. #include <unistd.h>
  280. #include <sys/types.h>
  281. #include <sys/wait.h>
  282. ]GL_MDA_DEFINES[
  283. extern char **environ;
  284. #ifndef STDIN_FILENO
  285. # define STDIN_FILENO 0
  286. #endif
  287. #ifndef STDOUT_FILENO
  288. # define STDOUT_FILENO 1
  289. #endif
  290. #ifndef STDERR_FILENO
  291. # define STDERR_FILENO 2
  292. #endif
  293. #ifndef WTERMSIG
  294. # define WTERMSIG(x) ((x) & 0x7f)
  295. #endif
  296. #ifndef WIFEXITED
  297. # define WIFEXITED(x) (WTERMSIG (x) == 0)
  298. #endif
  299. #ifndef WEXITSTATUS
  300. # define WEXITSTATUS(x) (((x) >> 8) & 0xff)
  301. #endif
  302. #define CHILD_PROGRAM_FILENAME "conftest"
  303. #define DATA_FILENAME "conftest%=*#?"
  304. static int
  305. parent_main (void)
  306. {
  307. FILE *fp;
  308. char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
  309. posix_spawn_file_actions_t actions;
  310. bool actions_allocated;
  311. int err;
  312. pid_t child;
  313. int status;
  314. int exitstatus;
  315. /* Create a data file with specific contents. */
  316. fp = fopen (DATA_FILENAME, "wb");
  317. if (fp == NULL)
  318. {
  319. perror ("cannot create data file");
  320. return 1;
  321. }
  322. fwrite ("Halle Potta", 1, 11, fp);
  323. if (fflush (fp) || fclose (fp))
  324. {
  325. perror ("cannot prepare data file");
  326. return 2;
  327. }
  328. /* Avoid reading from our stdin, as it could block. */
  329. freopen ("/dev/null", "rb", stdin);
  330. /* Test whether posix_spawn_file_actions_addopen with this file name
  331. actually works, but spawning a child that reads from this file. */
  332. actions_allocated = false;
  333. if ((err = posix_spawn_file_actions_init (&actions)) != 0
  334. || (actions_allocated = true,
  335. (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, DATA_FILENAME, O_RDONLY, 0600)) != 0
  336. || (err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, &actions, NULL, argv, environ)) != 0))
  337. {
  338. if (actions_allocated)
  339. posix_spawn_file_actions_destroy (&actions);
  340. errno = err;
  341. perror ("subprocess failed");
  342. return 3;
  343. }
  344. posix_spawn_file_actions_destroy (&actions);
  345. status = 0;
  346. while (waitpid (child, &status, 0) != child)
  347. ;
  348. if (!WIFEXITED (status))
  349. {
  350. fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
  351. return 4;
  352. }
  353. exitstatus = WEXITSTATUS (status);
  354. if (exitstatus != 0)
  355. {
  356. fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
  357. return 5;
  358. }
  359. return 0;
  360. }
  361. static int
  362. child_main (void)
  363. {
  364. char buf[1024];
  365. /* See if reading from STDIN_FILENO yields the expected contents. */
  366. if (fread (buf, 1, sizeof (buf), stdin) == 11
  367. && memcmp (buf, "Halle Potta", 11) == 0)
  368. return 0;
  369. else
  370. return 8;
  371. }
  372. static void
  373. cleanup_then_die (int sig)
  374. {
  375. /* Clean up data file. */
  376. unlink (DATA_FILENAME);
  377. /* Re-raise the signal and die from it. */
  378. signal (sig, SIG_DFL);
  379. raise (sig);
  380. }
  381. int
  382. main (int argc, char *argv[])
  383. {
  384. int exitstatus;
  385. if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
  386. {
  387. /* This is the parent process. */
  388. signal (SIGINT, cleanup_then_die);
  389. signal (SIGTERM, cleanup_then_die);
  390. #ifdef SIGHUP
  391. signal (SIGHUP, cleanup_then_die);
  392. #endif
  393. exitstatus = parent_main ();
  394. }
  395. else
  396. {
  397. /* This is the child process. */
  398. exitstatus = child_main ();
  399. }
  400. unlink (DATA_FILENAME);
  401. return exitstatus;
  402. }
  403. ]])],
  404. [],
  405. [gl_cv_func_posix_spawn_works=no])
  406. fi
  407. else
  408. case "$host_os" in
  409. aix*) gl_cv_func_posix_spawn_works="guessing no";;
  410. *) gl_cv_func_posix_spawn_works="guessing yes";;
  411. esac
  412. fi
  413. ])
  414. ])
  415. dnl Test whether posix_spawn and posix_spawnp are secure.
  416. AC_DEFUN([gl_POSIX_SPAWN_SECURE],
  417. [
  418. AC_REQUIRE([AC_PROG_CC])
  419. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  420. dnl On many platforms, posix_spawn or posix_spawnp allow executing a
  421. dnl script without a '#!' marker as a shell script. This is unsecure.
  422. AC_CACHE_CHECK([whether posix_spawn rejects scripts without shebang],
  423. [gl_cv_func_posix_spawn_secure_exec],
  424. [echo ':' > conftest.scr
  425. chmod a+x conftest.scr
  426. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  427. #include <errno.h>
  428. #include <spawn.h>
  429. #include <stddef.h>
  430. #include <sys/types.h>
  431. #include <sys/wait.h>
  432. int
  433. main ()
  434. {
  435. const char *prog_path = "./conftest.scr";
  436. const char *prog_argv[2] = { prog_path, NULL };
  437. const char *environment[2] = { "PATH=.", NULL };
  438. pid_t child;
  439. int status;
  440. int err = posix_spawn (&child, prog_path, NULL, NULL,
  441. (char **) prog_argv, (char **) environment);
  442. if (err == ENOEXEC)
  443. return 0;
  444. if (err != 0)
  445. return 1;
  446. status = 0;
  447. while (waitpid (child, &status, 0) != child)
  448. ;
  449. if (!WIFEXITED (status))
  450. return 2;
  451. if (WEXITSTATUS (status) != 127)
  452. return 3;
  453. return 0;
  454. }
  455. ]])],
  456. [gl_cv_func_posix_spawn_secure_exec=yes],
  457. [gl_cv_func_posix_spawn_secure_exec=no],
  458. [case "$host_os" in
  459. # Guess no on GNU/Hurd.
  460. gnu*)
  461. gl_cv_func_posix_spawn_secure_exec="guessing no" ;;
  462. # Guess yes on all other platforms.
  463. *)
  464. gl_cv_func_posix_spawn_secure_exec="guessing yes" ;;
  465. esac
  466. ])
  467. rm -f conftest.scr
  468. ])
  469. AC_CACHE_CHECK([whether posix_spawnp rejects scripts without shebang],
  470. [gl_cv_func_posix_spawnp_secure_exec],
  471. [echo ':' > conftest.scr
  472. chmod a+x conftest.scr
  473. AC_RUN_IFELSE([AC_LANG_SOURCE([[
  474. #include <errno.h>
  475. #include <spawn.h>
  476. #include <stddef.h>
  477. #include <sys/types.h>
  478. #include <sys/wait.h>
  479. int
  480. main ()
  481. {
  482. const char *prog_path = "./conftest.scr";
  483. const char *prog_argv[2] = { prog_path, NULL };
  484. const char *environment[2] = { "PATH=.", NULL };
  485. pid_t child;
  486. int status;
  487. int err = posix_spawnp (&child, prog_path, NULL, NULL,
  488. (char **) prog_argv, (char **) environment);
  489. if (err == ENOEXEC)
  490. return 0;
  491. if (err != 0)
  492. return 1;
  493. status = 0;
  494. while (waitpid (child, &status, 0) != child)
  495. ;
  496. if (!WIFEXITED (status))
  497. return 2;
  498. if (WEXITSTATUS (status) != 127)
  499. return 3;
  500. return 0;
  501. }
  502. ]])],
  503. [gl_cv_func_posix_spawnp_secure_exec=yes],
  504. [gl_cv_func_posix_spawnp_secure_exec=no],
  505. [case "$host_os" in
  506. # Guess yes on glibc systems (glibc >= 2.15 actually) except GNU/Hurd,
  507. # musl libc, NetBSD.
  508. *-gnu* | *-musl* | netbsd*)
  509. gl_cv_func_posix_spawnp_secure_exec="guessing yes" ;;
  510. # Guess no on GNU/Hurd, macOS, FreeBSD, OpenBSD, AIX, Solaris, Cygwin.
  511. gnu* | darwin* | freebsd* | dragonfly* | midnightbsd* | openbsd* | \
  512. aix* | solaris* | cygwin*)
  513. gl_cv_func_posix_spawnp_secure_exec="guessing no" ;;
  514. # If we don't know, obey --enable-cross-guesses.
  515. *)
  516. gl_cv_func_posix_spawnp_secure_exec="$gl_cross_guess_normal" ;;
  517. esac
  518. ])
  519. rm -f conftest.scr
  520. ])
  521. ])
  522. # Prerequisites of lib/spawni.c.
  523. AC_DEFUN([gl_PREREQ_POSIX_SPAWN_INTERNAL],
  524. [
  525. AC_CHECK_HEADERS([paths.h])
  526. AC_CHECK_FUNCS([confstr sched_setparam sched_setscheduler setegid seteuid vfork])
  527. ])
  528. AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE],
  529. [
  530. AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
  531. AC_REQUIRE([AC_PROG_CC])
  532. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  533. gl_POSIX_SPAWN
  534. if test $REPLACE_POSIX_SPAWN = 1; then
  535. REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=1
  536. else
  537. dnl On musl libc, posix_spawn_file_actions_addclose succeeds even if the fd
  538. dnl argument is negative.
  539. AC_CACHE_CHECK([whether posix_spawn_file_actions_addclose works],
  540. [gl_cv_func_posix_spawn_file_actions_addclose_works],
  541. [AC_RUN_IFELSE(
  542. [AC_LANG_SOURCE([[
  543. #include <spawn.h>
  544. int main ()
  545. {
  546. posix_spawn_file_actions_t actions;
  547. if (posix_spawn_file_actions_init (&actions) != 0)
  548. return 1;
  549. if (posix_spawn_file_actions_addclose (&actions, -5) == 0)
  550. return 2;
  551. return 0;
  552. }]])],
  553. [gl_cv_func_posix_spawn_file_actions_addclose_works=yes],
  554. [gl_cv_func_posix_spawn_file_actions_addclose_works=no],
  555. [# Guess no on musl libc and Solaris, yes otherwise.
  556. case "$host_os" in
  557. *-musl*) gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
  558. solaris*) gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
  559. # Guess no on native Windows.
  560. mingw*) gl_cv_func_posix_spawn_file_actions_addclose_works="guessing no" ;;
  561. *) gl_cv_func_posix_spawn_file_actions_addclose_works="guessing yes" ;;
  562. esac
  563. ])
  564. ])
  565. case "$gl_cv_func_posix_spawn_file_actions_addclose_works" in
  566. *yes) ;;
  567. *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=1 ;;
  568. esac
  569. fi
  570. ])
  571. AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2],
  572. [
  573. AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
  574. AC_REQUIRE([AC_PROG_CC])
  575. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  576. gl_POSIX_SPAWN
  577. if test $REPLACE_POSIX_SPAWN = 1; then
  578. REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1
  579. else
  580. dnl On musl libc and Solaris 11.0, posix_spawn_file_actions_adddup2
  581. dnl succeeds even if the fd argument is out of range.
  582. AC_CACHE_CHECK([whether posix_spawn_file_actions_adddup2 works],
  583. [gl_cv_func_posix_spawn_file_actions_adddup2_works],
  584. [AC_RUN_IFELSE(
  585. [AC_LANG_SOURCE([[
  586. #include <spawn.h>
  587. int main ()
  588. {
  589. posix_spawn_file_actions_t actions;
  590. if (posix_spawn_file_actions_init (&actions) != 0)
  591. return 1;
  592. if (posix_spawn_file_actions_adddup2 (&actions, 10000000, 2) == 0)
  593. return 2;
  594. return 0;
  595. }]])],
  596. [gl_cv_func_posix_spawn_file_actions_adddup2_works=yes],
  597. [gl_cv_func_posix_spawn_file_actions_adddup2_works=no],
  598. [# Guess no on musl libc and Solaris, yes otherwise.
  599. case "$host_os" in
  600. *-musl*) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no";;
  601. solaris*) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no";;
  602. # Guess no on native Windows.
  603. mingw*) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing no" ;;
  604. *) gl_cv_func_posix_spawn_file_actions_adddup2_works="guessing yes";;
  605. esac
  606. ])
  607. ])
  608. case "$gl_cv_func_posix_spawn_file_actions_adddup2_works" in
  609. *yes) ;;
  610. *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=1 ;;
  611. esac
  612. fi
  613. ])
  614. AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN],
  615. [
  616. AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
  617. AC_REQUIRE([AC_PROG_CC])
  618. AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
  619. gl_POSIX_SPAWN
  620. if test $REPLACE_POSIX_SPAWN = 1; then
  621. REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=1
  622. else
  623. dnl On musl libc and Solaris 11.0, posix_spawn_file_actions_addopen
  624. dnl succeeds even if the fd argument is out of range.
  625. AC_CACHE_CHECK([whether posix_spawn_file_actions_addopen works],
  626. [gl_cv_func_posix_spawn_file_actions_addopen_works],
  627. [AC_RUN_IFELSE(
  628. [AC_LANG_SOURCE([[
  629. #include <spawn.h>
  630. #include <fcntl.h>
  631. int main ()
  632. {
  633. posix_spawn_file_actions_t actions;
  634. if (posix_spawn_file_actions_init (&actions) != 0)
  635. return 1;
  636. if (posix_spawn_file_actions_addopen (&actions, 10000000, "foo", 0, O_RDONLY)
  637. == 0)
  638. return 2;
  639. return 0;
  640. }]])],
  641. [gl_cv_func_posix_spawn_file_actions_addopen_works=yes],
  642. [gl_cv_func_posix_spawn_file_actions_addopen_works=no],
  643. [# Guess no on musl libc and Solaris, yes otherwise.
  644. case "$host_os" in
  645. *-musl*) gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no";;
  646. solaris*) gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no";;
  647. # Guess no on native Windows.
  648. mingw*) gl_cv_func_posix_spawn_file_actions_addopen_works="guessing no" ;;
  649. *) gl_cv_func_posix_spawn_file_actions_addopen_works="guessing yes";;
  650. esac
  651. ])
  652. ])
  653. case "$gl_cv_func_posix_spawn_file_actions_addopen_works" in
  654. *yes) ;;
  655. *) REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=1 ;;
  656. esac
  657. fi
  658. ])