mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-20 11:48:28 -06:00
Allow a pre-opened FD to be be pass to virExec for stdout/err
This commit is contained in:
parent
60ed1d2a7a
commit
6bc99a7775
@ -1,3 +1,10 @@
|
||||
Wed Aug 20 09:59:54 BST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
* src/util.c: Allow a pre-opened FD to be passed in for childs
|
||||
stdout/err
|
||||
* src/openvz_driver.c, src/qemu_driver.c: Initialize FDs to
|
||||
-1 before calling virExec()
|
||||
|
||||
Wed Aug 20 09:35:33 BST 2008 Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Avoid signal race in virExec()
|
||||
|
@ -736,7 +736,9 @@ static int openvzGetNodeInfo(virConnectPtr conn,
|
||||
|
||||
static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
|
||||
int got = 0;
|
||||
int veid, pid, outfd, errfd;
|
||||
int veid, pid;
|
||||
int outfd = -1;
|
||||
int errfd = -1;
|
||||
int ret;
|
||||
char buf[32];
|
||||
char *endptr;
|
||||
@ -772,7 +774,7 @@ static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
||||
static int openvzListDefinedDomains(virConnectPtr conn,
|
||||
char **const names, int nnames) {
|
||||
int got = 0;
|
||||
int veid, pid, outfd, errfd, ret;
|
||||
int veid, pid, outfd = -1, errfd = -1, ret;
|
||||
char vpsname[OPENVZ_NAME_MAX];
|
||||
char buf[32];
|
||||
char *endptr;
|
||||
|
@ -949,6 +949,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
||||
qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
|
||||
errno, strerror(errno));
|
||||
|
||||
vm->stdout_fd = -1;
|
||||
vm->stderr_fd = -1;
|
||||
|
||||
ret = virExecNonBlock(conn, argv, &vm->pid,
|
||||
vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd);
|
||||
if (ret == 0) {
|
||||
|
119
src/util.c
119
src/util.c
@ -118,6 +118,8 @@ _virExec(virConnectPtr conn,
|
||||
int pid, null, i;
|
||||
int pipeout[2] = {-1,-1};
|
||||
int pipeerr[2] = {-1,-1};
|
||||
int childout = -1;
|
||||
int childerr = -1;
|
||||
sigset_t oldmask, newmask;
|
||||
struct sigaction sig_action;
|
||||
|
||||
@ -140,39 +142,66 @@ _virExec(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((outfd != NULL && pipe(pipeout) < 0) ||
|
||||
(errfd != NULL && pipe(pipeerr) < 0)) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot create pipe: %s"), strerror(errno));
|
||||
goto cleanup;
|
||||
if (outfd != NULL) {
|
||||
if (*outfd == -1) {
|
||||
if (pipe(pipeout) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot create pipe: %s"), strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (non_block &&
|
||||
virSetNonBlock(pipeout[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virSetCloseExec(pipeout[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set close-on-exec file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
childout = pipeout[1];
|
||||
} else {
|
||||
childout = *outfd;
|
||||
}
|
||||
#ifndef ENABLE_DEBUG
|
||||
} else {
|
||||
childout = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (outfd) {
|
||||
if(non_block &&
|
||||
virSetNonBlock(pipeout[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
if (errfd != NULL) {
|
||||
if (*errfd == -1) {
|
||||
if (pipe(pipeerr) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to create pipe: %s"), strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(virSetCloseExec(pipeout[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set close-on-exec file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (errfd) {
|
||||
if(non_block &&
|
||||
virSetNonBlock(pipeerr[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
if(virSetCloseExec(pipeerr[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set close-on-exec file descriptor flag"));
|
||||
goto cleanup;
|
||||
if (non_block &&
|
||||
virSetNonBlock(pipeerr[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set non-blocking file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virSetCloseExec(pipeerr[0]) == -1) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("Failed to set close-on-exec file descriptor flag"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
childerr = pipeerr[1];
|
||||
} else {
|
||||
childerr = *errfd;
|
||||
}
|
||||
#ifndef ENABLE_DEBUG
|
||||
} else {
|
||||
childerr = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
@ -183,11 +212,11 @@ _virExec(virConnectPtr conn,
|
||||
|
||||
if (pid) { /* parent */
|
||||
close(null);
|
||||
if (outfd) {
|
||||
if (outfd && *outfd == -1) {
|
||||
close(pipeout[1]);
|
||||
*outfd = pipeout[0];
|
||||
}
|
||||
if (errfd) {
|
||||
if (errfd && *errfd == -1) {
|
||||
close(pipeerr[1]);
|
||||
*errfd = pipeerr[0];
|
||||
}
|
||||
@ -250,35 +279,25 @@ _virExec(virConnectPtr conn,
|
||||
_("failed to setup stdin file handle: %s"), strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
#ifndef ENABLE_DEBUG
|
||||
if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0) {
|
||||
if (childout > 0 &&
|
||||
dup2(childout, STDOUT_FILENO) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to setup stdout file handle: %s"), strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0) {
|
||||
if (childerr > 0 &&
|
||||
dup2(childerr, STDERR_FILENO) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to setup stderr file handle: %s"), strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
#else /* ENABLE_DEBUG */
|
||||
if (pipeout[1] > 0 && dup2(pipeout[1], STDOUT_FILENO) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to setup stderr file handle: %s"), strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
if (pipeerr[1] > 0 && dup2(pipeerr[1], STDERR_FILENO) < 0) {
|
||||
ReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to setup stdout file handle: %s"), strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
#endif /* ENABLE_DEBUG */
|
||||
|
||||
close(null);
|
||||
if (pipeout[1] > 0)
|
||||
close(pipeout[1]);
|
||||
if (pipeerr[1] > 0)
|
||||
close(pipeerr[1]);
|
||||
if (childout > 0)
|
||||
close(childout);
|
||||
if (childerr > 0 &&
|
||||
childerr != childout)
|
||||
close(childerr);
|
||||
|
||||
execvp(argv[0], (char **) argv);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user