Add a new function libxl_read_sysfs_file_contents to handle sysfs file specially. It would be used in later pvusb work.
Signed-off-by: Chunyan Liu <cy...@suse.com> Acked-by: Ian Jackson <ian.jack...@eu.citrix.com> --- tools/libxl/libxl_internal.h | 4 +++ tools/libxl/libxl_utils.c | 74 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 9c8519a..429ea32 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -4078,6 +4078,10 @@ void libxl__bitmap_copy_best_effort(libxl__gc *gc, libxl_bitmap *dptr, int libxl__count_physical_sockets(libxl__gc *gc, int *sockets); +_hidden int libxl__read_sysfs_file_contents(libxl__gc *gc, + const char *filename, + void **data_r, + int *datalen_r); #define LIBXL_QEMU_USER_PREFIX "xen-qemuuser" #define LIBXL_QEMU_USER_BASE LIBXL_QEMU_USER_PREFIX"-domid" diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index 672d3f8..b0cb9e1 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -396,6 +396,80 @@ int libxl_read_file_contents(libxl_ctx *ctx, const char *filename, return e; } +int libxl__read_sysfs_file_contents(libxl__gc *gc, 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; + LOGE(ERROR, "failed to open %s", filename); + goto xe; + } + + if (fstat(fileno(f), &stab)) { + LOGE(ERROR, "failed to fstat %s", filename); + goto xe; + } + + if (!S_ISREG(stab.st_mode)) { + LOGE(ERROR, "%s is not a plain file", filename); + errno = ENOTTY; + goto xe; + } + + if (stab.st_size > INT_MAX) { + LOG(ERROR, "file %s is far too large", filename); + errno = EFBIG; + goto xe; + } + + datalen = stab.st_size; + + if (stab.st_size && data_r) { + data = libxl__malloc(gc, datalen); + + /* For sysfs file, datalen is always PAGE_SIZE. 'read' + * will return the number of bytes of the actual content, + * rs <= datalen is expected. + */ + rs = fread(data, 1, datalen, f); + if (rs < datalen) { + if (ferror(f)) { + LOGE(ERROR, "failed to read %s", filename); + goto xe; + } + + datalen = rs; + data = libxl__realloc(gc, data, datalen); + } + } + + if (fclose(f)) { + f = 0; + LOGE(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); + return e; +} + + #define READ_WRITE_EXACTLY(rw, zero_is_eof, constdata) \ \ int libxl_##rw##_exactly(libxl_ctx *ctx, int fd, \ -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel