Improve kore.proc in the Python API.

Allow passing of an env keyword, allowing you to set environment variables
that may be required by the subprocess.

The env keyword must be a list with correctly formed environment variables.

eg:

proc = kore.proc("/bin/myproc",
    env=[
        "LD_LIBRARY_PATH=/my/path"
    ]
)
This commit is contained in:
Joris Vink 2022-10-19 08:04:16 +02:00
parent eab8dcd9ac
commit dd93790d80
2 changed files with 45 additions and 5 deletions

View File

@ -39,7 +39,6 @@ static PyObject *python_kore_app(PyObject *, PyObject *);
static PyObject *python_kore_log(PyObject *, PyObject *);
static PyObject *python_kore_time(PyObject *, PyObject *);
static PyObject *python_kore_lock(PyObject *, PyObject *);
static PyObject *python_kore_proc(PyObject *, PyObject *);
static PyObject *python_kore_fatal(PyObject *, PyObject *);
static PyObject *python_kore_queue(PyObject *, PyObject *);
static PyObject *python_kore_worker(PyObject *, PyObject *);
@ -56,6 +55,7 @@ static PyObject *python_kore_task_kill(PyObject *, PyObject *);
static PyObject *python_kore_prerequest(PyObject *, PyObject *);
static PyObject *python_kore_task_create(PyObject *, PyObject *);
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
static PyObject *python_kore_proc(PyObject *, PyObject *, PyObject *);
static PyObject *python_kore_route(PyObject *, PyObject *, PyObject *);
static PyObject *python_kore_timer(PyObject *, PyObject *, PyObject *);
static PyObject *python_kore_domain(PyObject *, PyObject *, PyObject *);
@ -92,7 +92,6 @@ static struct PyMethodDef pykore_methods[] = {
METHOD("log", python_kore_log, METH_VARARGS),
METHOD("time", python_kore_time, METH_NOARGS),
METHOD("lock", python_kore_lock, METH_NOARGS),
METHOD("proc", python_kore_proc, METH_VARARGS),
METHOD("queue", python_kore_queue, METH_VARARGS),
METHOD("worker", python_kore_worker, METH_VARARGS),
METHOD("tracer", python_kore_tracer, METH_VARARGS),
@ -109,6 +108,7 @@ static struct PyMethodDef pykore_methods[] = {
METHOD("prerequest", python_kore_prerequest, METH_VARARGS),
METHOD("task_create", python_kore_task_create, METH_VARARGS),
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
METHOD("proc", python_kore_proc, METH_VARARGS | METH_KEYWORDS),
METHOD("route", python_kore_route, METH_VARARGS | METH_KEYWORDS),
METHOD("timer", python_kore_timer, METH_VARARGS | METH_KEYWORDS),
METHOD("domain", python_kore_domain, METH_VARARGS | METH_KEYWORDS),
@ -560,6 +560,8 @@ static PyTypeObject pylock_op_type = {
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
};
#define PYTHON_PROC_MAX_ENV 32
struct pyproc {
PyObject_HEAD
pid_t pid;

View File

@ -72,6 +72,11 @@ struct reqcall {
TAILQ_ENTRY(reqcall) list;
};
union deconst {
char *p;
const char *cp;
};
TAILQ_HEAD(reqcall_list, reqcall);
PyMODINIT_FUNC python_module_init(void);
@ -2722,12 +2727,15 @@ python_kore_timer(PyObject *self, PyObject *args, PyObject *kwargs)
}
static PyObject *
python_kore_proc(PyObject *self, PyObject *args)
python_kore_proc(PyObject *self, PyObject *args, PyObject *kwargs)
{
union deconst cp;
const char *cmd;
struct pyproc *proc;
char *copy, *argv[32], *env[1];
Py_ssize_t idx, len;
PyObject *obj, *item;
int timeo, in_pipe[2], out_pipe[2];
char *copy, *argv[32], *env[PYTHON_PROC_MAX_ENV + 1];
timeo = -1;
@ -2740,6 +2748,37 @@ python_kore_proc(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s|i", &cmd, &timeo))
return (NULL);
if (kwargs != NULL &&
(obj = PyDict_GetItemString(kwargs, "env")) != NULL) {
if (!PyList_CheckExact(obj)) {
PyErr_SetString(PyExc_RuntimeError,
"kore.proc: env is not of type 'list'");
return (NULL);
}
len = PyList_Size(obj);
if (len > PYTHON_PROC_MAX_ENV) {
PyErr_SetString(PyExc_RuntimeError,
"kore.proc: too many entries in 'env' keyword");
return (NULL);
}
for (idx = 0; idx < len; idx++) {
if ((item = PyList_GetItem(obj, idx)) == NULL)
return (NULL);
if (!PyUnicode_CheckExact(item))
return (NULL);
if ((cp.cp = PyUnicode_AsUTF8(item)) == NULL)
return (NULL);
env[idx] = cp.p;
}
env[idx] = NULL;
}
if (pipe(in_pipe) == -1) {
PyErr_SetString(PyExc_RuntimeError, errno_s);
return (NULL);
@ -2796,7 +2835,6 @@ python_kore_proc(PyObject *self, PyObject *args)
dup2(in_pipe[0], STDIN_FILENO) == -1)
fatal("dup2: %s", errno_s);
env[0] = NULL;
copy = kore_strdup(cmd);
python_split_arguments(copy, argv, 32);