diff options
| author | Paul Eggert | 2011-04-05 11:19:19 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-05 11:19:19 -0700 |
| commit | 9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc (patch) | |
| tree | c60da8b92b2258e8d73fd27063275c8524b19932 /lib | |
| parent | ca23cc8840efb1354ebe16c6bb99bf1f8880e9b6 (diff) | |
| download | emacs-9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc.tar.gz emacs-9e0e57c7d64492351f4a7ce1c01054d4d43a1bcc.zip | |
Merge changes from gnulib.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/allocator.h | 12 | ||||
| -rw-r--r-- | lib/careadlinkat.c | 34 |
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 | |||
| 24 | struct allocator | 26 | struct 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. */ | ||
| 62 | static 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 | } |