diff options
| author | Paul Eggert | 2011-03-31 23:28:48 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-03-31 23:28:48 -0700 |
| commit | d1fdcab7425f36a34ddeaf304e2c6e3c471ba8db (patch) | |
| tree | f59643a560ce58433a9a92dfe615dd18aecc0457 | |
| parent | 63139bfa89692ec666815f57d0658996577a80d3 (diff) | |
| download | emacs-d1fdcab7425f36a34ddeaf304e2c6e3c471ba8db.tar.gz emacs-d1fdcab7425f36a34ddeaf304e2c6e3c471ba8db.zip | |
Replace two copies of readlink code with single gnulib version.
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | Makefile.in | 2 | ||||
| -rw-r--r-- | lib/allocator.h | 45 | ||||
| -rw-r--r-- | lib/careadlinkat.c | 179 | ||||
| -rw-r--r-- | lib/careadlinkat.h | 67 | ||||
| -rw-r--r-- | lib/gnulib.mk | 10 | ||||
| -rw-r--r-- | m4/gl-comp.m4 | 10 | ||||
| -rw-r--r-- | m4/ssize_t.m4 | 23 | ||||
| -rw-r--r-- | src/ChangeLog | 12 | ||||
| -rw-r--r-- | src/fileio.c | 36 | ||||
| -rw-r--r-- | src/filelock.c | 38 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/sysdep.c | 18 |
13 files changed, 390 insertions, 59 deletions
| @@ -1,3 +1,10 @@ | |||
| 1 | 2011-04-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Replace two copies of readlink code with single gnulib version. | ||
| 4 | * Makefile.in (GNULIB_MODULES): Add careadlinkat. | ||
| 5 | * lib/allocator.h, lib/careadlinkat.c, lib/careadlinkat.h: | ||
| 6 | * m4/ssize_t.m4: New files, automatically generated from gnulib. | ||
| 7 | |||
| 1 | 2011-03-28 Glenn Morris <rgm@gnu.org> | 8 | 2011-03-28 Glenn Morris <rgm@gnu.org> |
| 2 | 9 | ||
| 3 | * autogen/update_autogen: Pass -f to autoreconf. | 10 | * autogen/update_autogen: Pass -f to autoreconf. |
diff --git a/Makefile.in b/Makefile.in index 699589c6920..1ac77ed66ac 100644 --- a/Makefile.in +++ b/Makefile.in | |||
| @@ -331,7 +331,7 @@ DOS_gnulib_comp.m4 = gl-comp.m4 | |||
| 331 | # $(gnulib_srcdir) (relative to $(srcdir) and should have build tools | 331 | # $(gnulib_srcdir) (relative to $(srcdir) and should have build tools |
| 332 | # as per $(gnulib_srcdir)/DEPENDENCIES. | 332 | # as per $(gnulib_srcdir)/DEPENDENCIES. |
| 333 | GNULIB_MODULES = \ | 333 | GNULIB_MODULES = \ |
| 334 | crypto/md5 dtoastr filemode getloadavg getopt-gnu \ | 334 | careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu \ |
| 335 | ignore-value intprops lstat mktime readlink \ | 335 | ignore-value intprops lstat mktime readlink \ |
| 336 | socklen stdio strftime symlink sys_stat | 336 | socklen stdio strftime symlink sys_stat |
| 337 | GNULIB_TOOL_FLAGS = \ | 337 | GNULIB_TOOL_FLAGS = \ |
diff --git a/lib/allocator.h b/lib/allocator.h new file mode 100644 index 00000000000..54cc5ff66f0 --- /dev/null +++ b/lib/allocator.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* Memory allocators such as malloc+free. | ||
| 2 | |||
| 3 | Copyright (C) 2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert. */ | ||
| 19 | |||
| 20 | #ifndef _GL_ALLOCATOR_H | ||
| 21 | |||
| 22 | #include <stddef.h> | ||
| 23 | |||
| 24 | struct allocator | ||
| 25 | { | ||
| 26 | /* Call MALLOC to allocate memory, like 'malloc'. On failure MALLOC | ||
| 27 | should return NULL, though not necessarily set errno. When given | ||
| 28 | a zero size it may return NULL even if successful. */ | ||
| 29 | void *(*malloc) (size_t); | ||
| 30 | |||
| 31 | /* If nonnull, call REALLOC to reallocate memory, like 'realloc'. | ||
| 32 | On failure REALLOC should return NULL, though not necessarily set | ||
| 33 | errno. When given a zero size it may return NULL even if | ||
| 34 | successful. */ | ||
| 35 | void *(*realloc) (void *, size_t); | ||
| 36 | |||
| 37 | /* Call FREE to free memory, like 'free'. */ | ||
| 38 | void (*free) (void *); | ||
| 39 | |||
| 40 | /* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should | ||
| 41 | not return. */ | ||
| 42 | void (*die) (void); | ||
| 43 | }; | ||
| 44 | |||
| 45 | #endif | ||
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c new file mode 100644 index 00000000000..828c0508db7 --- /dev/null +++ b/lib/careadlinkat.c | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | /* Read symbolic links into a buffer without size limitation, relative to fd. | ||
| 2 | |||
| 3 | Copyright (C) 2001, 2003-2004, 2007, 2009-2011 Free Software Foundation, | ||
| 4 | Inc. | ||
| 5 | |||
| 6 | This program is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ | ||
| 20 | |||
| 21 | #include <config.h> | ||
| 22 | |||
| 23 | #include "careadlinkat.h" | ||
| 24 | |||
| 25 | #include "allocator.h" | ||
| 26 | |||
| 27 | #include <errno.h> | ||
| 28 | #include <limits.h> | ||
| 29 | #include <stdlib.h> | ||
| 30 | #include <string.h> | ||
| 31 | #include <unistd.h> | ||
| 32 | |||
| 33 | /* Use the system functions, not the gnulib overrides, because this | ||
| 34 | module does not depend on GNU or POSIX semantics. */ | ||
| 35 | #undef malloc | ||
| 36 | #undef realloc | ||
| 37 | |||
| 38 | /* Define this independently so that stdint.h is not a prerequisite. */ | ||
| 39 | #ifndef SIZE_MAX | ||
| 40 | # define SIZE_MAX ((size_t) -1) | ||
| 41 | #endif | ||
| 42 | |||
| 43 | #ifndef SSIZE_MAX | ||
| 44 | # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #if ! HAVE_READLINKAT | ||
| 48 | /* Ignore FD. Get the symbolic link value of FILENAME and put it into | ||
| 49 | BUFFER, with size BUFFER_SIZE. This function acts like readlink | ||
| 50 | but has readlinkat's signature. */ | ||
| 51 | ssize_t | ||
| 52 | careadlinkatcwd (int fd, char const *filename, char *buffer, | ||
| 53 | size_t buffer_size) | ||
| 54 | { | ||
| 55 | (void) fd; | ||
| 56 | return readlink (filename, buffer, buffer_size); | ||
| 57 | } | ||
| 58 | #endif | ||
| 59 | |||
| 60 | /* 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. | ||
| 62 | If FD is AT_FDCWD, FILENAME is interpreted relative to the current | ||
| 63 | working directory, as in openat. | ||
| 64 | |||
| 65 | If the link is small enough to fit into BUFFER put it there. | ||
| 66 | BUFFER's size is BUFFER_SIZE, and BUFFER can be null | ||
| 67 | if BUFFER_SIZE is zero. | ||
| 68 | |||
| 69 | If the link is not small, put it into a dynamically allocated | ||
| 70 | buffer managed by ALLOC. It is the caller's responsibility to free | ||
| 71 | the returned value if it is nonnull and is not BUFFER. A null | ||
| 72 | ALLOC stands for the standard allocator. | ||
| 73 | |||
| 74 | The PREADLINKAT function specifies how to read links. | ||
| 75 | |||
| 76 | If successful, return the buffer address; otherwise return NULL and | ||
| 77 | set errno. */ | ||
| 78 | |||
| 79 | char * | ||
| 80 | careadlinkat (int fd, char const *filename, | ||
| 81 | char *buffer, size_t buffer_size, | ||
| 82 | struct allocator const *alloc, | ||
| 83 | ssize_t (*preadlinkat) (int, char const *, char *, size_t)) | ||
| 84 | { | ||
| 85 | char *buf; | ||
| 86 | size_t buf_size; | ||
| 87 | size_t buf_size_max = | ||
| 88 | SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; | ||
| 89 | char stack_buf[1024]; | ||
| 90 | |||
| 91 | void *(*pmalloc) (size_t) = malloc; | ||
| 92 | void *(*prealloc) (void *, size_t) = realloc; | ||
| 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 | |||
| 103 | if (! buffer_size) | ||
| 104 | { | ||
| 105 | /* Allocate the initial buffer on the stack. This way, in the | ||
| 106 | common case of a symlink of small size, we get away with a | ||
| 107 | single small malloc() instead of a big malloc() followed by a | ||
| 108 | shrinking realloc(). */ | ||
| 109 | buffer = stack_buf; | ||
| 110 | buffer_size = sizeof stack_buf; | ||
| 111 | } | ||
| 112 | |||
| 113 | buf = buffer; | ||
| 114 | buf_size = buffer_size; | ||
| 115 | |||
| 116 | do | ||
| 117 | { | ||
| 118 | /* Attempt to read the link into the current buffer. */ | ||
| 119 | ssize_t link_length = preadlinkat (fd, filename, buf, buf_size); | ||
| 120 | size_t link_size; | ||
| 121 | if (link_length < 0) | ||
| 122 | { | ||
| 123 | /* On AIX 5L v5.3 and HP-UX 11i v2 04/09, readlink returns -1 | ||
| 124 | with errno == ERANGE if the buffer is too small. */ | ||
| 125 | int readlinkat_errno = errno; | ||
| 126 | if (readlinkat_errno != ERANGE) | ||
| 127 | { | ||
| 128 | if (buf != buffer) | ||
| 129 | { | ||
| 130 | pfree (buf); | ||
| 131 | errno = readlinkat_errno; | ||
| 132 | } | ||
| 133 | return NULL; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | link_size = link_length; | ||
| 138 | |||
| 139 | if (link_size < buf_size) | ||
| 140 | { | ||
| 141 | buf[link_size++] = '\0'; | ||
| 142 | |||
| 143 | if (buf == stack_buf) | ||
| 144 | { | ||
| 145 | char *b = (char *) pmalloc (link_size); | ||
| 146 | if (! b) | ||
| 147 | break; | ||
| 148 | memcpy (b, buf, link_size); | ||
| 149 | buf = b; | ||
| 150 | } | ||
| 151 | else if (link_size < buf_size && buf != buffer && prealloc) | ||
| 152 | { | ||
| 153 | /* Shrink BUF before returning it. */ | ||
| 154 | char *b = (char *) prealloc (buf, link_size); | ||
| 155 | if (b) | ||
| 156 | buf = b; | ||
| 157 | } | ||
| 158 | |||
| 159 | return buf; | ||
| 160 | } | ||
| 161 | |||
| 162 | if (buf != buffer) | ||
| 163 | pfree (buf); | ||
| 164 | |||
| 165 | if (buf_size <= buf_size_max / 2) | ||
| 166 | buf_size *= 2; | ||
| 167 | else if (buf_size < buf_size_max) | ||
| 168 | buf_size = buf_size_max; | ||
| 169 | else | ||
| 170 | break; | ||
| 171 | buf = (char *) pmalloc (buf_size); | ||
| 172 | } | ||
| 173 | while (buf); | ||
| 174 | |||
| 175 | if (pdie) | ||
| 176 | pdie (); | ||
| 177 | errno = ENOMEM; | ||
| 178 | return NULL; | ||
| 179 | } | ||
diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h new file mode 100644 index 00000000000..c5e4bcfc15f --- /dev/null +++ b/lib/careadlinkat.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* Read symbolic links into a buffer without size limitation, relative to fd. | ||
| 2 | |||
| 3 | Copyright (C) 2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This program is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ | ||
| 19 | |||
| 20 | #ifndef _GL_CAREADLINKAT_H | ||
| 21 | |||
| 22 | #include <fcntl.h> | ||
| 23 | #include <unistd.h> | ||
| 24 | |||
| 25 | struct allocator; | ||
| 26 | |||
| 27 | /* Assuming the current directory is FD, get the symbolic link value | ||
| 28 | of FILENAME as a null-terminated string and put it into a buffer. | ||
| 29 | If FD is AT_FDCWD, FILENAME is interpreted relative to the current | ||
| 30 | working directory, as in openat. | ||
| 31 | |||
| 32 | If the link is small enough to fit into BUFFER put it there. | ||
| 33 | BUFFER's size is BUFFER_SIZE, and BUFFER can be null | ||
| 34 | if BUFFER_SIZE is zero. | ||
| 35 | |||
| 36 | If the link is not small, put it into a dynamically allocated | ||
| 37 | buffer managed by ALLOC. It is the caller's responsibility to free | ||
| 38 | the returned value if it is nonnull and is not BUFFER. | ||
| 39 | |||
| 40 | The PREADLINKAT function specifies how to read links. | ||
| 41 | |||
| 42 | If successful, return the buffer address; otherwise return NULL and | ||
| 43 | set errno. */ | ||
| 44 | |||
| 45 | char *careadlinkat (int fd, char const *filename, | ||
| 46 | char *buffer, size_t buffer_size, | ||
| 47 | struct allocator const *alloc, | ||
| 48 | ssize_t (*preadlinkat) (int, char const *, | ||
| 49 | char *, size_t)); | ||
| 50 | |||
| 51 | /* Suitable values for careadlinkat's FD and PREADLINKAT arguments, | ||
| 52 | when doing a plain readlink. */ | ||
| 53 | #if HAVE_READLINKAT | ||
| 54 | # define careadlinkatcwd readlinkat | ||
| 55 | #else | ||
| 56 | /* Define AT_FDCWD independently, so that the careadlinkat module does | ||
| 57 | not depend on the fcntl-h module. The value does not matter, since | ||
| 58 | careadlinkatcwd ignores it, but we might as well use the same value | ||
| 59 | as fcntl-h. */ | ||
| 60 | # ifndef AT_FDCWD | ||
| 61 | # define AT_FDCWD (-3041965) | ||
| 62 | # endif | ||
| 63 | ssize_t careadlinkatcwd (int fd, char const *filename, | ||
| 64 | char *buffer, size_t buffer_size); | ||
| 65 | #endif | ||
| 66 | |||
| 67 | #endif /* _GL_CAREADLINKAT_H */ | ||
diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 030f95b7a68..bb5bdcf852e 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | # the same distribution terms as the rest of that program. | 9 | # the same distribution terms as the rest of that program. |
| 10 | # | 10 | # |
| 11 | # Generated by gnulib-tool. | 11 | # Generated by gnulib-tool. |
| 12 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdio strftime symlink sys_stat | 12 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdio strftime symlink sys_stat |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | MOSTLYCLEANFILES += core *.stackdump | 15 | MOSTLYCLEANFILES += core *.stackdump |
| @@ -69,6 +69,14 @@ EXTRA_DIST += $(top_srcdir)/./c++defs.h | |||
| 69 | 69 | ||
| 70 | ## end gnulib module c++defs | 70 | ## end gnulib module c++defs |
| 71 | 71 | ||
| 72 | ## begin gnulib module careadlinkat | ||
| 73 | |||
| 74 | libgnu_a_SOURCES += careadlinkat.c | ||
| 75 | |||
| 76 | EXTRA_DIST += allocator.h careadlinkat.h | ||
| 77 | |||
| 78 | ## end gnulib module careadlinkat | ||
| 79 | |||
| 72 | ## begin gnulib module crypto/md5 | 80 | ## begin gnulib module crypto/md5 |
| 73 | 81 | ||
| 74 | 82 | ||
diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4 index af3cae75abb..43cce9b3676 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 | |||
| @@ -28,6 +28,7 @@ AC_DEFUN([gl_EARLY], | |||
| 28 | AC_REQUIRE([AC_PROG_RANLIB]) | 28 | AC_REQUIRE([AC_PROG_RANLIB]) |
| 29 | # Code from module arg-nonnull: | 29 | # Code from module arg-nonnull: |
| 30 | # Code from module c++defs: | 30 | # Code from module c++defs: |
| 31 | # Code from module careadlinkat: | ||
| 31 | # Code from module crypto/md5: | 32 | # Code from module crypto/md5: |
| 32 | # Code from module dosname: | 33 | # Code from module dosname: |
| 33 | # Code from module dtoastr: | 34 | # Code from module dtoastr: |
| @@ -46,6 +47,7 @@ AC_DEFUN([gl_EARLY], | |||
| 46 | # Code from module multiarch: | 47 | # Code from module multiarch: |
| 47 | # Code from module readlink: | 48 | # Code from module readlink: |
| 48 | # Code from module socklen: | 49 | # Code from module socklen: |
| 50 | # Code from module ssize_t: | ||
| 49 | # Code from module stat: | 51 | # Code from module stat: |
| 50 | # Code from module stdbool: | 52 | # Code from module stdbool: |
| 51 | # Code from module stddef: | 53 | # Code from module stddef: |
| @@ -79,6 +81,8 @@ AC_DEFUN([gl_INIT], | |||
| 79 | gl_source_base='lib' | 81 | gl_source_base='lib' |
| 80 | # Code from module arg-nonnull: | 82 | # Code from module arg-nonnull: |
| 81 | # Code from module c++defs: | 83 | # Code from module c++defs: |
| 84 | # Code from module careadlinkat: | ||
| 85 | AC_CHECK_FUNCS_ONCE([readlinkat]) | ||
| 82 | # Code from module crypto/md5: | 86 | # Code from module crypto/md5: |
| 83 | gl_MD5 | 87 | gl_MD5 |
| 84 | # Code from module dosname: | 88 | # Code from module dosname: |
| @@ -115,6 +119,8 @@ AC_DEFUN([gl_INIT], | |||
| 115 | gl_UNISTD_MODULE_INDICATOR([readlink]) | 119 | gl_UNISTD_MODULE_INDICATOR([readlink]) |
| 116 | # Code from module socklen: | 120 | # Code from module socklen: |
| 117 | gl_TYPE_SOCKLEN_T | 121 | gl_TYPE_SOCKLEN_T |
| 122 | # Code from module ssize_t: | ||
| 123 | gt_TYPE_SSIZE_T | ||
| 118 | # Code from module stat: | 124 | # Code from module stat: |
| 119 | gl_FUNC_STAT | 125 | gl_FUNC_STAT |
| 120 | gl_SYS_STAT_MODULE_INDICATOR([stat]) | 126 | gl_SYS_STAT_MODULE_INDICATOR([stat]) |
| @@ -287,6 +293,9 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 287 | build-aux/arg-nonnull.h | 293 | build-aux/arg-nonnull.h |
| 288 | build-aux/c++defs.h | 294 | build-aux/c++defs.h |
| 289 | build-aux/warn-on-use.h | 295 | build-aux/warn-on-use.h |
| 296 | lib/allocator.h | ||
| 297 | lib/careadlinkat.c | ||
| 298 | lib/careadlinkat.h | ||
| 290 | lib/dosname.h | 299 | lib/dosname.h |
| 291 | lib/dtoastr.c | 300 | lib/dtoastr.c |
| 292 | lib/filemode.c | 301 | lib/filemode.c |
| @@ -335,6 +344,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 335 | m4/multiarch.m4 | 344 | m4/multiarch.m4 |
| 336 | m4/readlink.m4 | 345 | m4/readlink.m4 |
| 337 | m4/socklen.m4 | 346 | m4/socklen.m4 |
| 347 | m4/ssize_t.m4 | ||
| 338 | m4/st_dm_mode.m4 | 348 | m4/st_dm_mode.m4 |
| 339 | m4/stat.m4 | 349 | m4/stat.m4 |
| 340 | m4/stdbool.m4 | 350 | m4/stdbool.m4 |
diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 new file mode 100644 index 00000000000..d7127521ebe --- /dev/null +++ b/m4/ssize_t.m4 | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | # ssize_t.m4 serial 5 (gettext-0.18.2) | ||
| 2 | dnl Copyright (C) 2001-2003, 2006, 2010-2011 Free Software Foundation, Inc. | ||
| 3 | dnl This file is free software; the Free Software Foundation | ||
| 4 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 5 | dnl with or without modifications, as long as this notice is preserved. | ||
| 6 | |||
| 7 | dnl From Bruno Haible. | ||
| 8 | dnl Test whether ssize_t is defined. | ||
| 9 | |||
| 10 | AC_DEFUN([gt_TYPE_SSIZE_T], | ||
| 11 | [ | ||
| 12 | AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t], | ||
| 13 | [AC_COMPILE_IFELSE( | ||
| 14 | [AC_LANG_PROGRAM( | ||
| 15 | [[#include <sys/types.h>]], | ||
| 16 | [[int x = sizeof (ssize_t *) + sizeof (ssize_t); | ||
| 17 | return !x;]])], | ||
| 18 | [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])]) | ||
| 19 | if test $gt_cv_ssize_t = no; then | ||
| 20 | AC_DEFINE([ssize_t], [int], | ||
| 21 | [Define as a signed type of the same size as size_t.]) | ||
| 22 | fi | ||
| 23 | ]) | ||
diff --git a/src/ChangeLog b/src/ChangeLog index c2e28251cb0..5649c8819d3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2011-04-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Replace two copies of readlink code with single gnulib version. | ||
| 4 | The gnulib version avoids calling malloc in the usual case, | ||
| 5 | and on 64-bit hosts doesn't have some arbitrary 32-bit limits. | ||
| 6 | * fileio.c (Ffile_symlink_p): Use emacs_readlink. | ||
| 7 | * filelock.c (current_lock_owner): Likewise. | ||
| 8 | * lisp.h (READLINK_BUFSIZE, emacs_readlink): New function. | ||
| 9 | * sysdep.c: Include allocator.h, careadlinkat.h. | ||
| 10 | (emacs_no_realloc_allocator): New static constant. | ||
| 11 | (emacs_readlink): New function. | ||
| 12 | |||
| 1 | 2011-03-31 Juanma Barranquero <lekktu@gmail.com> | 13 | 2011-03-31 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 14 | ||
| 3 | * xdisp.c (redisplay_internal): Fix prototype. | 15 | * xdisp.c (redisplay_internal): Fix prototype. |
diff --git a/src/fileio.c b/src/fileio.c index 85431dfd5b1..552044f7272 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -2579,9 +2579,8 @@ points to a nonexistent file. */) | |||
| 2579 | { | 2579 | { |
| 2580 | Lisp_Object handler; | 2580 | Lisp_Object handler; |
| 2581 | char *buf; | 2581 | char *buf; |
| 2582 | int bufsize; | ||
| 2583 | int valsize; | ||
| 2584 | Lisp_Object val; | 2582 | Lisp_Object val; |
| 2583 | char readlink_buf[READLINK_BUFSIZE]; | ||
| 2585 | 2584 | ||
| 2586 | CHECK_STRING (filename); | 2585 | CHECK_STRING (filename); |
| 2587 | filename = Fexpand_file_name (filename, Qnil); | 2586 | filename = Fexpand_file_name (filename, Qnil); |
| @@ -2594,36 +2593,15 @@ points to a nonexistent file. */) | |||
| 2594 | 2593 | ||
| 2595 | filename = ENCODE_FILE (filename); | 2594 | filename = ENCODE_FILE (filename); |
| 2596 | 2595 | ||
| 2597 | bufsize = 50; | 2596 | buf = emacs_readlink (SSDATA (filename), readlink_buf); |
| 2598 | buf = NULL; | 2597 | if (! buf) |
| 2599 | do | 2598 | return Qnil; |
| 2600 | { | ||
| 2601 | bufsize *= 2; | ||
| 2602 | buf = (char *) xrealloc (buf, bufsize); | ||
| 2603 | memset (buf, 0, bufsize); | ||
| 2604 | |||
| 2605 | errno = 0; | ||
| 2606 | valsize = readlink (SSDATA (filename), buf, bufsize); | ||
| 2607 | if (valsize == -1) | ||
| 2608 | { | ||
| 2609 | #ifdef ERANGE | ||
| 2610 | /* HP-UX reports ERANGE if buffer is too small. */ | ||
| 2611 | if (errno == ERANGE) | ||
| 2612 | valsize = bufsize; | ||
| 2613 | else | ||
| 2614 | #endif | ||
| 2615 | { | ||
| 2616 | xfree (buf); | ||
| 2617 | return Qnil; | ||
| 2618 | } | ||
| 2619 | } | ||
| 2620 | } | ||
| 2621 | while (valsize >= bufsize); | ||
| 2622 | 2599 | ||
| 2623 | val = make_string (buf, valsize); | 2600 | val = build_string (buf); |
| 2624 | if (buf[0] == '/' && strchr (buf, ':')) | 2601 | if (buf[0] == '/' && strchr (buf, ':')) |
| 2625 | val = concat2 (build_string ("/:"), val); | 2602 | val = concat2 (build_string ("/:"), val); |
| 2626 | xfree (buf); | 2603 | if (buf != readlink_buf) |
| 2604 | xfree (buf); | ||
| 2627 | val = DECODE_FILE (val); | 2605 | val = DECODE_FILE (val); |
| 2628 | return val; | 2606 | return val; |
| 2629 | } | 2607 | } |
diff --git a/src/filelock.c b/src/filelock.c index 2138eaa502b..13b27c72f19 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -396,36 +396,16 @@ within_one_second (time_t a, time_t b) | |||
| 396 | static int | 396 | static int |
| 397 | current_lock_owner (lock_info_type *owner, char *lfname) | 397 | current_lock_owner (lock_info_type *owner, char *lfname) |
| 398 | { | 398 | { |
| 399 | int len, ret; | 399 | int ret; |
| 400 | size_t len; | ||
| 400 | int local_owner = 0; | 401 | int local_owner = 0; |
| 401 | char *at, *dot, *colon; | 402 | char *at, *dot, *colon; |
| 402 | char *lfinfo = 0; | 403 | char readlink_buf[READLINK_BUFSIZE]; |
| 403 | int bufsize = 50; | 404 | char *lfinfo = emacs_readlink (lfname, readlink_buf); |
| 404 | /* Read arbitrarily-long contents of symlink. Similar code in | ||
| 405 | file-symlink-p in fileio.c. */ | ||
| 406 | do | ||
| 407 | { | ||
| 408 | bufsize *= 2; | ||
| 409 | lfinfo = (char *) xrealloc (lfinfo, bufsize); | ||
| 410 | errno = 0; | ||
| 411 | len = readlink (lfname, lfinfo, bufsize); | ||
| 412 | #ifdef ERANGE | ||
| 413 | /* HP-UX reports ERANGE if the buffer is too small. */ | ||
| 414 | if (len == -1 && errno == ERANGE) | ||
| 415 | len = bufsize; | ||
| 416 | #endif | ||
| 417 | } | ||
| 418 | while (len >= bufsize); | ||
| 419 | 405 | ||
| 420 | /* If nonexistent lock file, all is well; otherwise, got strange error. */ | 406 | /* If nonexistent lock file, all is well; otherwise, got strange error. */ |
| 421 | if (len == -1) | 407 | if (!lfinfo) |
| 422 | { | 408 | return errno == ENOENT ? 0 : -1; |
| 423 | xfree (lfinfo); | ||
| 424 | return errno == ENOENT ? 0 : -1; | ||
| 425 | } | ||
| 426 | |||
| 427 | /* Link info exists, so `len' is its length. Null terminate. */ | ||
| 428 | lfinfo[len] = 0; | ||
| 429 | 409 | ||
| 430 | /* Even if the caller doesn't want the owner info, we still have to | 410 | /* Even if the caller doesn't want the owner info, we still have to |
| 431 | read it to determine return value, so allocate it. */ | 411 | read it to determine return value, so allocate it. */ |
| @@ -441,7 +421,8 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 441 | dot = strrchr (lfinfo, '.'); | 421 | dot = strrchr (lfinfo, '.'); |
| 442 | if (!at || !dot) | 422 | if (!at || !dot) |
| 443 | { | 423 | { |
| 444 | xfree (lfinfo); | 424 | if (lfinfo != readlink_buf) |
| 425 | xfree (lfinfo); | ||
| 445 | return -1; | 426 | return -1; |
| 446 | } | 427 | } |
| 447 | len = at - lfinfo; | 428 | len = at - lfinfo; |
| @@ -467,7 +448,8 @@ current_lock_owner (lock_info_type *owner, char *lfname) | |||
| 467 | owner->host[len] = 0; | 448 | owner->host[len] = 0; |
| 468 | 449 | ||
| 469 | /* We're done looking at the link info. */ | 450 | /* We're done looking at the link info. */ |
| 470 | xfree (lfinfo); | 451 | if (lfinfo != readlink_buf) |
| 452 | xfree (lfinfo); | ||
| 471 | 453 | ||
| 472 | /* On current host? */ | 454 | /* On current host? */ |
| 473 | if (STRINGP (Fsystem_name ()) | 455 | if (STRINGP (Fsystem_name ()) |
diff --git a/src/lisp.h b/src/lisp.h index 85838d111db..63f346f6a25 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3340,6 +3340,8 @@ extern int emacs_open (const char *, int, int); | |||
| 3340 | extern int emacs_close (int); | 3340 | extern int emacs_close (int); |
| 3341 | extern int emacs_read (int, char *, unsigned int); | 3341 | extern int emacs_read (int, char *, unsigned int); |
| 3342 | extern int emacs_write (int, const char *, unsigned int); | 3342 | extern int emacs_write (int, const char *, unsigned int); |
| 3343 | enum { READLINK_BUFSIZE = 1024 }; | ||
| 3344 | extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]); | ||
| 3343 | #ifndef HAVE_MEMSET | 3345 | #ifndef HAVE_MEMSET |
| 3344 | extern void *memset (void *, int, size_t); | 3346 | extern void *memset (void *, int, size_t); |
| 3345 | #endif | 3347 | #endif |
diff --git a/src/sysdep.c b/src/sysdep.c index 1bb400421f0..a165a9ca52f 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -31,6 +31,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 31 | #endif /* HAVE_LIMITS_H */ | 31 | #endif /* HAVE_LIMITS_H */ |
| 32 | #include <unistd.h> | 32 | #include <unistd.h> |
| 33 | 33 | ||
| 34 | #include <allocator.h> | ||
| 35 | #include <careadlinkat.h> | ||
| 34 | #include <ignore-value.h> | 36 | #include <ignore-value.h> |
| 35 | 37 | ||
| 36 | #include "lisp.h" | 38 | #include "lisp.h" |
| @@ -1866,6 +1868,22 @@ emacs_write (int fildes, const char *buf, unsigned int nbyte) | |||
| 1866 | } | 1868 | } |
| 1867 | return (bytes_written); | 1869 | return (bytes_written); |
| 1868 | } | 1870 | } |
| 1871 | |||
| 1872 | static struct allocator const emacs_norealloc_allocator = | ||
| 1873 | { xmalloc, NULL, xfree, memory_full }; | ||
| 1874 | |||
| 1875 | /* Get the symbolic link value of FILENAME. Return a pointer to a | ||
| 1876 | NUL-terminated string. If readlink fails, return NULL and set | ||
| 1877 | errno. If the value fits in INITIAL_BUF, return INITIAL_BUF. | ||
| 1878 | Otherwise, allocate memory and return a pointer to that memory. If | ||
| 1879 | memory allocation fails, diagnose and fail without returning. If | ||
| 1880 | successful, store the length of the symbolic link into *LINKLEN. */ | ||
| 1881 | char * | ||
| 1882 | emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE]) | ||
| 1883 | { | ||
| 1884 | return careadlinkat (AT_FDCWD, filename, initial_buf, READLINK_BUFSIZE, | ||
| 1885 | &emacs_norealloc_allocator, careadlinkatcwd); | ||
| 1886 | } | ||
| 1869 | 1887 | ||
| 1870 | #ifdef USG | 1888 | #ifdef USG |
| 1871 | /* | 1889 | /* |