WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 03/16] libxl: New utility functions in for reading an

We introduce these functions in libxl_utils.h:

  int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
                               void **data_r, int *datalen_r);
  int libxl_read_exactly(struct libxl_ctx *ctx, int fd, void *data, ssize_t sz,
                         const char *filename, const char *what);
  int libxl_write_exactly(struct libxl_ctx *ctx, int fd, const void *data,
                          ssize_t sz, const char *filename, const char *what);

They will be needed by the following patches.  They have to be in
libxl.a rather than libxutil.a because they will be used, amongst
other places, in libxl itself.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 tools/libxl/libxl_utils.c |  103 +++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_utils.h |   18 ++++++++
 2 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index afc852a..3a1f095 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <assert.h>
 
 #include "libxl_utils.h"
 #include "libxl_internal.h"
@@ -177,3 +178,105 @@ out:
     return rc;
 }
 
+int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
+                             void **data_r, int *datalen_r) {
+    FILE *f = 0;
+    uint8_t *data = 0;
+    int datalen = 0;
+    int e;
+    struct stat stab;
+    ssize_t rs;
+    
+    f = fopen(filename, "r");
+    if (!f) {
+        if (errno == ENOENT) return ENOENT;
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to open %s", filename);
+        goto xe;
+    }
+
+    if (fstat(fileno(f), &stab)) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to fstat %s", filename);
+        goto xe;
+    }
+
+    if (!S_ISREG(stab.st_mode)) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "%s is not a plain file", filename);
+        errno = ENOTTY;
+        goto xe;
+    }
+
+    if (stab.st_size > INT_MAX) {
+        XL_LOG(ctx, XL_LOG_ERROR, "file %s is far too large", filename);
+        errno = EFBIG;
+        goto xe;
+    }
+
+    datalen = stab.st_size;
+
+    if (stab.st_size && data_r) {
+        data = malloc(datalen);
+        if (!data) goto xe;
+
+        rs = fread(data, 1, datalen, f);
+        if (rs != datalen) {
+            if (ferror(f))
+                XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to read %s", filename);
+            else if (feof(f))
+                XL_LOG(ctx, XL_LOG_ERROR, "%s changed size while we"
+                       " were reading it", filename);
+            else
+                abort();
+            goto xe;
+        }
+    }
+
+    if (fclose(f)) {
+        f = 0;
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to close %s", filename);
+        goto xe;
+    }
+
+    if (data_r) *data_r = data;
+    if (datalen_r) *datalen_r = datalen;
+
+    return 0;
+
+ xe:
+    e = errno;
+    assert(e != ENOENT);
+    if (f) fclose(f);
+    if (data) free(data);
+    return e;
+}
+
+#define READ_WRITE_EXACTLY(rw, zero_is_eof, constdata)                    \
+                                                                          \
+  int libxl_##rw##_exactly(struct libxl_ctx *ctx, int fd,                 \
+                           constdata void *data, ssize_t sz,              \
+                           const char *filename, const char *what) {      \
+      ssize_t got;                                                        \
+                                                                          \
+      while (sz > 0) {                                                    \
+          got = rw(fd, data, sz);                                         \
+          if (got == -1) {                                                \
+              if (errno == EINTR) continue;                               \
+              XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to " #rw " %s%s%s", \
+                           what?what:"", what?" from ":"", filename);     \
+              return errno;                                               \
+          }                                                               \
+          if (got == 0) {                                                 \
+              XL_LOG(ctx, XL_LOG_ERROR,                                   \
+                     zero_is_eof                                          \
+                     ? "file/stream truncated reading %s%s%s"             \
+                     : "file/stream write returned 0! writing %s%s%s",    \
+                     what?what:"", what?" from ":"", filename);           \
+              return EPROTO;                                              \
+          }                                                               \
+          sz -= got;                                                      \
+          data = (char*)data + got;                                       \
+      }                                                                   \
+      return 0;                                                           \
+  }
+
+READ_WRITE_EXACTLY(read, 1, /* */)
+READ_WRITE_EXACTLY(write, 0, const)
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 05fa4e3..65e7e31 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -26,5 +26,23 @@ int libxl_is_stubdom(struct libxl_ctx *ctx, uint32_t domid, 
uint32_t *target_dom
 int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name);
 int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, 
libxl_disk_phystype *phystype);
 
+int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
+                             void **data_r, int *datalen_r);
+  /* Reads the contents of the plain file filename into a mallocd
+   * buffer.  Returns 0 or errno.  Any errors other than ENOENT are logged.
+   * If the file is empty, *data_r and *datalen_r are set to 0.
+   * On error, *data_r and *datalen_r are undefined.
+   * data_r and/or datalen_r may be 0.
+   */
+
+int libxl_read_exactly(struct libxl_ctx *ctx, int fd, void *data, ssize_t sz,
+                       const char *filename, const char *what);
+int libxl_write_exactly(struct libxl_ctx *ctx, int fd, const void *data,
+                        ssize_t sz, const char *filename, const char *what);
+  /* Returns 0 or errno.  If file is truncated on reading, returns
+   * EPROTO and you have no way to tell how much was read.  Errors are
+   * logged using filename (which is only used for logging) and what
+   * (which may be 0). */
+    
 #endif
 
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel