Added qemudEscapeShellArg(), and saferead()/safewrite() APIs

This commit is contained in:
Daniel P. Berrange 2007-08-14 01:33:38 +00:00
parent 79a3754210
commit 383ae8c4ec
4 changed files with 116 additions and 2 deletions

View File

@ -1,14 +1,23 @@
Mon Aug 13 21:33:48 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/qemu_driver.c: added qemudEscapeShellArg() helper function
for future save impl. Patch from Jim Paris
* src/util.c, src/util.h: Added saferead/safewrite convenience
functions for doing read/write safe from signals. Patch from
Jim Paris
Mon Aug 13 21:26:48 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c: Add support
for passing -incoming option to QEMU for migration/restore.
for passing -incoming option to QEMU for migration/restore. Patch
from Jim Paris
Mon Aug 13 21:18:48 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/util.h, src/util.c: Allow a file descriptor to be supplied
for STDIN when calling virExec(), or if -1, redirect from /dev/null
* src/qemu_driver.c, src/openvz_driver.c: Pass in -1 for new stdin
parameter above where neccessary
parameter above where neccessary. Patch from Jim Paris
Mon Aug 13 20:13:48 EST 2007 Daniel P. Berrange <berrange@redhat.com>

View File

@ -1855,6 +1855,72 @@ static int qemudDomainGetInfo(virDomainPtr dom,
}
static char *qemudEscapeShellArg(const char *in)
{
int len = 0;
int i, j;
char *out;
/* To pass through the QEMU monitor, we need to use escape
sequences: \r, \n, \", \\
To pass through both QEMU + the shell, we need to escape
the single character ' as the five characters '\\''
*/
for (i = 0; in[i] != '\0'; i++) {
switch(in[i]) {
case '\r':
case '\n':
case '"':
case '\\':
len += 2;
break;
case '\'':
len += 5;
break;
default:
len += 1;
break;
}
}
if ((out = (char *)malloc(len + 1)) == NULL)
return NULL;
for (i = j = 0; in[i] != '\0'; i++) {
switch(in[i]) {
case '\r':
out[j++] = '\\';
out[j++] = 'r';
break;
case '\n':
out[j++] = '\\';
out[j++] = 'n';
break;
case '"':
case '\\':
out[j++] = '\\';
out[j++] = in[i];
break;
case '\'':
out[j++] = '\'';
out[j++] = '\\';
out[j++] = '\\';
out[j++] = '\'';
out[j++] = '\'';
break;
default:
out[j++] = in[i];
break;
}
}
out[j] = '\0';
return out;
}
static int qemudDomainSave(virDomainPtr dom,
const char *path ATTRIBUTE_UNUSED) {
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;

View File

@ -189,3 +189,40 @@ virExecNonBlock(virConnectPtr conn,
return(_virExec(conn, argv, retpid, infd, outfd, errfd, 1));
}
/* Like read(), but restarts after EINTR */
int saferead(int fd, void *buf, size_t count)
{
size_t nread = 0;
while (count > 0) {
int r = read(fd, buf, count);
if (r < 0 && errno == EINTR)
continue;
if (r < 0)
return r;
if (r == 0)
return nread;
buf = (unsigned char *)buf + r;
count -= r;
nread += r;
}
return nread;
}
/* Like write(), but restarts after EINTR */
ssize_t safewrite(int fd, const void *buf, size_t count)
{
size_t nwritten = 0;
while (count > 0) {
int r = write(fd, buf, count);
if (r < 0 && errno == EINTR)
continue;
if (r < 0)
return r;
if (r == 0)
return nwritten;
buf = (unsigned char *)buf + r;
count -= r;
nwritten += r;
}
return nwritten;
}

View File

@ -24,3 +24,5 @@
int virExec(virConnectPtr conn, char **argv, int *retpid, int infd, int *outfd, int *errfd);
int virExecNonBlock(virConnectPtr conn, char **argv, int *retpid, int infd, int *outfd, int *errfd);
int saferead(int fd, void *buf, size_t count);
ssize_t safewrite(int fd, const void *buf, size_t count);