debuggers.hg
changeset 21182:df34011884a3
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@eu.citrix.com>
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@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Apr 12 17:39:29 2010 +0100 (2010-04-12) |
parents | 37e4d8e11554 |
children | c031244c190e |
files | tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h |
line diff
1.1 --- a/tools/libxl/libxl_utils.c Mon Apr 12 17:38:42 2010 +0100 1.2 +++ b/tools/libxl/libxl_utils.c Mon Apr 12 17:39:29 2010 +0100 1.3 @@ -26,6 +26,7 @@ 1.4 #include <sys/stat.h> 1.5 #include <sys/types.h> 1.6 #include <unistd.h> 1.7 +#include <assert.h> 1.8 1.9 #include "libxl_utils.h" 1.10 #include "libxl_internal.h" 1.11 @@ -177,3 +178,105 @@ out: 1.12 return rc; 1.13 } 1.14 1.15 +int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename, 1.16 + void **data_r, int *datalen_r) { 1.17 + FILE *f = 0; 1.18 + uint8_t *data = 0; 1.19 + int datalen = 0; 1.20 + int e; 1.21 + struct stat stab; 1.22 + ssize_t rs; 1.23 + 1.24 + f = fopen(filename, "r"); 1.25 + if (!f) { 1.26 + if (errno == ENOENT) return ENOENT; 1.27 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to open %s", filename); 1.28 + goto xe; 1.29 + } 1.30 + 1.31 + if (fstat(fileno(f), &stab)) { 1.32 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to fstat %s", filename); 1.33 + goto xe; 1.34 + } 1.35 + 1.36 + if (!S_ISREG(stab.st_mode)) { 1.37 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "%s is not a plain file", filename); 1.38 + errno = ENOTTY; 1.39 + goto xe; 1.40 + } 1.41 + 1.42 + if (stab.st_size > INT_MAX) { 1.43 + XL_LOG(ctx, XL_LOG_ERROR, "file %s is far too large", filename); 1.44 + errno = EFBIG; 1.45 + goto xe; 1.46 + } 1.47 + 1.48 + datalen = stab.st_size; 1.49 + 1.50 + if (stab.st_size && data_r) { 1.51 + data = malloc(datalen); 1.52 + if (!data) goto xe; 1.53 + 1.54 + rs = fread(data, 1, datalen, f); 1.55 + if (rs != datalen) { 1.56 + if (ferror(f)) 1.57 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to read %s", filename); 1.58 + else if (feof(f)) 1.59 + XL_LOG(ctx, XL_LOG_ERROR, "%s changed size while we" 1.60 + " were reading it", filename); 1.61 + else 1.62 + abort(); 1.63 + goto xe; 1.64 + } 1.65 + } 1.66 + 1.67 + if (fclose(f)) { 1.68 + f = 0; 1.69 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to close %s", filename); 1.70 + goto xe; 1.71 + } 1.72 + 1.73 + if (data_r) *data_r = data; 1.74 + if (datalen_r) *datalen_r = datalen; 1.75 + 1.76 + return 0; 1.77 + 1.78 + xe: 1.79 + e = errno; 1.80 + assert(e != ENOENT); 1.81 + if (f) fclose(f); 1.82 + if (data) free(data); 1.83 + return e; 1.84 +} 1.85 + 1.86 +#define READ_WRITE_EXACTLY(rw, zero_is_eof, constdata) \ 1.87 + \ 1.88 + int libxl_##rw##_exactly(struct libxl_ctx *ctx, int fd, \ 1.89 + constdata void *data, ssize_t sz, \ 1.90 + const char *filename, const char *what) { \ 1.91 + ssize_t got; \ 1.92 + \ 1.93 + while (sz > 0) { \ 1.94 + got = rw(fd, data, sz); \ 1.95 + if (got == -1) { \ 1.96 + if (errno == EINTR) continue; \ 1.97 + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to " #rw " %s%s%s", \ 1.98 + what?what:"", what?" from ":"", filename); \ 1.99 + return errno; \ 1.100 + } \ 1.101 + if (got == 0) { \ 1.102 + XL_LOG(ctx, XL_LOG_ERROR, \ 1.103 + zero_is_eof \ 1.104 + ? "file/stream truncated reading %s%s%s" \ 1.105 + : "file/stream write returned 0! writing %s%s%s", \ 1.106 + what?what:"", what?" from ":"", filename); \ 1.107 + return EPROTO; \ 1.108 + } \ 1.109 + sz -= got; \ 1.110 + data = (char*)data + got; \ 1.111 + } \ 1.112 + return 0; \ 1.113 + } 1.114 + 1.115 +READ_WRITE_EXACTLY(read, 1, /* */) 1.116 +READ_WRITE_EXACTLY(write, 0, const)
2.1 --- a/tools/libxl/libxl_utils.h Mon Apr 12 17:38:42 2010 +0100 2.2 +++ b/tools/libxl/libxl_utils.h Mon Apr 12 17:39:29 2010 +0100 2.3 @@ -26,5 +26,23 @@ int libxl_is_stubdom(struct libxl_ctx *c 2.4 int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name); 2.5 int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype); 2.6 2.7 +int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename, 2.8 + void **data_r, int *datalen_r); 2.9 + /* Reads the contents of the plain file filename into a mallocd 2.10 + * buffer. Returns 0 or errno. Any errors other than ENOENT are logged. 2.11 + * If the file is empty, *data_r and *datalen_r are set to 0. 2.12 + * On error, *data_r and *datalen_r are undefined. 2.13 + * data_r and/or datalen_r may be 0. 2.14 + */ 2.15 + 2.16 +int libxl_read_exactly(struct libxl_ctx *ctx, int fd, void *data, ssize_t sz, 2.17 + const char *filename, const char *what); 2.18 +int libxl_write_exactly(struct libxl_ctx *ctx, int fd, const void *data, 2.19 + ssize_t sz, const char *filename, const char *what); 2.20 + /* Returns 0 or errno. If file is truncated on reading, returns 2.21 + * EPROTO and you have no way to tell how much was read. Errors are 2.22 + * logged using filename (which is only used for logging) and what 2.23 + * (which may be 0). */ 2.24 + 2.25 #endif 2.26