linux/tools/perf/util/wrapper.c
<<
>>
Prefs
   1/*
   2 * Various trivial helper wrappers around standard functions
   3 */
   4#include "cache.h"
   5
   6/*
   7 * There's no pack memory to release - but stay close to the Git
   8 * version so wrap this away:
   9 */
  10static inline void release_pack_memory(size_t size __used, int flag __used)
  11{
  12}
  13
  14char *xstrdup(const char *str)
  15{
  16        char *ret = strdup(str);
  17        if (!ret) {
  18                release_pack_memory(strlen(str) + 1, -1);
  19                ret = strdup(str);
  20                if (!ret)
  21                        die("Out of memory, strdup failed");
  22        }
  23        return ret;
  24}
  25
  26void *xmalloc(size_t size)
  27{
  28        void *ret = malloc(size);
  29        if (!ret && !size)
  30                ret = malloc(1);
  31        if (!ret) {
  32                release_pack_memory(size, -1);
  33                ret = malloc(size);
  34                if (!ret && !size)
  35                        ret = malloc(1);
  36                if (!ret)
  37                        die("Out of memory, malloc failed");
  38        }
  39#ifdef XMALLOC_POISON
  40        memset(ret, 0xA5, size);
  41#endif
  42        return ret;
  43}
  44
  45/*
  46 * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
  47 * "data" to the allocated memory, zero terminates the allocated memory,
  48 * and returns a pointer to the allocated memory. If the allocation fails,
  49 * the program dies.
  50 */
  51void *xmemdupz(const void *data, size_t len)
  52{
  53        char *p = xmalloc(len + 1);
  54        memcpy(p, data, len);
  55        p[len] = '\0';
  56        return p;
  57}
  58
  59char *xstrndup(const char *str, size_t len)
  60{
  61        char *p = memchr(str, '\0', len);
  62
  63        return xmemdupz(str, p ? (size_t)(p - str) : len);
  64}
  65
  66void *xrealloc(void *ptr, size_t size)
  67{
  68        void *ret = realloc(ptr, size);
  69        if (!ret && !size)
  70                ret = realloc(ptr, 1);
  71        if (!ret) {
  72                release_pack_memory(size, -1);
  73                ret = realloc(ptr, size);
  74                if (!ret && !size)
  75                        ret = realloc(ptr, 1);
  76                if (!ret)
  77                        die("Out of memory, realloc failed");
  78        }
  79        return ret;
  80}
  81
  82void *xcalloc(size_t nmemb, size_t size)
  83{
  84        void *ret = calloc(nmemb, size);
  85        if (!ret && (!nmemb || !size))
  86                ret = calloc(1, 1);
  87        if (!ret) {
  88                release_pack_memory(nmemb * size, -1);
  89                ret = calloc(nmemb, size);
  90                if (!ret && (!nmemb || !size))
  91                        ret = calloc(1, 1);
  92                if (!ret)
  93                        die("Out of memory, calloc failed");
  94        }
  95        return ret;
  96}
  97
  98void *xmmap(void *start, size_t length,
  99        int prot, int flags, int fd, off_t offset)
 100{
 101        void *ret = mmap(start, length, prot, flags, fd, offset);
 102        if (ret == MAP_FAILED) {
 103                if (!length)
 104                        return NULL;
 105                release_pack_memory(length, fd);
 106                ret = mmap(start, length, prot, flags, fd, offset);
 107                if (ret == MAP_FAILED)
 108                        die("Out of memory? mmap failed: %s", strerror(errno));
 109        }
 110        return ret;
 111}
 112
 113/*
 114 * xread() is the same a read(), but it automatically restarts read()
 115 * operations with a recoverable error (EAGAIN and EINTR). xread()
 116 * DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
 117 */
 118ssize_t xread(int fd, void *buf, size_t len)
 119{
 120        ssize_t nr;
 121        while (1) {
 122                nr = read(fd, buf, len);
 123                if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
 124                        continue;
 125                return nr;
 126        }
 127}
 128
 129/*
 130 * xwrite() is the same a write(), but it automatically restarts write()
 131 * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
 132 * GUARANTEE that "len" bytes is written even if the operation is successful.
 133 */
 134ssize_t xwrite(int fd, const void *buf, size_t len)
 135{
 136        ssize_t nr;
 137        while (1) {
 138                nr = write(fd, buf, len);
 139                if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
 140                        continue;
 141                return nr;
 142        }
 143}
 144
 145ssize_t read_in_full(int fd, void *buf, size_t count)
 146{
 147        char *p = buf;
 148        ssize_t total = 0;
 149
 150        while (count > 0) {
 151                ssize_t loaded = xread(fd, p, count);
 152                if (loaded <= 0)
 153                        return total ? total : loaded;
 154                count -= loaded;
 155                p += loaded;
 156                total += loaded;
 157        }
 158
 159        return total;
 160}
 161
 162ssize_t write_in_full(int fd, const void *buf, size_t count)
 163{
 164        const char *p = buf;
 165        ssize_t total = 0;
 166
 167        while (count > 0) {
 168                ssize_t written = xwrite(fd, p, count);
 169                if (written < 0)
 170                        return -1;
 171                if (!written) {
 172                        errno = ENOSPC;
 173                        return -1;
 174                }
 175                count -= written;
 176                p += written;
 177                total += written;
 178        }
 179
 180        return total;
 181}
 182
 183int xdup(int fd)
 184{
 185        int ret = dup(fd);
 186        if (ret < 0)
 187                die("dup failed: %s", strerror(errno));
 188        return ret;
 189}
 190
 191FILE *xfdopen(int fd, const char *mode)
 192{
 193        FILE *stream = fdopen(fd, mode);
 194        if (stream == NULL)
 195                die("Out of memory? fdopen failed: %s", strerror(errno));
 196        return stream;
 197}
 198
 199int xmkstemp(char *template)
 200{
 201        int fd;
 202
 203        fd = mkstemp(template);
 204        if (fd < 0)
 205                die("Unable to create temporary file: %s", strerror(errno));
 206        return fd;
 207}
 208