mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
rework SystemExec - use vfork wrapper (and lots of related stuff)
This commit is contained in:
parent
f48b556888
commit
543099afba
16 changed files with 240 additions and 40 deletions
101
libs/vfork/exec_wrapper.c
Normal file
101
libs/vfork/exec_wrapper.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
#ifndef STDERR_FILENO
|
||||
#define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
static void close_fd (int *fd) { if ((*fd) >= 0) close (*fd); *fd = -1; }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 10) {
|
||||
// TODO: if argv > 3, assume pok[] is given, notifify parent.
|
||||
// usage() and a man-page (help2man) would not be bad, either :)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pok[2];
|
||||
int pin[2];
|
||||
int pout[2];
|
||||
|
||||
pok[0] = atoi(argv[1]);
|
||||
pok[1] = atoi(argv[2]);
|
||||
pin[0] = atoi(argv[3]);
|
||||
pin[1] = atoi(argv[4]);
|
||||
pout[0] = atoi(argv[5]);
|
||||
pout[1] = atoi(argv[6]);
|
||||
|
||||
int stderr_mode = atoi(argv[7]);
|
||||
int nicelevel = atoi(argv[8]);
|
||||
|
||||
/* vfork()ed child process - exec external process */
|
||||
close_fd(&pok[0]);
|
||||
fcntl(pok[1], F_SETFD, FD_CLOEXEC);
|
||||
|
||||
close_fd(&pin[1]);
|
||||
if (pin[0] != STDIN_FILENO) {
|
||||
dup2(pin[0], STDIN_FILENO);
|
||||
}
|
||||
close_fd(&pin[0]);
|
||||
close_fd(&pout[0]);
|
||||
if (pout[1] != STDOUT_FILENO) {
|
||||
dup2(pout[1], STDOUT_FILENO);
|
||||
}
|
||||
|
||||
if (stderr_mode == 2) {
|
||||
/* merge STDERR into output */
|
||||
if (pout[1] != STDERR_FILENO) {
|
||||
dup2(pout[1], STDERR_FILENO);
|
||||
}
|
||||
} else if (stderr_mode == 1) {
|
||||
/* ignore STDERR */
|
||||
close(STDERR_FILENO);
|
||||
} else {
|
||||
/* keep STDERR */
|
||||
}
|
||||
|
||||
if (pout[1] != STDOUT_FILENO && pout[1] != STDERR_FILENO) {
|
||||
close_fd(&pout[1]);
|
||||
}
|
||||
|
||||
if (nicelevel !=0) {
|
||||
nice(nicelevel);
|
||||
}
|
||||
|
||||
/* copy current environment */
|
||||
char **envp = NULL;
|
||||
int i=0;
|
||||
envp = (char **) calloc(1, sizeof(char*));
|
||||
for (i=0;environ[i];++i) {
|
||||
envp[i] = strdup(environ[i]);
|
||||
envp = (char **) realloc(envp, (i+2) * sizeof(char*));
|
||||
}
|
||||
envp[i] = 0;
|
||||
|
||||
#ifdef HAVE_SIGSET
|
||||
sigset(SIGPIPE, SIG_DFL);
|
||||
#else
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
#endif
|
||||
|
||||
/* all systems go */
|
||||
execve(argv[9], &argv[9], envp);
|
||||
|
||||
/* if we reach here something went wrong.. */
|
||||
char buf = 0;
|
||||
(void) write(pok[1], &buf, 1 );
|
||||
close_fd(&pok[1]);
|
||||
exit(-1);
|
||||
return -1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue