Skip to content

Commit 5f3f9cd

Browse files
committed
subprocess-posix: avoid using mmap
1 parent 2f6617d commit 5f3f9cd

1 file changed

Lines changed: 26 additions & 16 deletions

File tree

osdep/subprocess-posix.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,27 @@ struct child_args {
9595
const char *path;
9696
struct mp_subprocess_opts *opts;
9797
int *src_fds;
98+
void *child_stack;
9899
int pipe_end;
99100
bool detach;
100101
};
101102

102103
static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *opts,
103-
int src_fds[], bool detach);
104+
int src_fds[], bool detach, void *stacks[]);
104105

105106
static int child_main(void* args)
106107
{
107108
struct child_args *child_args = args;
108109
const char *path = child_args->path;
109110
struct mp_subprocess_opts *opts = child_args->opts;
110111
int *src_fds = child_args->src_fds;
112+
void *child_stack = child_args->child_stack;
111113
int *pipe_end = &child_args->pipe_end;
112114
bool detach = child_args->detach;
113115

114116
if (detach) {
115117
setsid();
116-
if (!spawn_process_inner(path, opts, src_fds, false))
118+
if (!spawn_process_inner(path, opts, src_fds, false, &child_stack))
117119
goto child_failed;
118120
return 0;
119121
}
@@ -148,7 +150,7 @@ static int child_main(void* args)
148150
}
149151

150152
static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *opts,
151-
int src_fds[], bool detach)
153+
int src_fds[], bool detach, void *stacks[])
152154
{
153155
pid_t fres = 0;
154156
int r;
@@ -157,21 +159,15 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
157159
.path = path,
158160
.opts = opts,
159161
.src_fds = src_fds,
162+
.child_stack = stacks[1],
160163
.pipe_end = 0,
161164
.detach = detach,
162165
};
163166

164-
#if HAVE_CLONE || HAVE_RFORK
165-
const size_t stack_size = 0x8000;
166-
void* stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
167-
if (stack == MAP_FAILED)
168-
goto done;
169-
#endif
170-
171167
#if HAVE_RFORK
172-
fres = rfork_thread(RFSPAWN, (int8_t*)stack + stack_size, child_main, &child_args);
168+
fres = rfork_thread(RFSPAWN, stacks[0], child_main, &child_args);
173169
#elif HAVE_CLONE
174-
fres = clone(child_main, (int8_t*)stack + stack_size, CLONE_VM | CLONE_VFORK | SIGCHLD, &child_args);
170+
fres = clone(child_main, stacks[0], CLONE_VM | CLONE_VFORK | SIGCHLD, &child_args);
175171
#else
176172
int p[2] = {-1, -1};
177173
// We setup a communication pipe to signal failure. Since the child calls
@@ -219,9 +215,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
219215
}
220216

221217
done:
222-
#if HAVE_CLONE || HAVE_RFORK
223-
munmap(stack, stack_size);
224-
#else
218+
#if !HAVE_CLONE && !HAVE_RFORK
225219
SAFE_CLOSE(p[0]);
226220
SAFE_CLOSE(p[1]);
227221
#endif
@@ -234,19 +228,35 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
234228
static pid_t spawn_process(const char *path, struct mp_subprocess_opts *opts,
235229
int src_fds[])
236230
{
231+
bool detach = opts->detach;
232+
void *stacks[2];
233+
234+
#if HAVE_CLONE || HAVE_RFORK
235+
// pre-allocate stacks so we can be async-signal-safe in spawn_process_inner()
236+
const size_t stack_size = 0x8000;
237+
void *ctx = talloc_new(NULL);
238+
// stack should be aligned to 16 bytes, which is guaranteed by malloc
239+
stacks[0] = (int8_t*)talloc_size(ctx, stack_size) + stack_size;
240+
if (detach) stacks[1] = (int8_t*)talloc_size(ctx, stack_size) + stack_size;
241+
#endif
242+
237243
#if !HAVE_RFORK
238244
sigset_t sigmask, oldmask;
239245

240246
sigfillset(&sigmask);
241247
pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
242248
#endif
243249

244-
pid_t fres = spawn_process_inner(path, opts, src_fds, opts->detach);
250+
pid_t fres = spawn_process_inner(path, opts, src_fds, detach, stacks);
245251

246252
#if !HAVE_RFORK
247253
pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
248254
#endif
249255

256+
#if HAVE_CLONE || HAVE_RFORK
257+
talloc_free(ctx);
258+
#endif
259+
250260
return fres;
251261
}
252262

0 commit comments

Comments
 (0)