]> xenbits.xensource.com Git - libvirt.git/commitdiff
Added qemudEscapeShellArg(), and saferead()/safewrite() APIs
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 14 Aug 2007 01:33:38 +0000 (01:33 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 14 Aug 2007 01:33:38 +0000 (01:33 +0000)
ChangeLog
src/qemu_driver.c
src/util.c
src/util.h

index 5705e77906071fc85d2f5894cc588440bd11872f..a93a34d45270cecca7e77875f06f6325e214c50f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
index e649060087ef470e147f82708483b138c45d405f..8125622ca039acd328fbba857d28be0dda16169e 100644 (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;
index 4f80eef2ecb7b5212ae07847a3102f1db7580fe9..eb5785990e37a0c1ebc03da84f198fca04dd9ae8 100644 (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;
+}
index d11e6d9797ab1de086104bc5ad70459d9d9b34f5..f69fac8601bad86d691470ca2d0340eab685fc59 100644 (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);