+}
+
+
+int __posix_spawnx(pid_t *restrict res, const char *restrict path,
+ int (*exec)(const char *, char *const *, char *const *),
+ const posix_spawn_file_actions_t *fa,
+ const posix_spawnattr_t *restrict attr,
+ char *const argv[restrict], char *const envp[restrict])
+{
+ pid_t pid;
+ char stack[1024];
+ int ec=0, cs;
+ struct args args;
+
+ if (pipe2(args.p, O_CLOEXEC))
+ return errno;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+ args.path = path;
+ args.exec = exec;
+ args.fa = fa;
+ args.attr = attr ? attr : &(const posix_spawnattr_t){0};
+ args.argv = argv;
+ args.envp = envp;
+ pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
+
+ pid = __clone(child, stack+sizeof stack,
+ CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
+ close(args.p[1]);
+
+ if (pid > 0) {
+ if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
+ else waitpid(pid, &(int){0}, 0);
+ } else {
+ ec = -pid;
+ }
+
+ close(args.p[0]);
+
+ if (!ec && res) *res = pid;
+
+ pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
+ pthread_setcancelstate(cs, 0);