- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / tools / perf / util / wrapper.c
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  */
10 static inline void release_pack_memory(size_t size __used, int flag __used)
11 {
12 }
13
14 char *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
26 void *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  */
51 void *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
59 char *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
66 void *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
82 /*
83  * xread() is the same a read(), but it automatically restarts read()
84  * operations with a recoverable error (EAGAIN and EINTR). xread()
85  * DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
86  */
87 static ssize_t xread(int fd, void *buf, size_t len)
88 {
89         ssize_t nr;
90         while (1) {
91                 nr = read(fd, buf, len);
92                 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
93                         continue;
94                 return nr;
95         }
96 }
97
98 /*
99  * xwrite() is the same a write(), but it automatically restarts write()
100  * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
101  * GUARANTEE that "len" bytes is written even if the operation is successful.
102  */
103 static ssize_t xwrite(int fd, const void *buf, size_t len)
104 {
105         ssize_t nr;
106         while (1) {
107                 nr = write(fd, buf, len);
108                 if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
109                         continue;
110                 return nr;
111         }
112 }
113
114 ssize_t read_in_full(int fd, void *buf, size_t count)
115 {
116         char *p = buf;
117         ssize_t total = 0;
118
119         while (count > 0) {
120                 ssize_t loaded = xread(fd, p, count);
121                 if (loaded <= 0)
122                         return total ? total : loaded;
123                 count -= loaded;
124                 p += loaded;
125                 total += loaded;
126         }
127
128         return total;
129 }
130
131 ssize_t write_in_full(int fd, const void *buf, size_t count)
132 {
133         const char *p = buf;
134         ssize_t total = 0;
135
136         while (count > 0) {
137                 ssize_t written = xwrite(fd, p, count);
138                 if (written < 0)
139                         return -1;
140                 if (!written) {
141                         errno = ENOSPC;
142                         return -1;
143                 }
144                 count -= written;
145                 p += written;
146                 total += written;
147         }
148
149         return total;
150 }