From 5365ebd501850ea10d9a5b28fc6480ea34dbe16d Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Tue, 14 Apr 2009 13:51:12 +0100 Subject: Add 'command' and 'command-lines'. Fix args freeing in Perl bindings. --- daemon/command.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 daemon/command.c (limited to 'daemon/command.c') diff --git a/daemon/command.c b/daemon/command.c new file mode 100644 index 00000000..589ca769 --- /dev/null +++ b/daemon/command.c @@ -0,0 +1,101 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2009 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include + +#include "../src/guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" + +char * +do_command (char * const * const argv) +{ + char *out, *err; + int r; + + /* We need a root filesystem mounted to do this. */ + NEED_ROOT (NULL); + + /* Conveniently, argv is already a NULL-terminated argv-style array + * of parameters, so we can pass it straight in to our internal + * commandv. We just have to check the list is non-empty. + */ + if (argv[0] == NULL) { + reply_with_error ("command: passed an empty list"); + return NULL; + } + + CHROOT_IN; + r = commandv (&out, &err, argv); + CHROOT_OUT; + + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return out; /* Caller frees. */ +} + +char ** +do_command_lines (char * const * const argv) +{ + char *out; + char **lines = NULL; + int size = 0, alloc = 0; + char *p, *pend; + + out = do_command (argv); + if (out == NULL) + return NULL; + + /* Now convert the output to a list of lines. */ + p = out; + while (p) { + pend = strchr (p, '\n'); + if (pend) { + *pend = '\0'; + pend++; + } + + /* Final \n? Don't return an empty final element. */ + if (pend && *pend == '\0') break; + + if (add_string (&lines, &size, &alloc, p) == -1) { + free (out); + return NULL; + } + + p = pend; + } + + free (out); + + if (add_string (&lines, &size, &alloc, NULL) == -1) + return NULL; + + return lines; +} -- cgit