[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 03/16] libxl: New utility functions in for reading and writing files.
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |