|
|
1 | /* GetProcessId is XP and up, which means in all supported versions */ |
|
|
2 | /* but older SDK's might need this */ |
|
|
3 | #define _WIN32_WINNT NTDDI_WINXP |
|
|
4 | |
1 | #include "EXTERN.h" |
5 | #include "EXTERN.h" |
2 | #include "perl.h" |
6 | #include "perl.h" |
3 | #include "XSUB.h" |
7 | #include "XSUB.h" |
4 | |
8 | |
5 | #include <stdio.h> |
9 | #include <stdio.h> |
6 | |
10 | |
7 | #ifdef WIN32 |
11 | #ifdef WIN32 |
8 | |
12 | |
|
|
13 | /* perl probably did this already */ |
9 | #include <windows.h> |
14 | #include <windows.h> |
10 | |
15 | |
11 | #else |
16 | #else |
12 | |
17 | |
13 | #include <errno.h> |
18 | #include <errno.h> |
… | |
… | |
41 | if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV) |
46 | if (!SvROK (sv) || SvTYPE (SvRV (sv)) != SVt_PVAV) |
42 | croak ("expected a reference to an array of argument/environment strings"); |
47 | croak ("expected a reference to an array of argument/environment strings"); |
43 | |
48 | |
44 | av = (AV *)SvRV (sv); |
49 | av = (AV *)SvRV (sv); |
45 | n = av_len (av) + 1; |
50 | n = av_len (av) + 1; |
46 | cvec = (char **)SvPVX (sv_2mortal (NEWSV (0, sizeof (char *) * n + 1))); |
51 | cvec = (char **)SvPVX (sv_2mortal (NEWSV (0, sizeof (char *) * (n + 1)))); |
47 | |
52 | |
48 | for (i = 0; i < n; ++i) |
53 | for (i = 0; i < n; ++i) |
49 | cvec [i] = SvPVbyte_nolen (*av_fetch (av, i, 11)); |
54 | cvec [i] = SvPVbyte_nolen (*av_fetch (av, i, 1)); |
50 | |
55 | |
51 | cvec [n] = 0; |
56 | cvec [n] = 0; |
52 | |
57 | |
53 | return cvec; |
58 | return cvec; |
54 | } |
59 | } |
… | |
… | |
62 | cv_undef (get_cv ("Proc::FastSpawn::_quote", 0)); |
67 | cv_undef (get_cv ("Proc::FastSpawn::_quote", 0)); |
63 | #endif |
68 | #endif |
64 | |
69 | |
65 | long |
70 | long |
66 | spawn (const char *path, SV *argv, SV *envp = &PL_sv_undef) |
71 | spawn (const char *path, SV *argv, SV *envp = &PL_sv_undef) |
|
|
72 | ALIAS: |
|
|
73 | spawnp = 1 |
67 | INIT: |
74 | INIT: |
68 | { |
75 | { |
69 | #ifdef WIN32 |
76 | #ifdef WIN32 |
70 | if (w32_num_children >= MAXIMUM_WAIT_OBJECTS) |
77 | if (w32_num_children >= MAXIMUM_WAIT_OBJECTS) |
71 | { |
78 | { |
… | |
… | |
88 | char *const *cenvp = SvOK (envp) ? array_to_cvec (envp) : environ; |
95 | char *const *cenvp = SvOK (envp) ? array_to_cvec (envp) : environ; |
89 | intptr_t pid; |
96 | intptr_t pid; |
90 | |
97 | |
91 | fflush (0); |
98 | fflush (0); |
92 | #ifdef WIN32 |
99 | #ifdef WIN32 |
93 | pid = _spawnve (_P_NOWAIT, path, cargv, cenvp); |
100 | pid = (ix ? _spawnvpe : _spawnve) (_P_NOWAIT, path, cargv, cenvp); |
94 | |
101 | |
95 | if (pid == -1) |
102 | if (pid == -1) |
96 | XSRETURN_UNDEF; |
103 | XSRETURN_UNDEF; |
97 | |
104 | |
98 | /* do it like perl, dadadoop dadadoop */ |
105 | /* do it like perl, dadadoop dadadoop */ |
99 | w32_child_handles [w32_num_children] = (HANDLE)pid; |
106 | w32_child_handles [w32_num_children] = (HANDLE)pid; |
100 | pid = GetProcessId ((HANDLE)pid); /* get the real pid, unfortunately, requires wxp or newer */ |
107 | pid = GetProcessId ((HANDLE)pid); /* get the real pid, unfortunately, requires wxp or newer */ |
101 | w32_child_pids [w32_num_children] = pid; |
108 | w32_child_pids [w32_num_children] = pid; |
102 | ++w32_num_children; |
109 | ++w32_num_children; |
103 | #elif USE_SPAWN |
110 | #elif USE_SPAWN |
104 | { |
111 | { |
105 | pid_t xpid; |
112 | pid_t xpid; |
106 | |
113 | |
107 | errno = posix_spawn (&xpid, path, 0, 0, cargv, cenvp); |
114 | errno = (ix ? posix_spawnp : posix_spawn) (&xpid, path, 0, 0, cargv, cenvp); |
108 | |
115 | |
109 | if (errno) |
116 | if (errno) |
110 | XSRETURN_UNDEF; |
117 | XSRETURN_UNDEF; |
111 | |
118 | |
112 | pid = xpid; |
119 | pid = xpid; |
113 | } |
120 | } |
114 | #else |
121 | #else |
115 | pid = vfork (); |
122 | pid = (ix ? fork : vfork) (); |
116 | |
123 | |
117 | if (pid < 0) |
124 | if (pid < 0) |
118 | XSRETURN_UNDEF; |
125 | XSRETURN_UNDEF; |
119 | |
126 | |
120 | if (pid == 0) |
127 | if (pid == 0) |
121 | { |
128 | { |
|
|
129 | if (ix) |
|
|
130 | { |
|
|
131 | environ = (char **)cenvp; |
|
|
132 | execvp (path, cargv); |
|
|
133 | } |
|
|
134 | else |
122 | execve (path, cargv, cenvp); |
135 | execve (path, cargv, cenvp); |
|
|
136 | |
123 | _exit (127); |
137 | _exit (127); |
124 | } |
138 | } |
125 | #endif |
139 | #endif |
126 | |
140 | |
127 | RETVAL = pid; |
141 | RETVAL = pid; |
… | |
… | |
134 | #ifdef WIN32 |
148 | #ifdef WIN32 |
135 | SetHandleInformation ((HANDLE)_get_osfhandle (fd), HANDLE_FLAG_INHERIT, on ? HANDLE_FLAG_INHERIT : 0); |
149 | SetHandleInformation ((HANDLE)_get_osfhandle (fd), HANDLE_FLAG_INHERIT, on ? HANDLE_FLAG_INHERIT : 0); |
136 | #else |
150 | #else |
137 | fcntl (fd, F_SETFD, on ? 0 : FD_CLOEXEC); |
151 | fcntl (fd, F_SETFD, on ? 0 : FD_CLOEXEC); |
138 | #endif |
152 | #endif |
|
|
153 | |