[libvirt] [PATCH] openvz: convert popen to virCommand
Matthias Bolte
matthias.bolte at googlemail.com
Sat Dec 4 11:21:59 UTC 2010
2010/12/3 Eric Blake <eblake at redhat.com>:
> popen must be matched with pclose (not fclose), or it will leak
> resources. Furthermore, it is a lousy interface when it comes
> to signal handling. We're much better off using our decent command
> wrapper.
>
> * src/openvz/openvz_conf.c (openvzLoadDomains, openvzGetVEID):
> Replace popen with virCommand usage.
> ---
> src/openvz/openvz_conf.c | 54 +++++++++++++++++++++++----------------------
> 1 files changed, 28 insertions(+), 26 deletions(-)
> int openvzLoadDomains(struct openvz_driver *driver) {
> - FILE *fp;
> int veid, ret;
> char status[16];
> char uuidstr[VIR_UUID_STRING_BUFLEN];
> virDomainObjPtr dom = NULL;
> char temp[50];
> + char *outbuf = NULL;
> + char *line;
> + virCommandPtr cmd = NULL;
>
> if (openvzAssignUUIDs() < 0)
> return -1;
>
> - if ((fp = popen(VZLIST " -a -ovpsid,status -H 2>/dev/null", "r")) == NULL) {
> - openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("popen failed"));
> - return -1;
> - }
> -
> - while (!feof(fp)) {
> - if (fscanf(fp, "%d %s\n", &veid, status) != 2) {
> - if (feof(fp))
> - break;
> + cmd = virCommandNewArgList(VZLIST, "-a", "-ovpsid,status", "-H", NULL);
> + virCommandSetOutputBuffer(cmd, &outbuf);
> + if (virCommandRun(cmd, NULL) < 0)
> + goto cleanup;
>
> + line = *outbuf ? outbuf : NULL;
Is outbuf guaranteed to be non-NULL when virCommandRun succeeds?
Otherwise we have a potential NULL dereference here.
> + while (line) {
> + if (sscanf(line, "%d %s\n", &veid, status) != 2) {
> openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
> _("Failed to parse vzlist output"));
> goto cleanup;
> @@ -978,27 +985,22 @@ static int openvzAssignUUIDs(void)
> */
>
> int openvzGetVEID(const char *name) {
> - char *cmd;
> + virCommandPtr cmd;
> + char *outbuf;
> int veid;
> - FILE *fp;
> bool ok;
>
> - if (virAsprintf(&cmd, "%s %s -ovpsid -H", VZLIST, name) < 0) {
> - openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("virAsprintf failed"));
> + cmd = virCommandNewArgList(VZLIST, name, "-ovpsid", "-H", NULL);
> + virCommandSetOutputBuffer(cmd, &outbuf);
> + if (virCommandRun(cmd, NULL) < 0) {
> + virCommandFree(cmd);
Is outbuf guaranteed to be unallocated when virCommandRun fails?
Otherwise a VIR_FREE(outbuf) is missing here.
> return -1;
> }
>
> - fp = popen(cmd, "r");
> - VIR_FREE(cmd);
> -
> - if (fp == NULL) {
> - openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("popen failed"));
> - return -1;
> - }
> + virCommandFree(cmd);
> + ok = sscanf(outbuf, "%d\n", &veid) == 1;
Same question here about outbuf being guaranteed to be non-NULL when
virCommandRun succeeds as in openvzLoadDomains. If not then sscanf is
called with NULL and that'll probably segfault.
> + VIR_FREE(outbuf);
>
> - ok = fscanf(fp, "%d\n", &veid ) == 1;
> - VIR_FORCE_FCLOSE(fp);
> if (ok && veid >= 0)
> return veid;
Matthias
More information about the libvir-list
mailing list