spawni.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. /* Guts of POSIX spawn interface. Generic POSIX.1 version.
  2. Copyright (C) 2000-2006, 2008-2023 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. This file is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as
  6. published by the Free Software Foundation; either version 2.1 of the
  7. License, or (at your option) any later version.
  8. This file is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  14. #include <config.h>
  15. /* Specification. */
  16. #include <spawn.h>
  17. #include "spawn_int.h"
  18. #include <alloca.h>
  19. #include <errno.h>
  20. #include <fcntl.h>
  21. #ifndef O_LARGEFILE
  22. # define O_LARGEFILE 0
  23. #endif
  24. #if _LIBC || HAVE_PATHS_H
  25. # include <paths.h>
  26. #else
  27. # define _PATH_BSHELL BOURNE_SHELL
  28. #endif
  29. #include <signal.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #if _LIBC
  34. # include <not-cancel.h>
  35. #else
  36. # define close_not_cancel close
  37. # define open_not_cancel open
  38. #endif
  39. #if _LIBC
  40. # include <local-setxid.h>
  41. #else
  42. # if !HAVE_SETEUID
  43. # define seteuid(id) setresuid (-1, id, -1)
  44. # endif
  45. # if !HAVE_SETEGID
  46. # define setegid(id) setresgid (-1, id, -1)
  47. # endif
  48. # define local_seteuid(id) seteuid (id)
  49. # define local_setegid(id) setegid (id)
  50. #endif
  51. #if _LIBC
  52. # define alloca __alloca
  53. # define execve __execve
  54. # define dup2 __dup2
  55. # define fork __fork
  56. # define getgid __getgid
  57. # define getuid __getuid
  58. # define sched_setparam __sched_setparam
  59. # define sched_setscheduler __sched_setscheduler
  60. # define setpgid __setpgid
  61. # define sigaction __sigaction
  62. # define sigismember __sigismember
  63. # define sigprocmask __sigprocmask
  64. # define strchrnul __strchrnul
  65. # define vfork __vfork
  66. #endif
  67. /* The Unix standard contains a long explanation of the way to signal
  68. an error after the fork() was successful. Since no new wait status
  69. was wanted there is no way to signal an error using one of the
  70. available methods. The committee chose to signal an error by a
  71. normal program exit with the exit code 127. */
  72. #define SPAWN_ERROR 127
  73. #if defined _WIN32 && ! defined __CYGWIN__
  74. /* Native Windows API. */
  75. /* Define to 1 to enable DuplicateHandle optimization.
  76. Define to 0 to disable this optimization. */
  77. # ifndef SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE
  78. # define SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE 1
  79. # endif
  80. /* Get declarations of the native Windows API functions. */
  81. # define WIN32_LEAN_AND_MEAN
  82. # include <windows.h>
  83. # include <stdio.h>
  84. # include "filename.h"
  85. # include "concat-filename.h"
  86. # include "findprog.h"
  87. # include "malloca.h"
  88. # include "windows-spawn.h"
  89. /* Don't assume that UNICODE is not defined. */
  90. # undef CreateFile
  91. # define CreateFile CreateFileA
  92. # undef STARTUPINFO
  93. # define STARTUPINFO STARTUPINFOA
  94. # undef CreateProcess
  95. # define CreateProcess CreateProcessA
  96. /* Grows inh_handles->count so that it becomes > newfd.
  97. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  98. */
  99. static int
  100. grow_inheritable_handles (struct inheritable_handles *inh_handles, int newfd)
  101. {
  102. if (inh_handles->allocated <= newfd)
  103. {
  104. size_t new_allocated = 2 * inh_handles->allocated + 1;
  105. if (new_allocated <= newfd)
  106. new_allocated = newfd + 1;
  107. struct IHANDLE *new_ih =
  108. (struct IHANDLE *)
  109. realloc (inh_handles->ih, new_allocated * sizeof (struct IHANDLE));
  110. if (new_ih == NULL)
  111. {
  112. errno = ENOMEM;
  113. return -1;
  114. }
  115. inh_handles->allocated = new_allocated;
  116. inh_handles->ih = new_ih;
  117. }
  118. struct IHANDLE *ih = inh_handles->ih;
  119. for (; inh_handles->count <= newfd; inh_handles->count++)
  120. ih[inh_handles->count].handle = INVALID_HANDLE_VALUE;
  121. return 0;
  122. }
  123. # if SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE
  124. /* Assuming inh_handles->ih[newfd].handle != INVALID_HANDLE_VALUE
  125. and (inh_handles->ih[newfd].flags & DELAYED_DUP2_NEWFD) != 0,
  126. actually performs the delayed dup2 (oldfd, newfd).
  127. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  128. */
  129. static int
  130. do_delayed_dup2 (int newfd, struct inheritable_handles *inh_handles,
  131. HANDLE curr_process)
  132. {
  133. int oldfd = inh_handles->ih[newfd].linked_fd;
  134. /* Check invariants. */
  135. if (!((inh_handles->ih[oldfd].flags & DELAYED_DUP2_OLDFD) != 0
  136. && newfd == inh_handles->ih[oldfd].linked_fd
  137. && inh_handles->ih[newfd].handle == inh_handles->ih[oldfd].handle))
  138. abort ();
  139. /* Duplicate the handle now. */
  140. if (!DuplicateHandle (curr_process, inh_handles->ih[oldfd].handle,
  141. curr_process, &inh_handles->ih[newfd].handle,
  142. 0, TRUE, DUPLICATE_SAME_ACCESS))
  143. {
  144. errno = EBADF; /* arbitrary */
  145. return -1;
  146. }
  147. inh_handles->ih[oldfd].flags &= ~DELAYED_DUP2_OLDFD;
  148. inh_handles->ih[newfd].flags =
  149. (unsigned char) inh_handles->ih[oldfd].flags | KEEP_OPEN_IN_CHILD;
  150. return 0;
  151. }
  152. /* Performs the remaining delayed dup2 (oldfd, newfd).
  153. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  154. */
  155. static int
  156. do_remaining_delayed_dup2 (struct inheritable_handles *inh_handles,
  157. HANDLE curr_process)
  158. {
  159. size_t handles_count = inh_handles->count;
  160. int newfd;
  161. for (newfd = 0; newfd < handles_count; newfd++)
  162. if (inh_handles->ih[newfd].handle != INVALID_HANDLE_VALUE
  163. && (inh_handles->ih[newfd].flags & DELAYED_DUP2_NEWFD) != 0)
  164. if (do_delayed_dup2 (newfd, inh_handles, curr_process) < 0)
  165. return -1;
  166. return 0;
  167. }
  168. # endif
  169. /* Closes the handles in inh_handles that are not meant to be preserved in the
  170. child process, and reduces inh_handles->count to the minimum needed. */
  171. static void
  172. shrink_inheritable_handles (struct inheritable_handles *inh_handles)
  173. {
  174. struct IHANDLE *ih = inh_handles->ih;
  175. size_t handles_count = inh_handles->count;
  176. unsigned int fd;
  177. for (fd = 0; fd < handles_count; fd++)
  178. {
  179. HANDLE handle = ih[fd].handle;
  180. if (handle != INVALID_HANDLE_VALUE
  181. && (ih[fd].flags & KEEP_OPEN_IN_CHILD) == 0)
  182. {
  183. if (!(ih[fd].flags & KEEP_OPEN_IN_PARENT))
  184. CloseHandle (handle);
  185. ih[fd].handle = INVALID_HANDLE_VALUE;
  186. }
  187. }
  188. while (handles_count > 3
  189. && ih[handles_count - 1].handle == INVALID_HANDLE_VALUE)
  190. handles_count--;
  191. inh_handles->count = handles_count;
  192. }
  193. /* Closes all handles in inh_handles. */
  194. static void
  195. close_inheritable_handles (struct inheritable_handles *inh_handles)
  196. {
  197. struct IHANDLE *ih = inh_handles->ih;
  198. size_t handles_count = inh_handles->count;
  199. unsigned int fd;
  200. for (fd = 0; fd < handles_count; fd++)
  201. {
  202. HANDLE handle = ih[fd].handle;
  203. if (handle != INVALID_HANDLE_VALUE
  204. && !(ih[fd].flags & DELAYED_DUP2_NEWFD)
  205. && !(ih[fd].flags & KEEP_OPEN_IN_PARENT))
  206. CloseHandle (handle);
  207. }
  208. }
  209. /* Tests whether a memory region, starting at P and N bytes long, contains only
  210. zeroes. */
  211. static bool
  212. memiszero (const void *p, size_t n)
  213. {
  214. const char *cp = p;
  215. for (; n > 0; cp++, n--)
  216. if (*cp != 0)
  217. return 0;
  218. return 1;
  219. }
  220. /* Tests whether *S contains no signals. */
  221. static bool
  222. sigisempty (const sigset_t *s)
  223. {
  224. return memiszero (s, sizeof (sigset_t));
  225. }
  226. /* Executes a 'close' action.
  227. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  228. */
  229. static int
  230. do_close (struct inheritable_handles *inh_handles, int fd, bool ignore_EBADF)
  231. {
  232. if (!(fd >= 0 && fd < inh_handles->count
  233. && inh_handles->ih[fd].handle != INVALID_HANDLE_VALUE))
  234. {
  235. if (ignore_EBADF)
  236. return 0;
  237. else
  238. {
  239. errno = EBADF;
  240. return -1;
  241. }
  242. }
  243. # if SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE
  244. if ((inh_handles->ih[fd].flags & DELAYED_DUP2_NEWFD) != 0)
  245. {
  246. int dup2_oldfd = inh_handles->ih[fd].linked_fd;
  247. /* Check invariants. */
  248. if (!((inh_handles->ih[dup2_oldfd].flags & DELAYED_DUP2_OLDFD) != 0
  249. && fd == inh_handles->ih[dup2_oldfd].linked_fd
  250. && inh_handles->ih[fd].handle == inh_handles->ih[dup2_oldfd].handle))
  251. abort ();
  252. /* Annihilate a delayed dup2 (..., fd) call. */
  253. inh_handles->ih[dup2_oldfd].flags &= ~DELAYED_DUP2_OLDFD;
  254. }
  255. else if ((inh_handles->ih[fd].flags & DELAYED_DUP2_OLDFD) != 0)
  256. {
  257. int dup2_newfd = inh_handles->ih[fd].linked_fd;
  258. /* Check invariants. */
  259. if (!((inh_handles->ih[dup2_newfd].flags & DELAYED_DUP2_NEWFD) != 0
  260. && fd == inh_handles->ih[dup2_newfd].linked_fd
  261. && inh_handles->ih[fd].handle == inh_handles->ih[dup2_newfd].handle))
  262. abort ();
  263. /* Optimize a delayed dup2 (fd, ...) call. */
  264. inh_handles->ih[dup2_newfd].flags =
  265. (inh_handles->ih[fd].flags & ~DELAYED_DUP2_OLDFD) | KEEP_OPEN_IN_CHILD;
  266. }
  267. else
  268. # endif
  269. {
  270. if (!(inh_handles->ih[fd].flags & KEEP_OPEN_IN_PARENT)
  271. && !CloseHandle (inh_handles->ih[fd].handle))
  272. {
  273. inh_handles->ih[fd].handle = INVALID_HANDLE_VALUE;
  274. errno = EIO;
  275. return -1;
  276. }
  277. }
  278. inh_handles->ih[fd].handle = INVALID_HANDLE_VALUE;
  279. return 0;
  280. }
  281. /* Opens an inheritable HANDLE to a file.
  282. Upon failure, returns INVALID_HANDLE_VALUE with errno set. */
  283. static HANDLE
  284. open_handle (const char *name, int flags, mode_t mode)
  285. {
  286. /* To ease portability. Like in open.c. */
  287. if (strcmp (name, "/dev/null") == 0)
  288. name = "NUL";
  289. /* POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>
  290. specifies: "More than two leading <slash> characters shall be treated as
  291. a single <slash> character." */
  292. if (ISSLASH (name[0]) && ISSLASH (name[1]) && ISSLASH (name[2]))
  293. {
  294. name += 2;
  295. while (ISSLASH (name[1]))
  296. name++;
  297. }
  298. size_t len = strlen (name);
  299. size_t drive_prefix_len = (HAS_DEVICE (name) ? 2 : 0);
  300. /* Remove trailing slashes (except the very first one, at position
  301. drive_prefix_len), but remember their presence. */
  302. size_t rlen;
  303. bool check_dir = false;
  304. rlen = len;
  305. while (rlen > drive_prefix_len && ISSLASH (name[rlen-1]))
  306. {
  307. check_dir = true;
  308. if (rlen == drive_prefix_len + 1)
  309. break;
  310. rlen--;
  311. }
  312. /* Handle '' and 'C:'. */
  313. if (!check_dir && rlen == drive_prefix_len)
  314. {
  315. errno = ENOENT;
  316. return INVALID_HANDLE_VALUE;
  317. }
  318. /* Handle '\\'. */
  319. if (rlen == 1 && ISSLASH (name[0]) && len >= 2)
  320. {
  321. errno = ENOENT;
  322. return INVALID_HANDLE_VALUE;
  323. }
  324. const char *rname;
  325. char *malloca_rname;
  326. if (rlen == len)
  327. {
  328. rname = name;
  329. malloca_rname = NULL;
  330. }
  331. else
  332. {
  333. malloca_rname = malloca (rlen + 1);
  334. if (malloca_rname == NULL)
  335. {
  336. errno = ENOMEM;
  337. return INVALID_HANDLE_VALUE;
  338. }
  339. memcpy (malloca_rname, name, rlen);
  340. malloca_rname[rlen] = '\0';
  341. rname = malloca_rname;
  342. }
  343. /* For the meaning of the flags, see
  344. <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen> */
  345. /* Open a handle to the file.
  346. CreateFile
  347. <https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea>
  348. <https://docs.microsoft.com/en-us/windows/desktop/FileIO/creating-and-opening-files> */
  349. SECURITY_ATTRIBUTES sec_attr;
  350. sec_attr.nLength = sizeof (SECURITY_ATTRIBUTES);
  351. sec_attr.lpSecurityDescriptor = NULL;
  352. sec_attr.bInheritHandle = TRUE;
  353. HANDLE handle =
  354. CreateFile (rname,
  355. ((flags & (O_WRONLY | O_RDWR)) != 0
  356. ? GENERIC_READ | GENERIC_WRITE
  357. : GENERIC_READ),
  358. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  359. &sec_attr,
  360. ((flags & O_CREAT) != 0
  361. ? ((flags & O_EXCL) != 0
  362. ? CREATE_NEW
  363. : ((flags & O_TRUNC) != 0 ? CREATE_ALWAYS : OPEN_ALWAYS))
  364. : ((flags & O_TRUNC) != 0
  365. ? TRUNCATE_EXISTING
  366. : OPEN_EXISTING)),
  367. /* FILE_FLAG_BACKUP_SEMANTICS is useful for opening directories,
  368. which is out-of-scope here. */
  369. /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
  370. in case as different) makes sense only when applied to *all*
  371. filesystem operations. */
  372. /* FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS */
  373. FILE_ATTRIBUTE_NORMAL
  374. | ((flags & O_TEMPORARY) != 0 ? FILE_FLAG_DELETE_ON_CLOSE : 0)
  375. | ((flags & O_SEQUENTIAL ) != 0 ? FILE_FLAG_SEQUENTIAL_SCAN : 0)
  376. | ((flags & O_RANDOM) != 0 ? FILE_FLAG_RANDOM_ACCESS : 0),
  377. NULL);
  378. if (handle == INVALID_HANDLE_VALUE)
  379. switch (GetLastError ())
  380. {
  381. /* Some of these errors probably cannot happen with the specific flags
  382. that we pass to CreateFile. But who knows... */
  383. case ERROR_FILE_NOT_FOUND: /* The last component of rname does not exist. */
  384. case ERROR_PATH_NOT_FOUND: /* Some directory component in rname does not exist. */
  385. case ERROR_BAD_PATHNAME: /* rname is such as '\\server'. */
  386. case ERROR_BAD_NETPATH: /* rname is such as '\\nonexistentserver\share'. */
  387. case ERROR_BAD_NET_NAME: /* rname is such as '\\server\nonexistentshare'. */
  388. case ERROR_INVALID_NAME: /* rname contains wildcards, misplaced colon, etc. */
  389. case ERROR_DIRECTORY:
  390. errno = ENOENT;
  391. break;
  392. case ERROR_ACCESS_DENIED: /* rname is such as 'C:\System Volume Information\foo'. */
  393. case ERROR_SHARING_VIOLATION: /* rname is such as 'C:\pagefile.sys'. */
  394. /* XXX map to EACCES or EPERM? */
  395. errno = EACCES;
  396. break;
  397. case ERROR_OUTOFMEMORY:
  398. errno = ENOMEM;
  399. break;
  400. case ERROR_WRITE_PROTECT:
  401. errno = EROFS;
  402. break;
  403. case ERROR_WRITE_FAULT:
  404. case ERROR_READ_FAULT:
  405. case ERROR_GEN_FAILURE:
  406. errno = EIO;
  407. break;
  408. case ERROR_BUFFER_OVERFLOW:
  409. case ERROR_FILENAME_EXCED_RANGE:
  410. errno = ENAMETOOLONG;
  411. break;
  412. case ERROR_DELETE_PENDING: /* XXX map to EACCES or EPERM? */
  413. errno = EPERM;
  414. break;
  415. default:
  416. errno = EINVAL;
  417. break;
  418. }
  419. if (malloca_rname != NULL)
  420. {
  421. int saved_errno = errno;
  422. freea (malloca_rname);
  423. errno = saved_errno;
  424. }
  425. return handle;
  426. }
  427. /* Executes an 'open' action.
  428. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  429. */
  430. static int
  431. do_open (struct inheritable_handles *inh_handles, int newfd,
  432. const char *filename, const char *directory,
  433. int flags, mode_t mode)
  434. {
  435. if (!(newfd >= 0 && newfd < _getmaxstdio ()))
  436. {
  437. errno = EBADF;
  438. return -1;
  439. }
  440. if (grow_inheritable_handles (inh_handles, newfd) < 0)
  441. return -1;
  442. if (do_close (inh_handles, newfd, true) < 0)
  443. return -1;
  444. if (filename == NULL)
  445. {
  446. errno = EINVAL;
  447. return -1;
  448. }
  449. char *filename_to_free = NULL;
  450. if (directory != NULL && IS_RELATIVE_FILE_NAME (filename))
  451. {
  452. char *real_filename = concatenated_filename (directory, filename, NULL);
  453. if (real_filename == NULL)
  454. {
  455. errno = ENOMEM;
  456. return -1;
  457. }
  458. filename = real_filename;
  459. filename_to_free = real_filename;
  460. }
  461. HANDLE handle = open_handle (filename, flags, mode);
  462. if (handle == INVALID_HANDLE_VALUE)
  463. {
  464. free (filename_to_free);
  465. return -1;
  466. }
  467. free (filename_to_free);
  468. inh_handles->ih[newfd].handle = handle;
  469. inh_handles->ih[newfd].flags =
  470. ((flags & O_APPEND) != 0 ? 32 : 0) | KEEP_OPEN_IN_CHILD;
  471. return 0;
  472. }
  473. /* Executes a 'dup2' action.
  474. Returns 0 upon success. In case of failure, -1 is returned, with errno set.
  475. */
  476. static int
  477. do_dup2 (struct inheritable_handles *inh_handles, int oldfd, int newfd,
  478. HANDLE curr_process)
  479. {
  480. if (!(oldfd >= 0 && oldfd < inh_handles->count
  481. && inh_handles->ih[oldfd].handle != INVALID_HANDLE_VALUE))
  482. {
  483. errno = EBADF;
  484. return -1;
  485. }
  486. if (!(newfd >= 0 && newfd < _getmaxstdio ()))
  487. {
  488. errno = EBADF;
  489. return -1;
  490. }
  491. if (newfd != oldfd)
  492. {
  493. if (grow_inheritable_handles (inh_handles, newfd) < 0)
  494. return -1;
  495. if (do_close (inh_handles, newfd, true) < 0)
  496. return -1;
  497. /* We may need to duplicate the handle, so that a forthcoming do_close
  498. action on oldfd has no effect on newfd. */
  499. # if SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE
  500. /* But try to not do it now; delay it if possible. In many cases, the
  501. DuplicateHandle call can be optimized away. */
  502. if ((inh_handles->ih[oldfd].flags & DELAYED_DUP2_NEWFD) != 0)
  503. if (do_delayed_dup2 (oldfd, inh_handles, curr_process) < 0)
  504. return -1;
  505. if ((inh_handles->ih[oldfd].flags & DELAYED_DUP2_OLDFD) != 0)
  506. {
  507. /* Check invariants. */
  508. int dup2_newfd = inh_handles->ih[oldfd].linked_fd;
  509. if (!((inh_handles->ih[dup2_newfd].flags & DELAYED_DUP2_NEWFD) != 0
  510. && oldfd == inh_handles->ih[dup2_newfd].linked_fd
  511. && inh_handles->ih[oldfd].handle == inh_handles->ih[dup2_newfd].handle))
  512. abort ();
  513. /* We can't delay two or more dup2 calls from the same oldfd. */
  514. if (!DuplicateHandle (curr_process, inh_handles->ih[oldfd].handle,
  515. curr_process, &inh_handles->ih[newfd].handle,
  516. 0, TRUE, DUPLICATE_SAME_ACCESS))
  517. {
  518. errno = EBADF; /* arbitrary */
  519. return -1;
  520. }
  521. inh_handles->ih[newfd].flags =
  522. (unsigned char) inh_handles->ih[oldfd].flags | KEEP_OPEN_IN_CHILD;
  523. }
  524. else
  525. {
  526. /* Delay the dup2 (oldfd, newfd) action. */
  527. inh_handles->ih[oldfd].flags |= DELAYED_DUP2_OLDFD;
  528. inh_handles->ih[oldfd].linked_fd = newfd;
  529. inh_handles->ih[newfd].handle = inh_handles->ih[oldfd].handle;
  530. inh_handles->ih[newfd].flags = DELAYED_DUP2_NEWFD;
  531. inh_handles->ih[newfd].linked_fd = oldfd;
  532. }
  533. # else
  534. if (!DuplicateHandle (curr_process, inh_handles->ih[oldfd].handle,
  535. curr_process, &inh_handles->ih[newfd].handle,
  536. 0, TRUE, DUPLICATE_SAME_ACCESS))
  537. {
  538. errno = EBADF; /* arbitrary */
  539. return -1;
  540. }
  541. inh_handles->ih[newfd].flags =
  542. (unsigned char) inh_handles->ih[oldfd].flags | KEEP_OPEN_IN_CHILD;
  543. # endif
  544. }
  545. return 0;
  546. }
  547. int
  548. __spawni (pid_t *pid, const char *prog_filename,
  549. const posix_spawn_file_actions_t *file_actions,
  550. const posix_spawnattr_t *attrp, const char *const prog_argv[],
  551. const char *const envp[], int use_path)
  552. {
  553. /* Validate the arguments. */
  554. if (prog_filename == NULL
  555. || (attrp != NULL
  556. && ((attrp->_flags & ~POSIX_SPAWN_SETPGROUP) != 0
  557. || attrp->_pgrp != 0
  558. || ! sigisempty (&attrp->_sd)
  559. || ! sigisempty (&attrp->_ss)
  560. || attrp->_sp.sched_priority != 0
  561. || attrp->_policy != 0)))
  562. return EINVAL;
  563. /* Process group handling:
  564. Native Windows does not have the concept of process group, but it has the
  565. concept of a console attached to a process.
  566. So, we interpret the three cases as follows:
  567. - Flag POSIX_SPAWN_SETPGROUP not set: Means, the child process is in the
  568. same process group as the parent process. We interpret this as a
  569. request to reuse the same console.
  570. - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp == 0: Means the child
  571. process starts a process group of its own. See
  572. <https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_getpgroup.html>
  573. <https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgrp.html>
  574. We interpret this as a request to detach from the current console.
  575. - Flag POSIX_SPAWN_SETPGROUP set with attrp->_pgrp != 0: Means the child
  576. process joins another, existing process group. See
  577. <https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_getpgroup.html>
  578. <https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html>
  579. We don't support this case; it produces error EINVAL above. */
  580. /* <https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags> */
  581. DWORD process_creation_flags =
  582. (attrp != NULL && (attrp->_flags & POSIX_SPAWN_SETPGROUP) != 0 ? DETACHED_PROCESS : 0);
  583. char *argv_mem_to_free;
  584. const char **argv = prepare_spawn (prog_argv, &argv_mem_to_free);
  585. if (argv == NULL)
  586. return errno; /* errno is set here */
  587. argv++;
  588. /* Compose the command. */
  589. char *command = compose_command (argv);
  590. if (command == NULL)
  591. {
  592. free (argv_mem_to_free);
  593. return ENOMEM;
  594. }
  595. /* Copy *ENVP into a contiguous block of memory. */
  596. char *envblock;
  597. if (envp == NULL)
  598. envblock = NULL;
  599. else
  600. {
  601. envblock = compose_envblock (envp);
  602. if (envblock == NULL)
  603. {
  604. free (command);
  605. free (argv_mem_to_free);
  606. return ENOMEM;
  607. }
  608. }
  609. /* Set up the array of handles to inherit.
  610. Duplicate each handle, so that a spawn_do_close action (below) has no
  611. effect on the file descriptors of the current process. Alternatively,
  612. we could store, for each handle, a bit that tells whether it is shared
  613. with the current process. But this is simpler. */
  614. struct inheritable_handles inh_handles;
  615. if (init_inheritable_handles (&inh_handles, true) < 0)
  616. goto failed_1;
  617. /* Directory in which to execute the new process. */
  618. const char *directory = NULL;
  619. /* Execute the file_actions, modifying the inh_handles instead of the
  620. file descriptors of the current process. */
  621. if (file_actions != NULL)
  622. {
  623. HANDLE curr_process = GetCurrentProcess ();
  624. int cnt;
  625. for (cnt = 0; cnt < file_actions->_used; ++cnt)
  626. {
  627. struct __spawn_action *action = &file_actions->_actions[cnt];
  628. switch (action->tag)
  629. {
  630. case spawn_do_close:
  631. {
  632. int fd = action->action.close_action.fd;
  633. if (do_close (&inh_handles, fd, false) < 0)
  634. goto failed_2;
  635. }
  636. break;
  637. case spawn_do_open:
  638. {
  639. int newfd = action->action.open_action.fd;
  640. const char *filename = action->action.open_action.path;
  641. int flags = action->action.open_action.oflag;
  642. mode_t mode = action->action.open_action.mode;
  643. if (do_open (&inh_handles, newfd, filename, directory,
  644. flags, mode)
  645. < 0)
  646. goto failed_2;
  647. }
  648. break;
  649. case spawn_do_dup2:
  650. {
  651. int oldfd = action->action.dup2_action.fd;
  652. int newfd = action->action.dup2_action.newfd;
  653. if (do_dup2 (&inh_handles, oldfd, newfd, curr_process) < 0)
  654. goto failed_2;
  655. }
  656. break;
  657. case spawn_do_chdir:
  658. {
  659. char *newdir = action->action.chdir_action.path;
  660. if (directory != NULL && IS_RELATIVE_FILE_NAME (newdir))
  661. {
  662. newdir = concatenated_filename (directory, newdir, NULL);
  663. if (newdir == NULL)
  664. {
  665. errno = ENOMEM;
  666. goto failed_2;
  667. }
  668. }
  669. directory = newdir;
  670. }
  671. break;
  672. case spawn_do_fchdir:
  673. /* Not supported in this implementation. */
  674. errno = EINVAL;
  675. goto failed_2;
  676. }
  677. }
  678. # if SPAWN_INTERNAL_OPTIMIZE_DUPLICATEHANDLE
  679. /* Do the remaining delayed dup2 invocations. */
  680. if (do_remaining_delayed_dup2 (&inh_handles, curr_process) < 0)
  681. goto failed_2;
  682. # endif
  683. }
  684. /* Close the handles in inh_handles that are not meant to be preserved in the
  685. child process, and reduce inh_handles.count to the minimum needed. */
  686. shrink_inheritable_handles (&inh_handles);
  687. /* CreateProcess
  688. <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa> */
  689. /* STARTUPINFO
  690. <https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa> */
  691. STARTUPINFO sinfo;
  692. sinfo.cb = sizeof (STARTUPINFO);
  693. sinfo.lpReserved = NULL;
  694. sinfo.lpDesktop = NULL;
  695. sinfo.lpTitle = NULL;
  696. if (compose_handles_block (&inh_handles, &sinfo) < 0)
  697. goto failed_2;
  698. /* Perform the PATH search now, considering the final DIRECTORY. */
  699. char *resolved_prog_filename_to_free = NULL;
  700. {
  701. const char *resolved_prog_filename =
  702. find_in_given_path (prog_filename, use_path ? getenv ("PATH") : "",
  703. directory, false);
  704. if (resolved_prog_filename == NULL)
  705. goto failed_3;
  706. if (resolved_prog_filename != prog_filename)
  707. resolved_prog_filename_to_free = (char *) resolved_prog_filename;
  708. prog_filename = resolved_prog_filename;
  709. }
  710. PROCESS_INFORMATION pinfo;
  711. if (!CreateProcess (prog_filename, command, NULL, NULL, TRUE,
  712. process_creation_flags, envblock, directory, &sinfo,
  713. &pinfo))
  714. {
  715. DWORD error = GetLastError ();
  716. free (resolved_prog_filename_to_free);
  717. free (sinfo.lpReserved2);
  718. close_inheritable_handles (&inh_handles);
  719. free_inheritable_handles (&inh_handles);
  720. free (envblock);
  721. free (command);
  722. free (argv_mem_to_free);
  723. return convert_CreateProcess_error (error);
  724. }
  725. if (pinfo.hThread)
  726. CloseHandle (pinfo.hThread);
  727. free (resolved_prog_filename_to_free);
  728. free (sinfo.lpReserved2);
  729. close_inheritable_handles (&inh_handles);
  730. free_inheritable_handles (&inh_handles);
  731. free (envblock);
  732. free (command);
  733. free (argv_mem_to_free);
  734. if (pid != NULL)
  735. *pid = (intptr_t) pinfo.hProcess;
  736. return 0;
  737. failed_3:
  738. {
  739. int saved_errno = errno;
  740. free (sinfo.lpReserved2);
  741. close_inheritable_handles (&inh_handles);
  742. free_inheritable_handles (&inh_handles);
  743. free (envblock);
  744. free (command);
  745. free (argv_mem_to_free);
  746. return saved_errno;
  747. }
  748. failed_2:
  749. {
  750. int saved_errno = errno;
  751. close_inheritable_handles (&inh_handles);
  752. free_inheritable_handles (&inh_handles);
  753. free (envblock);
  754. free (command);
  755. free (argv_mem_to_free);
  756. return saved_errno;
  757. }
  758. failed_1:
  759. free (envblock);
  760. free (command);
  761. free (argv_mem_to_free);
  762. return errno;
  763. }
  764. #else
  765. /* The warning "warning: 'vfork' is deprecated: Use posix_spawn or fork" seen
  766. on macOS 12 is pointless, as we use vfork only when it is safe or when the
  767. user has explicitly requested it. Silence this warning. */
  768. #if __GNUC__ >= 3
  769. # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  770. #endif
  771. /* Spawn a new process executing PATH with the attributes describes in *ATTRP.
  772. Before running the process perform the actions described in FILE-ACTIONS. */
  773. int
  774. __spawni (pid_t *pid, const char *file,
  775. const posix_spawn_file_actions_t *file_actions,
  776. const posix_spawnattr_t *attrp, const char *const argv[],
  777. const char *const envp[], int use_path)
  778. {
  779. pid_t new_pid;
  780. char *path, *p, *name;
  781. size_t len;
  782. size_t pathlen;
  783. /* Do this once. */
  784. short int flags = attrp == NULL ? 0 : attrp->_flags;
  785. /* Avoid gcc warning
  786. "variable 'flags' might be clobbered by 'longjmp' or 'vfork'" */
  787. (void) &flags;
  788. /* Generate the new process. */
  789. #if HAVE_VFORK
  790. if ((flags & POSIX_SPAWN_USEVFORK) != 0
  791. /* If no major work is done, allow using vfork. Note that we
  792. might perform the path searching. But this would be done by
  793. a call to execvp(), too, and such a call must be OK according
  794. to POSIX. */
  795. || ((flags & (POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF
  796. | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER
  797. | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_RESETIDS)) == 0
  798. && file_actions == NULL))
  799. new_pid = vfork ();
  800. else
  801. #endif
  802. new_pid = fork ();
  803. if (new_pid != 0)
  804. {
  805. if (new_pid < 0)
  806. return errno;
  807. /* The call was successful. Store the PID if necessary. */
  808. if (pid != NULL)
  809. *pid = new_pid;
  810. return 0;
  811. }
  812. /* Set signal mask. */
  813. if ((flags & POSIX_SPAWN_SETSIGMASK) != 0
  814. && sigprocmask (SIG_SETMASK, &attrp->_ss, NULL) != 0)
  815. _exit (SPAWN_ERROR);
  816. /* Set signal default action. */
  817. if ((flags & POSIX_SPAWN_SETSIGDEF) != 0)
  818. {
  819. /* We have to iterate over all signals. This could possibly be
  820. done better but it requires system specific solutions since
  821. the sigset_t data type can be very different on different
  822. architectures. */
  823. int sig;
  824. struct sigaction sa;
  825. memset (&sa, '\0', sizeof (sa));
  826. sa.sa_handler = SIG_DFL;
  827. for (sig = 1; sig <= NSIG; ++sig)
  828. if (sigismember (&attrp->_sd, sig) != 0
  829. && sigaction (sig, &sa, NULL) != 0)
  830. _exit (SPAWN_ERROR);
  831. }
  832. #if (_LIBC ? defined _POSIX_PRIORITY_SCHEDULING : HAVE_SCHED_SETPARAM && HAVE_SCHED_SETSCHEDULER)
  833. /* Set the scheduling algorithm and parameters. */
  834. if ((flags & (POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER))
  835. == POSIX_SPAWN_SETSCHEDPARAM)
  836. {
  837. if (sched_setparam (0, &attrp->_sp) == -1)
  838. _exit (SPAWN_ERROR);
  839. }
  840. else if ((flags & POSIX_SPAWN_SETSCHEDULER) != 0)
  841. {
  842. if (sched_setscheduler (0, attrp->_policy,
  843. (flags & POSIX_SPAWN_SETSCHEDPARAM) != 0
  844. ? &attrp->_sp : NULL) == -1)
  845. _exit (SPAWN_ERROR);
  846. }
  847. #endif
  848. /* Set the process group ID. */
  849. if ((flags & POSIX_SPAWN_SETPGROUP) != 0
  850. && setpgid (0, attrp->_pgrp) != 0)
  851. _exit (SPAWN_ERROR);
  852. /* Set the effective user and group IDs. */
  853. if ((flags & POSIX_SPAWN_RESETIDS) != 0
  854. && (local_seteuid (getuid ()) != 0
  855. || local_setegid (getgid ()) != 0))
  856. _exit (SPAWN_ERROR);
  857. /* Execute the file actions. */
  858. if (file_actions != NULL)
  859. {
  860. int cnt;
  861. for (cnt = 0; cnt < file_actions->_used; ++cnt)
  862. {
  863. struct __spawn_action *action = &file_actions->_actions[cnt];
  864. switch (action->tag)
  865. {
  866. case spawn_do_close:
  867. if (close_not_cancel (action->action.close_action.fd) != 0)
  868. /* Signal the error. */
  869. _exit (SPAWN_ERROR);
  870. break;
  871. case spawn_do_open:
  872. {
  873. int new_fd = open_not_cancel (action->action.open_action.path,
  874. action->action.open_action.oflag
  875. | O_LARGEFILE,
  876. action->action.open_action.mode);
  877. if (new_fd == -1)
  878. /* The 'open' call failed. */
  879. _exit (SPAWN_ERROR);
  880. /* Make sure the desired file descriptor is used. */
  881. if (new_fd != action->action.open_action.fd)
  882. {
  883. if (dup2 (new_fd, action->action.open_action.fd)
  884. != action->action.open_action.fd)
  885. /* The 'dup2' call failed. */
  886. _exit (SPAWN_ERROR);
  887. if (close_not_cancel (new_fd) != 0)
  888. /* The 'close' call failed. */
  889. _exit (SPAWN_ERROR);
  890. }
  891. }
  892. break;
  893. case spawn_do_dup2:
  894. if (dup2 (action->action.dup2_action.fd,
  895. action->action.dup2_action.newfd)
  896. != action->action.dup2_action.newfd)
  897. /* The 'dup2' call failed. */
  898. _exit (SPAWN_ERROR);
  899. break;
  900. case spawn_do_chdir:
  901. if (chdir (action->action.chdir_action.path) < 0)
  902. /* The 'chdir' call failed. */
  903. _exit (SPAWN_ERROR);
  904. break;
  905. case spawn_do_fchdir:
  906. if (fchdir (action->action.fchdir_action.fd) < 0)
  907. /* The 'fchdir' call failed. */
  908. _exit (SPAWN_ERROR);
  909. break;
  910. }
  911. }
  912. }
  913. if (! use_path || strchr (file, '/') != NULL)
  914. {
  915. /* The FILE parameter is actually a path. */
  916. execve (file, (char * const *) argv, (char * const *) envp);
  917. /* Oh, oh. 'execve' returns. This is bad. */
  918. _exit (SPAWN_ERROR);
  919. }
  920. /* We have to search for FILE on the path. */
  921. path = getenv ("PATH");
  922. if (path == NULL)
  923. {
  924. #if HAVE_CONFSTR
  925. /* There is no 'PATH' in the environment.
  926. The default search path is the current directory
  927. followed by the path 'confstr' returns for '_CS_PATH'. */
  928. len = confstr (_CS_PATH, (char *) NULL, 0);
  929. path = (char *) alloca (1 + len);
  930. path[0] = ':';
  931. (void) confstr (_CS_PATH, path + 1, len);
  932. #else
  933. /* Pretend that the PATH contains only the current directory. */
  934. path = "";
  935. #endif
  936. }
  937. len = strlen (file) + 1;
  938. pathlen = strlen (path);
  939. name = alloca (pathlen + len + 1);
  940. /* Copy the file name at the top. */
  941. name = (char *) memcpy (name + pathlen + 1, file, len);
  942. /* And add the slash. */
  943. *--name = '/';
  944. p = path;
  945. do
  946. {
  947. char *startp;
  948. path = p;
  949. p = strchrnul (path, ':');
  950. if (p == path)
  951. /* Two adjacent colons, or a colon at the beginning or the end
  952. of 'PATH' means to search the current directory. */
  953. startp = name + 1;
  954. else
  955. startp = (char *) memcpy (name - (p - path), path, p - path);
  956. /* Try to execute this name. If it works, execv will not return. */
  957. execve (startp, (char * const *) argv, (char * const *) envp);
  958. switch (errno)
  959. {
  960. case EACCES:
  961. case ENOENT:
  962. case ESTALE:
  963. case ENOTDIR:
  964. /* Those errors indicate the file is missing or not executable
  965. by us, in which case we want to just try the next path
  966. directory. */
  967. break;
  968. default:
  969. /* Some other error means we found an executable file, but
  970. something went wrong executing it; return the error to our
  971. caller. */
  972. _exit (SPAWN_ERROR);
  973. }
  974. }
  975. while (*p++ != '\0');
  976. /* Return with an error. */
  977. _exit (SPAWN_ERROR);
  978. }
  979. #endif