[vlc-commits] spawn: provide fallback implementation using fork() & exec()
Rémi Denis-Courmont
git at videolan.org
Sun Sep 20 11:53:11 CEST 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Sep 19 12:53:29 2020 +0300| [6103ed767042ddd765fa1c9e2cee48e8ad843d68] | committer: Rémi Denis-Courmont
spawn: provide fallback implementation using fork() & exec()
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6103ed767042ddd765fa1c9e2cee48e8ad843d68
---
src/posix/spawn.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/src/posix/spawn.c b/src/posix/spawn.c
index 774c6cb6cb..233bb01047 100644
--- a/src/posix/spawn.c
+++ b/src/posix/spawn.c
@@ -115,11 +115,74 @@ out:
#else /* _POSIX_SPAWN */
+#include <vlc_fs.h>
+
static int vlc_spawn_inner(pid_t *restrict pid, const char *path,
const int *fdv, const char *const *argv,
bool search)
{
- (void) pid; (void) path; (void) fdv; (void) argv; (void) search;
+ size_t argc = 0;
+
+ assert(pid != NULL);
+ assert(path != NULL);
+ assert(fdv != NULL);
+ assert(argv != NULL);
+
+ int nulfd = vlc_open("/dev/null", O_RDWR);
+ if (unlikely(nulfd == -1))
+ return errno;
+
+ while (argv[argc++] != NULL);
+
+ char **vargv = malloc(sizeof (*argv) * argc);
+ if (unlikely(vargv == NULL)) {
+ vlc_close(nulfd);
+ return errno;
+ }
+
+ for (size_t i = 0; i < argc; i++)
+ vargv[i] = (char *)argv[i];
+
+ *pid = fork();
+
+ switch (*pid) {
+ case -1:
+ return errno;
+
+ case 0:
+ break;
+
+ default:
+ free(vargv);
+ vlc_close(nulfd);
+ return 0;
+ }
+
+ for (int newfd = 0; newfd < 3 || fdv[newfd] != -1; newfd++) {
+ int oldfd = fdv[newfd];
+
+ if (oldfd == -1)
+ oldfd = nulfd;
+
+ if (oldfd == newfd)
+ fcntl(oldfd, F_SETFD, fcntl(oldfd, F_GETFD) & ~FD_CLOEXEC);
+ else
+ if (dup2(oldfd, newfd) < 0)
+ _exit(1);
+ }
+
+ sigset_t set;
+
+ sigemptyset(&set);
+ pthread_sigmask(SIG_SETMASK, &set, NULL);
+ signal(SIGPIPE, SIG_DFL);
+
+ if (search)
+ execvp(path, vargv);
+ else
+ execv(path, vargv);
+
+ _exit(1);
}
#endif /* _POSIX_SPAWN */
More information about the vlc-commits
mailing list