Quoting Stéphane Graber (stgra...@ubuntu.com): > This properly regroups the module functions together and then sorts all > other functions alphabetically to match the function and property lists. > > Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com> > --- > src/python-lxc/lxc.c | 709 > ++++++++++++++++++++++++++------------------------- > 1 file changed, 357 insertions(+), 352 deletions(-) > > diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c > index 0604ec7..1ed8cbe 100644 > --- a/src/python-lxc/lxc.c > +++ b/src/python-lxc/lxc.c > @@ -31,10 +31,7 @@ > #include <stdio.h> > #include <sys/wait.h> > > -typedef struct { > - PyObject_HEAD > - struct lxc_container *container; > -} Container; > +/* Helper functions */ > > char** > convert_tuple_to_char_pointer_array(PyObject *argv) { > @@ -113,50 +110,218 @@ error: > return NULL; > } > > -static void > -Container_dealloc(Container* self) > +struct lxc_attach_python_payload { > + PyObject *fn; > + PyObject *arg; > +}; > + > +static int lxc_attach_python_exec(void* _payload) > { > - lxc_container_put(self->container); > - Py_TYPE(self)->tp_free((PyObject*)self); > + struct lxc_attach_python_payload *payload = > + (struct lxc_attach_python_payload *)_payload; > + PyObject *result = PyObject_CallFunctionObjArgs(payload->fn, > + payload->arg, NULL); > + > + if (!result) { > + PyErr_Print(); > + return -1; > + } > + if (PyLong_Check(result)) > + return (int)PyLong_AsLong(result); > + else > + return -1; > } > > -static PyObject * > -Container_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > +static void lxc_attach_free_options(lxc_attach_options_t *options); > + > +static lxc_attach_options_t *lxc_attach_parse_options(PyObject *kwds) > { > - Container *self; > + static char *kwlist[] = {"attach_flags", "namespaces", "personality", > + "initial_cwd", "uid", "gid", "env_policy", > + "extra_env_vars", "extra_keep_env", "stdin", > + "stdout", "stderr", NULL}; > + long temp_uid, temp_gid; > + int temp_env_policy; > + PyObject *extra_env_vars_obj = NULL; > + PyObject *extra_keep_env_obj = NULL; > + PyObject *stdin_obj = NULL; > + PyObject *stdout_obj = NULL; > + PyObject *stderr_obj = NULL; > + PyObject *initial_cwd_obj = NULL; > + PyObject *dummy; > + bool parse_result; > > - self = (Container *)type->tp_alloc(type, 0); > + lxc_attach_options_t default_options = LXC_ATTACH_OPTIONS_DEFAULT; > + lxc_attach_options_t *options = malloc(sizeof(*options)); > > - return (PyObject *)self; > + if (!options) { > + PyErr_SetNone(PyExc_MemoryError); > + return NULL; > + } > + memcpy(options, &default_options, sizeof(*options)); > + > + /* we need some dummy variables because we can't be sure > + * the data types match completely */ > + temp_uid = -1; > + temp_gid = -1; > + temp_env_policy = options->env_policy; > + > + /* we need a dummy tuple */ > + dummy = PyTuple_New(0); > + > + parse_result = PyArg_ParseTupleAndKeywords(dummy, kwds, "|iilO&lliOOOOO", > + kwlist, > &options->attach_flags, > + &options->namespaces, > + &options->personality, > + PyUnicode_FSConverter, > + &initial_cwd_obj, &temp_uid, > + &temp_gid, &temp_env_policy, > + &extra_env_vars_obj, > + &extra_keep_env_obj, > + &stdin_obj, &stdout_obj, > + &stderr_obj); > + > + /* immediately get rid of the dummy tuple */ > + Py_DECREF(dummy); > + > + if (!parse_result) { > + lxc_attach_free_options(options); > + return NULL; > + } > + > + /* duplicate the string, so we don't depend on some random Python object > */ > + if (initial_cwd_obj != NULL) { > + options->initial_cwd = strndup(PyBytes_AsString(initial_cwd_obj), > + PyBytes_Size(initial_cwd_obj)); > + Py_DECREF(initial_cwd_obj); > + } > + > + /* do the type conversion from the types that match the parse string */ > + if (temp_uid != -1) options->uid = (uid_t)temp_uid; > + if (temp_gid != -1) options->gid = (gid_t)temp_gid; > + options->env_policy = (lxc_attach_env_policy_t)temp_env_policy; > + > + if (extra_env_vars_obj) > + options->extra_env_vars = > + convert_tuple_to_char_pointer_array(extra_env_vars_obj); > + if (extra_keep_env_obj) > + options->extra_keep_env = > + convert_tuple_to_char_pointer_array(extra_keep_env_obj); > + if (stdin_obj) { > + options->stdin_fd = PyObject_AsFileDescriptor(stdin_obj); > + if (options->stdin_fd < 0) { > + lxc_attach_free_options(options); > + return NULL; > + } > + } > + if (stdout_obj) { > + options->stdout_fd = PyObject_AsFileDescriptor(stdout_obj); > + if (options->stdout_fd < 0) { > + lxc_attach_free_options(options); > + return NULL; > + } > + } > + if (stderr_obj) { > + options->stderr_fd = PyObject_AsFileDescriptor(stderr_obj); > + if (options->stderr_fd < 0) { > + lxc_attach_free_options(options); > + return NULL; > + } > + } > + > + return options; > } > > -static int > -Container_init(Container *self, PyObject *args, PyObject *kwds) > +void lxc_attach_free_options(lxc_attach_options_t *options) > { > - static char *kwlist[] = {"name", "config_path", NULL}; > - char *name = NULL; > - PyObject *fs_config_path = NULL; > - char *config_path = NULL; > + int i; > + if (!options) > + return; > + if (options->initial_cwd) > + free(options->initial_cwd); > + if (options->extra_env_vars) { > + for (i = 0; options->extra_env_vars[i]; i++) > + free(options->extra_env_vars[i]); > + free(options->extra_env_vars); > + } > + if (options->extra_keep_env) { > + for (i = 0; options->extra_keep_env[i]; i++) > + free(options->extra_keep_env[i]); > + free(options->extra_keep_env); > + } > + free(options); > +} > > - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist, > - &name, > - PyUnicode_FSConverter, > &fs_config_path)) > - return -1; > +/* Module functions */ > +static PyObject * > +LXC_arch_to_personality(PyObject *self, PyObject *arg) > +{ > + long rv = -1; > + PyObject *pystr; > + char *str; > > - if (fs_config_path != NULL) { > - config_path = PyBytes_AS_STRING(fs_config_path); > - assert(config_path != NULL); > + if (!PyUnicode_Check(arg)) { > + PyErr_SetString(PyExc_ValueError, "Expected a string"); > + return NULL; > } > > - self->container = lxc_container_new(name, config_path); > - if (!self->container) { > - Py_XDECREF(fs_config_path); > - fprintf(stderr, "%d: error creating container %s\n", __LINE__, name); > - return -1; > + pystr = PyUnicode_AsUTF8String(arg); > + if (!pystr) > + return NULL; > + > + str = PyBytes_AsString(pystr); > + if (!str) > + goto out; > + > + rv = lxc_config_parse_arch(str); > + if (rv == -1) > + PyErr_SetString(PyExc_KeyError, "Failed to lookup architecture."); > + > +out: > + Py_DECREF(pystr); > + return rv == -1 ? NULL : PyLong_FromLong(rv); > +} > + > +static PyObject * > +LXC_attach_run_command(PyObject *self, PyObject *arg) > +{ > + PyObject *args_obj = NULL; > + int i, rv; > + lxc_attach_command_t cmd = { > + NULL, /* program */ > + NULL /* argv[] */ > + }; > + > + if (!PyArg_ParseTuple(arg, "sO", (const char**)&cmd.program, &args_obj)) > + return NULL; > + if (args_obj && PyList_Check(args_obj)) { > + cmd.argv = convert_tuple_to_char_pointer_array(args_obj); > + } else { > + PyErr_Format(PyExc_TypeError, "Second part of tuple passed to " > + "attach_run_command must be a list."); > + return NULL; > } > > - Py_XDECREF(fs_config_path); > - return 0; > + if (!cmd.argv) > + return NULL; > + > + rv = lxc_attach_run_command(&cmd); > + > + for (i = 0; cmd.argv[i]; i++) > + free(cmd.argv[i]); > + free(cmd.argv); > + > + return PyLong_FromLong(rv); > +} > + > +static PyObject * > +LXC_attach_run_shell(PyObject *self, PyObject *arg) > +{ > + int rv; > + > + rv = lxc_attach_run_shell(NULL); > + > + return PyLong_FromLong(rv); > } > > static PyObject * > @@ -230,29 +395,81 @@ LXC_list_containers(PyObject *self, PyObject *args, > PyObject *kwds) > return list; > } > > -// Container properties > -static PyObject * > -Container_config_file_name(Container *self, void *closure) > -{ > - return PyUnicode_FromString( > - self->container->config_file_name(self->container)); > -} > +/* Base type and functions for Container */ > +typedef struct { > + PyObject_HEAD > + struct lxc_container *container; > +} Container; > > -static PyObject * > -Container_defined(Container *self, void *closure) > +static void > +Container_dealloc(Container* self) > { > - if (self->container->is_defined(self->container)) { > - Py_RETURN_TRUE; > - } > - > - Py_RETURN_FALSE; > + lxc_container_put(self->container); > + Py_TYPE(self)->tp_free((PyObject*)self); > } > > -static PyObject * > -Container_init_pid(Container *self, void *closure) > +static int > +Container_init(Container *self, PyObject *args, PyObject *kwds) > { > - return PyLong_FromLong(self->container->init_pid(self->container)); > -} > + static char *kwlist[] = {"name", "config_path", NULL}; > + char *name = NULL; > + PyObject *fs_config_path = NULL; > + char *config_path = NULL; > + > + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist, > + &name, > + PyUnicode_FSConverter, > &fs_config_path)) > + return -1; > + > + if (fs_config_path != NULL) { > + config_path = PyBytes_AS_STRING(fs_config_path); > + assert(config_path != NULL); > + } > + > + self->container = lxc_container_new(name, config_path); > + if (!self->container) { > + Py_XDECREF(fs_config_path); > + fprintf(stderr, "%d: error creating container %s\n", __LINE__, name); > + return -1; > + } > + > + Py_XDECREF(fs_config_path); > + return 0; > +} > + > +static PyObject * > +Container_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > +{ > + Container *self; > + > + self = (Container *)type->tp_alloc(type, 0); > + > + return (PyObject *)self; > +} > + > +/* Container properties */ > +static PyObject * > +Container_config_file_name(Container *self, void *closure) > +{ > + return PyUnicode_FromString( > + self->container->config_file_name(self->container)); > +} > + > +static PyObject * > +Container_defined(Container *self, void *closure) > +{ > + if (self->container->is_defined(self->container)) { > + Py_RETURN_TRUE; > + } > + > + Py_RETURN_FALSE; > +} > + > +static PyObject * > +Container_init_pid(Container *self, void *closure) > +{ > + return PyLong_FromLong(self->container->init_pid(self->container)); > +} > > static PyObject * > Container_name(Container *self, void *closure) > @@ -276,7 +493,58 @@ Container_state(Container *self, void *closure) > return PyUnicode_FromString(self->container->state(self->container)); > } > > -// Container Functions > +/* Container Functions */ > +static PyObject * > +Container_attach_and_possibly_wait(Container *self, PyObject *args, > + PyObject *kwds, int wait) > +{ > + struct lxc_attach_python_payload payload = { NULL, NULL }; > + lxc_attach_options_t *options = NULL; > + long ret; > + pid_t pid; > + > + if (!PyArg_ParseTuple(args, "O|O", &payload.fn, &payload.arg)) > + return NULL; > + if (!PyCallable_Check(payload.fn)) { > + PyErr_Format(PyExc_TypeError, "attach: object not callable"); > + return NULL; > + } > + > + options = lxc_attach_parse_options(kwds); > + if (!options) > + return NULL; > + > + ret = self->container->attach(self->container, lxc_attach_python_exec, > + &payload, options, &pid); > + if (ret < 0) > + goto out; > + > + if (wait) { > + ret = lxc_wait_for_pid_status(pid); > + /* handle case where attach fails */ > + if (WIFEXITED(ret) && WEXITSTATUS(ret) == 255) > + ret = -1; > + } else { > + ret = (long)pid; > + } > + > +out: > + lxc_attach_free_options(options); > + return PyLong_FromLong(ret); > +} > + > +static PyObject * > +Container_attach(Container *self, PyObject *args, PyObject *kwds) > +{ > + return Container_attach_and_possibly_wait(self, args, kwds, 0); > +} > + > +static PyObject * > +Container_attach_wait(Container *self, PyObject *args, PyObject *kwds) > +{ > + return Container_attach_and_possibly_wait(self, args, kwds, 1); > +} > + > static PyObject * > Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds) > { > @@ -295,6 +563,42 @@ Container_clear_config_item(Container *self, PyObject > *args, PyObject *kwds) > } > > static PyObject * > +Container_console(Container *self, PyObject *args, PyObject *kwds) > +{ > + static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd", > + "escape", NULL}; > + int ttynum = -1, stdinfd = 0, stdoutfd = 1, stderrfd = 2, escape = 1; > + > + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iiiii", kwlist, > + &ttynum, &stdinfd, &stdoutfd, > &stderrfd, > + &escape)) > + return NULL; > + > + if (self->container->console(self->container, ttynum, > + stdinfd, stdoutfd, stderrfd, escape) == 0) { > + Py_RETURN_TRUE; > + } > + Py_RETURN_FALSE; > +} > + > +static PyObject * > +Container_console_getfd(Container *self, PyObject *args, PyObject *kwds) > +{ > + static char *kwlist[] = {"ttynum", NULL}; > + int ttynum = -1, masterfd; > + > + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &ttynum)) > + return NULL; > + > + if (self->container->console_getfd(self->container, &ttynum, > + &masterfd) < 0) { > + PyErr_SetString(PyExc_ValueError, "Unable to allocate tty"); > + return NULL; > + } > + return PyLong_FromLong(masterfd); > +} > + > +static PyObject * > Container_create(Container *self, PyObject *args, PyObject *kwds) > { > char* template_name = NULL; > @@ -766,42 +1070,6 @@ Container_unfreeze(Container *self, PyObject *args, > PyObject *kwds) > } > > static PyObject * > -Container_console(Container *self, PyObject *args, PyObject *kwds) > -{ > - static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd", > - "escape", NULL}; > - int ttynum = -1, stdinfd = 0, stdoutfd = 1, stderrfd = 2, escape = 1; > - > - if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iiiii", kwlist, > - &ttynum, &stdinfd, &stdoutfd, > &stderrfd, > - &escape)) > - return NULL; > - > - if (self->container->console(self->container, ttynum, > - stdinfd, stdoutfd, stderrfd, escape) == 0) { > - Py_RETURN_TRUE; > - } > - Py_RETURN_FALSE; > -} > - > -static PyObject * > -Container_console_getfd(Container *self, PyObject *args, PyObject *kwds) > -{ > - static char *kwlist[] = {"ttynum", NULL}; > - int ttynum = -1, masterfd; > - > - if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &ttynum)) > - return NULL; > - > - if (self->container->console_getfd(self->container, &ttynum, > - &masterfd) < 0) { > - PyErr_SetString(PyExc_ValueError, "Unable to allocate tty"); > - return NULL; > - } > - return PyLong_FromLong(masterfd); > -} > - > -static PyObject * > Container_wait(Container *self, PyObject *args, PyObject *kwds) > { > static char *kwlist[] = {"state", "timeout", NULL}; > @@ -819,270 +1087,7 @@ Container_wait(Container *self, PyObject *args, > PyObject *kwds) > Py_RETURN_FALSE; > } > > -struct lxc_attach_python_payload { > - PyObject *fn; > - PyObject *arg; > -}; > - > -static int lxc_attach_python_exec(void* _payload) > -{ > - struct lxc_attach_python_payload *payload = > - (struct lxc_attach_python_payload *)_payload; > - PyObject *result = PyObject_CallFunctionObjArgs(payload->fn, > - payload->arg, NULL); > - > - if (!result) { > - PyErr_Print(); > - return -1; > - } > - if (PyLong_Check(result)) > - return (int)PyLong_AsLong(result); > - else > - return -1; > -} > - > -static void lxc_attach_free_options(lxc_attach_options_t *options); > - > -static lxc_attach_options_t *lxc_attach_parse_options(PyObject *kwds) > -{ > - static char *kwlist[] = {"attach_flags", "namespaces", "personality", > - "initial_cwd", "uid", "gid", "env_policy", > - "extra_env_vars", "extra_keep_env", "stdin", > - "stdout", "stderr", NULL}; > - long temp_uid, temp_gid; > - int temp_env_policy; > - PyObject *extra_env_vars_obj = NULL; > - PyObject *extra_keep_env_obj = NULL; > - PyObject *stdin_obj = NULL; > - PyObject *stdout_obj = NULL; > - PyObject *stderr_obj = NULL; > - PyObject *initial_cwd_obj = NULL; > - PyObject *dummy; > - bool parse_result; > - > - lxc_attach_options_t default_options = LXC_ATTACH_OPTIONS_DEFAULT; > - lxc_attach_options_t *options = malloc(sizeof(*options)); > - > - if (!options) { > - PyErr_SetNone(PyExc_MemoryError); > - return NULL; > - } > - memcpy(options, &default_options, sizeof(*options)); > - > - /* we need some dummy variables because we can't be sure > - * the data types match completely */ > - temp_uid = -1; > - temp_gid = -1; > - temp_env_policy = options->env_policy; > - > - /* we need a dummy tuple */ > - dummy = PyTuple_New(0); > - > - parse_result = PyArg_ParseTupleAndKeywords(dummy, kwds, "|iilO&lliOOOOO", > - kwlist, > &options->attach_flags, > - &options->namespaces, > - &options->personality, > - PyUnicode_FSConverter, > - &initial_cwd_obj, &temp_uid, > - &temp_gid, &temp_env_policy, > - &extra_env_vars_obj, > - &extra_keep_env_obj, > - &stdin_obj, &stdout_obj, > - &stderr_obj); > - > - /* immediately get rid of the dummy tuple */ > - Py_DECREF(dummy); > - > - if (!parse_result) { > - lxc_attach_free_options(options); > - return NULL; > - } > - > - /* duplicate the string, so we don't depend on some random Python object > */ > - if (initial_cwd_obj != NULL) { > - options->initial_cwd = strndup(PyBytes_AsString(initial_cwd_obj), > - PyBytes_Size(initial_cwd_obj)); > - Py_DECREF(initial_cwd_obj); > - } > - > - /* do the type conversion from the types that match the parse string */ > - if (temp_uid != -1) options->uid = (uid_t)temp_uid; > - if (temp_gid != -1) options->gid = (gid_t)temp_gid; > - options->env_policy = (lxc_attach_env_policy_t)temp_env_policy; > - > - if (extra_env_vars_obj) > - options->extra_env_vars = > - convert_tuple_to_char_pointer_array(extra_env_vars_obj); > - if (extra_keep_env_obj) > - options->extra_keep_env = > - convert_tuple_to_char_pointer_array(extra_keep_env_obj); > - if (stdin_obj) { > - options->stdin_fd = PyObject_AsFileDescriptor(stdin_obj); > - if (options->stdin_fd < 0) { > - lxc_attach_free_options(options); > - return NULL; > - } > - } > - if (stdout_obj) { > - options->stdout_fd = PyObject_AsFileDescriptor(stdout_obj); > - if (options->stdout_fd < 0) { > - lxc_attach_free_options(options); > - return NULL; > - } > - } > - if (stderr_obj) { > - options->stderr_fd = PyObject_AsFileDescriptor(stderr_obj); > - if (options->stderr_fd < 0) { > - lxc_attach_free_options(options); > - return NULL; > - } > - } > - > - return options; > -} > - > -void lxc_attach_free_options(lxc_attach_options_t *options) > -{ > - int i; > - if (!options) > - return; > - if (options->initial_cwd) > - free(options->initial_cwd); > - if (options->extra_env_vars) { > - for (i = 0; options->extra_env_vars[i]; i++) > - free(options->extra_env_vars[i]); > - free(options->extra_env_vars); > - } > - if (options->extra_keep_env) { > - for (i = 0; options->extra_keep_env[i]; i++) > - free(options->extra_keep_env[i]); > - free(options->extra_keep_env); > - } > - free(options); > -} > - > -static PyObject * > -Container_attach_and_possibly_wait(Container *self, PyObject *args, > - PyObject *kwds, int wait) > -{ > - struct lxc_attach_python_payload payload = { NULL, NULL }; > - lxc_attach_options_t *options = NULL; > - long ret; > - pid_t pid; > - > - if (!PyArg_ParseTuple(args, "O|O", &payload.fn, &payload.arg)) > - return NULL; > - if (!PyCallable_Check(payload.fn)) { > - PyErr_Format(PyExc_TypeError, "attach: object not callable"); > - return NULL; > - } > - > - options = lxc_attach_parse_options(kwds); > - if (!options) > - return NULL; > - > - ret = self->container->attach(self->container, lxc_attach_python_exec, > - &payload, options, &pid); > - if (ret < 0) > - goto out; > - > - if (wait) { > - ret = lxc_wait_for_pid_status(pid); > - /* handle case where attach fails */ > - if (WIFEXITED(ret) && WEXITSTATUS(ret) == 255) > - ret = -1; > - } else { > - ret = (long)pid; > - } > - > -out: > - lxc_attach_free_options(options); > - return PyLong_FromLong(ret); > -} > - > -static PyObject * > -Container_attach(Container *self, PyObject *args, PyObject *kwds) > -{ > - return Container_attach_and_possibly_wait(self, args, kwds, 0); > -} > - > -static PyObject * > -Container_attach_wait(Container *self, PyObject *args, PyObject *kwds) > -{ > - return Container_attach_and_possibly_wait(self, args, kwds, 1); > -} > - > -static PyObject * > -LXC_attach_run_shell(PyObject *self, PyObject *arg) > -{ > - int rv; > - > - rv = lxc_attach_run_shell(NULL); > - > - return PyLong_FromLong(rv); > -} > - > -static PyObject * > -LXC_arch_to_personality(PyObject *self, PyObject *arg) > -{ > - long rv = -1; > - PyObject *pystr; > - char *str; > - > - if (!PyUnicode_Check(arg)) { > - PyErr_SetString(PyExc_ValueError, "Expected a string"); > - return NULL; > - } > - > - pystr = PyUnicode_AsUTF8String(arg); > - if (!pystr) > - return NULL; > - > - str = PyBytes_AsString(pystr); > - if (!str) > - goto out; > - > - rv = lxc_config_parse_arch(str); > - if (rv == -1) > - PyErr_SetString(PyExc_KeyError, "Failed to lookup architecture."); > - > -out: > - Py_DECREF(pystr); > - return rv == -1 ? NULL : PyLong_FromLong(rv); > -} > - > -static PyObject * > -LXC_attach_run_command(PyObject *self, PyObject *arg) > -{ > - PyObject *args_obj = NULL; > - int i, rv; > - lxc_attach_command_t cmd = { > - NULL, /* program */ > - NULL /* argv[] */ > - }; > - > - if (!PyArg_ParseTuple(arg, "sO", (const char**)&cmd.program, &args_obj)) > - return NULL; > - if (args_obj && PyList_Check(args_obj)) { > - cmd.argv = convert_tuple_to_char_pointer_array(args_obj); > - } else { > - PyErr_Format(PyExc_TypeError, "Second part of tuple passed to " > - "attach_run_command must be a list."); > - return NULL; > - } > - > - if (!cmd.argv) > - return NULL; > - > - rv = lxc_attach_run_command(&cmd); > - > - for (i = 0; cmd.argv[i]; i++) > - free(cmd.argv[i]); > - free(cmd.argv); > - > - return PyLong_FromLong(rv); > -} > - > +/* Function/Properties list */ > static PyGetSetDef Container_getseters[] = { > {"config_file_name", > (getter)Container_config_file_name, NULL, > -- > 1.8.4.4 > > > ------------------------------------------------------------------------------ > Rapidly troubleshoot problems before they affect your business. Most IT > organizations don't have a clear picture of how application performance > affects their revenue. With AppDynamics, you get 100% visibility into your > Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! > http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk > _______________________________________________ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel