aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2011-04-05 11:19:19 -0700
committerPaul Eggert2011-04-05 11:19:19 -0700
commit9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc (patch)
treec60da8b92b2258e8d73fd27063275c8524b19932 /lib
parentca23cc8840efb1354ebe16c6bb99bf1f8880e9b6 (diff)
downloademacs-9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc.tar.gz
emacs-9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc.zip
Merge changes from gnulib.
Diffstat (limited to 'lib')
-rw-r--r--lib/allocator.h12
-rw-r--r--lib/careadlinkat.c34
2 files changed, 25 insertions, 21 deletions
diff --git a/lib/allocator.h b/lib/allocator.h
index 54cc5ff66f0..4ac863b224c 100644
--- a/lib/allocator.h
+++ b/lib/allocator.h
@@ -21,8 +21,15 @@
21 21
22#include <stddef.h> 22#include <stddef.h>
23 23
24/* An object describing a memory allocator family. */
25
24struct allocator 26struct allocator
25{ 27{
28 /* Do not use GCC attributes such as __attribute__ ((malloc)) with
29 the function types pointed at by these members, because these
30 attributes do not work with pointers to functions. See
31 <http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00007.html>. */
32
26 /* Call MALLOC to allocate memory, like 'malloc'. On failure MALLOC 33 /* Call MALLOC to allocate memory, like 'malloc'. On failure MALLOC
27 should return NULL, though not necessarily set errno. When given 34 should return NULL, though not necessarily set errno. When given
28 a zero size it may return NULL even if successful. */ 35 a zero size it may return NULL even if successful. */
@@ -37,8 +44,9 @@ struct allocator
37 /* Call FREE to free memory, like 'free'. */ 44 /* Call FREE to free memory, like 'free'. */
38 void (*free) (void *); 45 void (*free) (void *);
39 46
40 /* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should 47 /* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should not
41 not return. */ 48 return. DIE can be used by code that detects memory overflow
49 while calculating sizes to be passed to MALLOC or REALLOC. */
42 void (*die) (void); 50 void (*die) (void);
43}; 51};
44 52
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c
index 828c0508db7..15ffe24c0f4 100644
--- a/lib/careadlinkat.c
+++ b/lib/careadlinkat.c
@@ -57,6 +57,11 @@ careadlinkatcwd (int fd, char const *filename, char *buffer,
57} 57}
58#endif 58#endif
59 59
60/* A standard allocator. For now, only careadlinkat needs this, but
61 perhaps it should be moved to the allocator module. */
62static struct allocator const standard_allocator =
63 { malloc, realloc, free, NULL };
64
60/* Assuming the current directory is FD, get the symbolic link value 65/* Assuming the current directory is FD, get the symbolic link value
61 of FILENAME as a null-terminated string and put it into a buffer. 66 of FILENAME as a null-terminated string and put it into a buffer.
62 If FD is AT_FDCWD, FILENAME is interpreted relative to the current 67 If FD is AT_FDCWD, FILENAME is interpreted relative to the current
@@ -88,17 +93,8 @@ careadlinkat (int fd, char const *filename,
88 SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; 93 SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
89 char stack_buf[1024]; 94 char stack_buf[1024];
90 95
91 void *(*pmalloc) (size_t) = malloc; 96 if (! alloc)
92 void *(*prealloc) (void *, size_t) = realloc; 97 alloc = &standard_allocator;
93 void (*pfree) (void *) = free;
94 void (*pdie) (void) = NULL;
95 if (alloc)
96 {
97 pmalloc = alloc->malloc;
98 prealloc = alloc->realloc;
99 pfree = alloc->free;
100 pdie = alloc->die;
101 }
102 98
103 if (! buffer_size) 99 if (! buffer_size)
104 { 100 {
@@ -127,7 +123,7 @@ careadlinkat (int fd, char const *filename,
127 { 123 {
128 if (buf != buffer) 124 if (buf != buffer)
129 { 125 {
130 pfree (buf); 126 alloc->free (buf);
131 errno = readlinkat_errno; 127 errno = readlinkat_errno;
132 } 128 }
133 return NULL; 129 return NULL;
@@ -142,16 +138,16 @@ careadlinkat (int fd, char const *filename,
142 138
143 if (buf == stack_buf) 139 if (buf == stack_buf)
144 { 140 {
145 char *b = (char *) pmalloc (link_size); 141 char *b = (char *) alloc->malloc (link_size);
146 if (! b) 142 if (! b)
147 break; 143 break;
148 memcpy (b, buf, link_size); 144 memcpy (b, buf, link_size);
149 buf = b; 145 buf = b;
150 } 146 }
151 else if (link_size < buf_size && buf != buffer && prealloc) 147 else if (link_size < buf_size && buf != buffer && alloc->realloc)
152 { 148 {
153 /* Shrink BUF before returning it. */ 149 /* Shrink BUF before returning it. */
154 char *b = (char *) prealloc (buf, link_size); 150 char *b = (char *) alloc->realloc (buf, link_size);
155 if (b) 151 if (b)
156 buf = b; 152 buf = b;
157 } 153 }
@@ -160,7 +156,7 @@ careadlinkat (int fd, char const *filename,
160 } 156 }
161 157
162 if (buf != buffer) 158 if (buf != buffer)
163 pfree (buf); 159 alloc->free (buf);
164 160
165 if (buf_size <= buf_size_max / 2) 161 if (buf_size <= buf_size_max / 2)
166 buf_size *= 2; 162 buf_size *= 2;
@@ -168,12 +164,12 @@ careadlinkat (int fd, char const *filename,
168 buf_size = buf_size_max; 164 buf_size = buf_size_max;
169 else 165 else
170 break; 166 break;
171 buf = (char *) pmalloc (buf_size); 167 buf = (char *) alloc->malloc (buf_size);
172 } 168 }
173 while (buf); 169 while (buf);
174 170
175 if (pdie) 171 if (alloc->die)
176 pdie (); 172 alloc->die ();
177 errno = ENOMEM; 173 errno = ENOMEM;
178 return NULL; 174 return NULL;
179} 175}