mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-01-10 23:38:26 -05:00
libobs: Add os_process_pipe_create2
This new API uses the os_process_args_t object rather than a string for more safe and sane command line argument handling.
This commit is contained in:
@@ -31,14 +31,14 @@ struct os_process_pipe {
|
||||
FILE *err_file;
|
||||
};
|
||||
|
||||
os_process_pipe_t *os_process_pipe_create(const char *cmd_line,
|
||||
const char *type)
|
||||
os_process_pipe_t *os_process_pipe_create_internal(const char *bin, char **argv,
|
||||
const char *type)
|
||||
{
|
||||
struct os_process_pipe process_pipe = {0};
|
||||
struct os_process_pipe *out;
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
|
||||
if (!cmd_line || !type) {
|
||||
if (!bin || !argv || !type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -94,9 +94,8 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line,
|
||||
STDERR_FILENO);
|
||||
|
||||
int pid;
|
||||
char *argv[4] = {"sh", "-c", (char *)cmd_line, NULL};
|
||||
|
||||
int ret = posix_spawn(&pid, "/bin/sh", &file_actions, NULL, argv, NULL);
|
||||
int ret = posix_spawn(&pid, bin, &file_actions, NULL,
|
||||
(char *const *)argv, NULL);
|
||||
|
||||
posix_spawn_file_actions_destroy(&file_actions);
|
||||
|
||||
@@ -127,6 +126,23 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line,
|
||||
return out;
|
||||
}
|
||||
|
||||
os_process_pipe_t *os_process_pipe_create(const char *cmd_line,
|
||||
const char *type)
|
||||
{
|
||||
if (!cmd_line)
|
||||
return NULL;
|
||||
|
||||
char *argv[3] = {"-c", (char *)cmd_line, NULL};
|
||||
return os_process_pipe_create_internal("/bin/sh", argv, type);
|
||||
}
|
||||
|
||||
os_process_pipe_t *os_process_pipe_create2(const os_process_args_t *args,
|
||||
const char *type)
|
||||
{
|
||||
char **argv = os_process_args_get_argv(args);
|
||||
return os_process_pipe_create_internal(argv[0], argv, type);
|
||||
}
|
||||
|
||||
int os_process_pipe_destroy(os_process_pipe_t *pp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "platform.h"
|
||||
#include "bmem.h"
|
||||
#include "dstr.h"
|
||||
#include "pipe.h"
|
||||
|
||||
struct os_process_pipe {
|
||||
@@ -145,6 +146,69 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void add_backslashes(struct dstr *str, size_t count)
|
||||
{
|
||||
while (count--)
|
||||
dstr_cat_ch(str, '\\');
|
||||
}
|
||||
|
||||
os_process_pipe_t *os_process_pipe_create2(const os_process_args_t *args,
|
||||
const char *type)
|
||||
{
|
||||
struct dstr cmd_line = {0};
|
||||
|
||||
/* Convert list to command line as Windows does not have any API that
|
||||
* allows us to just pass argc/argv. */
|
||||
char **argv = os_process_args_get_argv(args);
|
||||
|
||||
/* Based on Python subprocess module implementation. */
|
||||
while (*argv) {
|
||||
size_t bs_count = 0;
|
||||
const char *arg = *argv;
|
||||
bool needs_quotes = strlen(arg) == 0 ||
|
||||
strstr(arg, " ") != NULL ||
|
||||
strstr(arg, "\t") != NULL;
|
||||
|
||||
if (cmd_line.len)
|
||||
dstr_cat_ch(&cmd_line, ' ');
|
||||
if (needs_quotes)
|
||||
dstr_cat_ch(&cmd_line, '"');
|
||||
|
||||
while (*arg) {
|
||||
if (*arg == '\\') {
|
||||
bs_count++;
|
||||
} else if (*arg == '"') {
|
||||
add_backslashes(&cmd_line, bs_count * 2);
|
||||
dstr_cat(&cmd_line, "\\\"");
|
||||
bs_count = 0;
|
||||
} else {
|
||||
if (bs_count) {
|
||||
add_backslashes(&cmd_line, bs_count);
|
||||
bs_count = 0;
|
||||
}
|
||||
dstr_cat_ch(&cmd_line, *arg);
|
||||
}
|
||||
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (bs_count)
|
||||
add_backslashes(&cmd_line, bs_count);
|
||||
|
||||
if (needs_quotes) {
|
||||
add_backslashes(&cmd_line, bs_count);
|
||||
dstr_cat_ch(&cmd_line, '"');
|
||||
}
|
||||
|
||||
argv++;
|
||||
}
|
||||
|
||||
os_process_pipe_t *ret = os_process_pipe_create(cmd_line.array, type);
|
||||
|
||||
dstr_free(&cmd_line);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int os_process_pipe_destroy(os_process_pipe_t *pp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef struct os_process_args os_process_args_t;
|
||||
|
||||
EXPORT os_process_pipe_t *os_process_pipe_create(const char *cmd_line,
|
||||
const char *type);
|
||||
EXPORT os_process_pipe_t *os_process_pipe_create2(const os_process_args_t *args,
|
||||
const char *type);
|
||||
EXPORT int os_process_pipe_destroy(os_process_pipe_t *pp);
|
||||
|
||||
EXPORT size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data,
|
||||
|
||||
Reference in New Issue
Block a user