This is a maintenance fork
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
4.6 KiB

2 years ago
2 years ago
2 years ago
  1. /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
  2. vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
  3. Copyright 2020 Justine Alexandra Roberts Tunney
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; version 2 of the License.
  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
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  14. 02110-1301 USA
  15. */
  16. #include "libc/alg/alg.h"
  17. #include "libc/alg/arraylist.h"
  18. #include "libc/bits/bits.h"
  19. #include "libc/bits/safemacros.h"
  20. #include "libc/calls/calls.h"
  21. #include "libc/calls/hefty/ntspawn.h"
  22. #include "libc/calls/internal.h"
  23. #include "libc/conv/conv.h"
  24. #include "libc/nt/enum/processcreationflags.h"
  25. #include "libc/nt/process.h"
  26. #include "libc/nt/runtime.h"
  27. #include "libc/runtime/missioncritical.h"
  28. #include "libc/runtime/runtime.h"
  29. #include "libc/str/str.h"
  30. #include "libc/sysv/consts/fileno.h"
  31. #include "libc/sysv/errfuns.h"
  32. /**
  33. * Spawns process on Windows NT.
  34. *
  35. * This function delegates to CreateProcess() with UTF-8 UTF-16
  36. * translation and argv escaping. Please note this will NOT escape
  37. * command interpreter syntax.
  38. *
  39. * @param program will not be PATH searched, see commandv()
  40. * @param argv[0] is the name of the program to run
  41. * @param argv[1,n-2] optionally specifies program arguments
  42. * @param argv[n-1] is NULL
  43. * @param envp[𝟶,m-2] specifies "foo=bar" environment variables, which
  44. * don't need to be passed in sorted order; however, this function
  45. * goes faster the closer they are to sorted
  46. * @param envp[m-1] is NULL
  47. * @param bInheritHandles means handles already marked inheritable will
  48. * be inherited; which, assuming the System V wrapper functions are
  49. * being used, should mean (1) all files and sockets that weren't
  50. * opened with O_CLOEXEC; and (2) all memory mappings
  51. * @param opt_out_lpProcessInformation can be used to return process and
  52. * thread IDs to parent, as well as open handles that need close()
  53. * @return 0 on success, or -1 w/ errno
  54. * @see spawnve() which abstracts this function
  55. */
  56. textwindows int ntspawn(
  57. const char *program, char *const argv[], char *const envp[],
  58. struct NtSecurityAttributes *opt_lpProcessAttributes,
  59. struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles,
  60. uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory,
  61. /*nodiscard*/ const struct NtStartupInfo *lpStartupInfo,
  62. struct NtProcessInformation *opt_out_lpProcessInformation) {
  63. int rc;
  64. char16_t program16[PATH_MAX], *lpCommandLine, *lpEnvironment;
  65. lpCommandLine = NULL;
  66. lpEnvironment = NULL;
  67. if (mkntpath(program, program16) != -1 &&
  68. (lpCommandLine = mkntcmdline(argv)) &&
  69. (lpEnvironment = mkntenvblock(envp))) {
  70. if (CreateProcess(program16, lpCommandLine, opt_lpProcessAttributes,
  71. opt_lpThreadAttributes, bInheritHandles,
  72. dwCreationFlags | kNtCreateUnicodeEnvironment,
  73. lpEnvironment, opt_lpCurrentDirectory, lpStartupInfo,
  74. opt_out_lpProcessInformation)) {
  75. rc = 0;
  76. } else {
  77. rc = winerr();
  78. }
  79. } else {
  80. rc = -1;
  81. }
  82. free(lpCommandLine);
  83. free(lpEnvironment);
  84. return rc;
  85. }