spawn: move argument parser from iptv_pipe
This commit is contained in:
parent
bd20a5393c
commit
bb31907761
3 changed files with 91 additions and 73 deletions
|
@ -32,88 +32,30 @@
|
|||
* Connect UDP/RTP
|
||||
*/
|
||||
static int
|
||||
iptv_pipe_start ( iptv_mux_t *im, const char *_raw, const url_t *url )
|
||||
iptv_pipe_start ( iptv_mux_t *im, const char *raw, const url_t *url )
|
||||
{
|
||||
char *argv[64], *envp[32], *f, *raw, *s, *p, *a;
|
||||
int i = 1, rd;
|
||||
char **argv = NULL, **envp = NULL;
|
||||
const char *replace[] = { "${service_name}", im->mm_iptv_svcname ?: "", NULL };
|
||||
int rd;
|
||||
pid_t pid;
|
||||
|
||||
if (strncmp(_raw, "pipe://", 7))
|
||||
return -1;
|
||||
if (strncmp(raw, "pipe://", 7))
|
||||
goto err;
|
||||
|
||||
s = raw = tvh_strdupa(_raw + 7);
|
||||
if (spawn_parse_args(&argv, 64, raw + 7, replace))
|
||||
goto err;
|
||||
|
||||
argv[0] = NULL;
|
||||
if (spawn_parse_args(&envp, 64, im->mm_iptv_env ?: "", NULL))
|
||||
goto err;
|
||||
|
||||
while (*s && *s != ' ')
|
||||
s++;
|
||||
if (*s == ' ') {
|
||||
*(char *)s = '\0';
|
||||
s++;
|
||||
}
|
||||
|
||||
while (*s && i < ARRAY_SIZE(argv) - 1) {
|
||||
f = s;
|
||||
while (*s && *s != ' ') {
|
||||
while (*s && *s != ' ' && *s != '\\')
|
||||
s++;
|
||||
if (*s == '\\') {
|
||||
memmove(s, s + 1, strlen(s));
|
||||
if (*s)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (f != s) {
|
||||
if (*s) {
|
||||
*(char *)s = '\0';
|
||||
s++;
|
||||
}
|
||||
p = strstr(f, "${service_name}");
|
||||
if (p) {
|
||||
a = alloca(strlen(f) + strlen(im->mm_iptv_svcname ?: ""));
|
||||
*p = '\0';
|
||||
strcpy(a, f);
|
||||
strcat(a, im->mm_iptv_svcname ?: "");
|
||||
strcat(a, p + 15);
|
||||
f = a;
|
||||
}
|
||||
argv[i++] = f;
|
||||
}
|
||||
}
|
||||
argv[i] = NULL;
|
||||
|
||||
s = im->mm_iptv_env ? tvh_strdupa(im->mm_iptv_env) : (char *)"";
|
||||
i = 0;
|
||||
while (*s && i < ARRAY_SIZE(envp) - 1) {
|
||||
f = s;
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
if (*s != '=')
|
||||
break;
|
||||
while (*s && *s != ' ') {
|
||||
while (*s && *s != ' ' && *s != '\\')
|
||||
s++;
|
||||
if (*s == '\\') {
|
||||
memmove(s, s + 1, strlen(s));
|
||||
if (*s)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (f != s) {
|
||||
if (*s) {
|
||||
*s = '\0';
|
||||
s++;
|
||||
}
|
||||
envp[i++] = f;
|
||||
}
|
||||
}
|
||||
envp[i] = NULL;
|
||||
|
||||
if (spawn_and_give_stdout(raw, argv, envp, &rd, &pid, 1)) {
|
||||
if (spawn_and_give_stdout(argv[0], argv, envp, &rd, &pid, 1)) {
|
||||
tvherror("iptv", "Unable to start pipe '%s' (wrong executable?)", raw);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
spawn_free_args(argv);
|
||||
spawn_free_args(envp);
|
||||
|
||||
fcntl(rd, F_SETFD, fcntl(rd, F_GETFD) | FD_CLOEXEC);
|
||||
fcntl(rd, F_SETFL, fcntl(rd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
|
@ -125,6 +67,13 @@ iptv_pipe_start ( iptv_mux_t *im, const char *_raw, const url_t *url )
|
|||
if (url)
|
||||
iptv_input_mux_started(im);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (argv)
|
||||
spawn_free_args(argv);
|
||||
if (envp)
|
||||
spawn_free_args(envp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
65
src/spawn.c
65
src/spawn.c
|
@ -324,6 +324,71 @@ spawn_enq(const char *name, int pid)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int
|
||||
spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace)
|
||||
{
|
||||
char *s, *f, *p, *a;
|
||||
const char **r;
|
||||
int i = 0, l;
|
||||
|
||||
if (!argv || !cmd)
|
||||
return -1;
|
||||
|
||||
s = tvh_strdupa(cmd);
|
||||
*argv = calloc(argc, sizeof(char *));
|
||||
|
||||
while (*s && i < argc - 1) {
|
||||
f = s;
|
||||
while (*s && *s != ' ') {
|
||||
while (*s && *s != ' ' && *s != '\\')
|
||||
s++;
|
||||
if (*s == '\\') {
|
||||
memmove(s, s + 1, strlen(s));
|
||||
if (*s)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (f != s) {
|
||||
if (*s) {
|
||||
*(char *)s = '\0';
|
||||
s++;
|
||||
}
|
||||
for (r = replace; r && *r; r += 2) {
|
||||
p = strstr(f, *r);
|
||||
if (p) {
|
||||
l = strlen(*r);
|
||||
a = malloc(strlen(f) + strlen(r[1]) + 1);
|
||||
*p = '\0';
|
||||
strcpy(a, f);
|
||||
strcat(a, r[1]);
|
||||
strcat(a, p + l);
|
||||
*argv[i++] = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (r && *r)
|
||||
continue;
|
||||
(*argv)[i++] = strdup(f);
|
||||
}
|
||||
}
|
||||
(*argv)[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
spawn_free_args(char **argv)
|
||||
{
|
||||
char **a = argv;
|
||||
for (; *a; a++)
|
||||
free(*a);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given program and return its standard output as file-descriptor (pipe).
|
||||
|
|
|
@ -25,6 +25,10 @@ void spawn_error ( const char *fmt, ... );
|
|||
|
||||
int find_exec ( const char *name, char *out, size_t len );
|
||||
|
||||
int spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace);
|
||||
|
||||
void spawn_free_args(char **argv);
|
||||
|
||||
int spawn_and_give_stdout(const char *prog, char *argv[], char *envp[],
|
||||
int *rd, pid_t *pid, int redir_stderr);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue