mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-13 16:38:14 +00:00
Merge changes from gnulib.
This commit is contained in:
parent
ca23cc8840
commit
9e0e57c7d6
@ -21,8 +21,15 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* An object describing a memory allocator family. */
|
||||
|
||||
struct allocator
|
||||
{
|
||||
/* Do not use GCC attributes such as __attribute__ ((malloc)) with
|
||||
the function types pointed at by these members, because these
|
||||
attributes do not work with pointers to functions. See
|
||||
<http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00007.html>. */
|
||||
|
||||
/* Call MALLOC to allocate memory, like 'malloc'. On failure MALLOC
|
||||
should return NULL, though not necessarily set errno. When given
|
||||
a zero size it may return NULL even if successful. */
|
||||
@ -37,8 +44,9 @@ struct allocator
|
||||
/* Call FREE to free memory, like 'free'. */
|
||||
void (*free) (void *);
|
||||
|
||||
/* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should
|
||||
not return. */
|
||||
/* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should not
|
||||
return. DIE can be used by code that detects memory overflow
|
||||
while calculating sizes to be passed to MALLOC or REALLOC. */
|
||||
void (*die) (void);
|
||||
};
|
||||
|
||||
|
@ -57,6 +57,11 @@ careadlinkatcwd (int fd, char const *filename, char *buffer,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A standard allocator. For now, only careadlinkat needs this, but
|
||||
perhaps it should be moved to the allocator module. */
|
||||
static struct allocator const standard_allocator =
|
||||
{ malloc, realloc, free, NULL };
|
||||
|
||||
/* Assuming the current directory is FD, get the symbolic link value
|
||||
of FILENAME as a null-terminated string and put it into a buffer.
|
||||
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
|
||||
@ -88,17 +93,8 @@ careadlinkat (int fd, char const *filename,
|
||||
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
|
||||
char stack_buf[1024];
|
||||
|
||||
void *(*pmalloc) (size_t) = malloc;
|
||||
void *(*prealloc) (void *, size_t) = realloc;
|
||||
void (*pfree) (void *) = free;
|
||||
void (*pdie) (void) = NULL;
|
||||
if (alloc)
|
||||
{
|
||||
pmalloc = alloc->malloc;
|
||||
prealloc = alloc->realloc;
|
||||
pfree = alloc->free;
|
||||
pdie = alloc->die;
|
||||
}
|
||||
if (! alloc)
|
||||
alloc = &standard_allocator;
|
||||
|
||||
if (! buffer_size)
|
||||
{
|
||||
@ -127,7 +123,7 @@ careadlinkat (int fd, char const *filename,
|
||||
{
|
||||
if (buf != buffer)
|
||||
{
|
||||
pfree (buf);
|
||||
alloc->free (buf);
|
||||
errno = readlinkat_errno;
|
||||
}
|
||||
return NULL;
|
||||
@ -142,16 +138,16 @@ careadlinkat (int fd, char const *filename,
|
||||
|
||||
if (buf == stack_buf)
|
||||
{
|
||||
char *b = (char *) pmalloc (link_size);
|
||||
char *b = (char *) alloc->malloc (link_size);
|
||||
if (! b)
|
||||
break;
|
||||
memcpy (b, buf, link_size);
|
||||
buf = b;
|
||||
}
|
||||
else if (link_size < buf_size && buf != buffer && prealloc)
|
||||
else if (link_size < buf_size && buf != buffer && alloc->realloc)
|
||||
{
|
||||
/* Shrink BUF before returning it. */
|
||||
char *b = (char *) prealloc (buf, link_size);
|
||||
char *b = (char *) alloc->realloc (buf, link_size);
|
||||
if (b)
|
||||
buf = b;
|
||||
}
|
||||
@ -160,7 +156,7 @@ careadlinkat (int fd, char const *filename,
|
||||
}
|
||||
|
||||
if (buf != buffer)
|
||||
pfree (buf);
|
||||
alloc->free (buf);
|
||||
|
||||
if (buf_size <= buf_size_max / 2)
|
||||
buf_size *= 2;
|
||||
@ -168,12 +164,12 @@ careadlinkat (int fd, char const *filename,
|
||||
buf_size = buf_size_max;
|
||||
else
|
||||
break;
|
||||
buf = (char *) pmalloc (buf_size);
|
||||
buf = (char *) alloc->malloc (buf_size);
|
||||
}
|
||||
while (buf);
|
||||
|
||||
if (pdie)
|
||||
pdie ();
|
||||
if (alloc->die)
|
||||
alloc->die ();
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user