diff options
Diffstat (limited to 'tools/xenstore/utils.c')
-rw-r--r-- | tools/xenstore/utils.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tools/xenstore/utils.c b/tools/xenstore/utils.c new file mode 100644 index 0000000000..2345021f70 --- /dev/null +++ b/tools/xenstore/utils.c @@ -0,0 +1,143 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <signal.h> + +#include "utils.h" + +void xprintf(const char *fmt, ...) +{ + static FILE *out = NULL; + va_list args; + if (!out) + out = fopen("/dev/console", "w"); + if (!out) + out = stderr; + + va_start(args, fmt); + vfprintf(out, fmt, args); + va_end(args); + fflush(out); +} + +void barf(const char *fmt, ...) +{ + char *str; + va_list arglist; + + xprintf("FATAL: "); + + va_start(arglist, fmt); + vasprintf(&str, fmt, arglist); + va_end(arglist); + + xprintf("%s\n", str); + free(str); + exit(1); +} + +void barf_perror(const char *fmt, ...) +{ + char *str; + int err = errno; + va_list arglist; + + xprintf("FATAL: "); + + va_start(arglist, fmt); + vasprintf(&str, fmt, arglist); + va_end(arglist); + + xprintf("%s: %s\n", str, strerror(err)); + free(str); + exit(1); +} + +void *_realloc_array(void *ptr, size_t size, size_t num) +{ + if (num >= SIZE_MAX/size) + return NULL; + return realloc_nofail(ptr, size * num); +} + +void *realloc_nofail(void *ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) + return ptr; + barf("realloc of %zu failed", size); +} + +void *malloc_nofail(size_t size) +{ + void *ptr = malloc(size); + if (ptr) + return ptr; + barf("malloc of %zu failed", size); +} + +/* Stevens. */ +void daemonize(void) +{ + pid_t pid; + + /* Separate from our parent via fork, so init inherits us. */ + if ((pid = fork()) < 0) + barf_perror("Failed to fork daemon"); + if (pid != 0) + exit(0); + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + /* Session leader so ^C doesn't whack us. */ + setsid(); + /* Move off any mount points we might be in. */ + chdir("/"); + /* Discard our parent's old-fashioned umask prejudices. */ + umask(0); +} + + +/* This version adds one byte (for nul term) */ +void *grab_file(const char *filename, unsigned long *size) +{ + unsigned int max = 16384; + int ret, fd; + void *buffer; + + if (streq(filename, "-")) + fd = dup(STDIN_FILENO); + else + fd = open(filename, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + buffer = malloc(max+1); + *size = 0; + while ((ret = read(fd, buffer + *size, max - *size)) > 0) { + *size += ret; + if (*size == max) + buffer = realloc(buffer, max *= 2 + 1); + } + if (ret < 0) { + free(buffer); + buffer = NULL; + } else + ((char *)buffer)[*size] = '\0'; + close(fd); + return buffer; +} + +void release_file(void *data, unsigned long size __attribute__((unused))) +{ + free(data); +} |