diff options
| author | Ton Voon <ton.voon@opsera.com> | 2010-06-24 10:02:31 +0100 |
|---|---|---|
| committer | Ton Voon <ton.voon@opsera.com> | 2010-06-24 10:02:31 +0100 |
| commit | 342f3b403e888800fb1b0502bf4e0d8268358573 (patch) | |
| tree | 47a0031fcf01edae3131fc147304d14f6f2aee20 /gl | |
| parent | f789a37b057b6f34820ea4f95d63f53b5a84c980 (diff) | |
| download | monitoring-plugins-342f3b403e888800fb1b0502bf4e0d8268358573.tar.gz | |
Added unsetenv and setenv from gnulib
Diffstat (limited to 'gl')
| -rw-r--r-- | gl/Makefile.am | 28 | ||||
| -rw-r--r-- | gl/m4/eealloc.m4 | 32 | ||||
| -rw-r--r-- | gl/m4/environ.m4 | 36 | ||||
| -rw-r--r-- | gl/m4/gnulib-cache.m4 | 4 | ||||
| -rw-r--r-- | gl/m4/gnulib-comp.m4 | 24 | ||||
| -rw-r--r-- | gl/m4/malloca.m4 | 15 | ||||
| -rw-r--r-- | gl/m4/setenv.m4 | 111 | ||||
| -rw-r--r-- | gl/malloca.c | 140 | ||||
| -rw-r--r-- | gl/malloca.h | 134 | ||||
| -rw-r--r-- | gl/malloca.valgrind | 7 | ||||
| -rw-r--r-- | gl/setenv.c | 390 | ||||
| -rw-r--r-- | gl/unsetenv.c | 120 |
12 files changed, 1039 insertions, 2 deletions
diff --git a/gl/Makefile.am b/gl/Makefile.am index 2f5f9c43..41a370b0 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am | |||
| @@ -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=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex strsep timegm vasprintf vsnprintf | 12 | # Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex setenv strsep timegm unsetenv vasprintf vsnprintf |
| 13 | 13 | ||
| 14 | AUTOMAKE_OPTIONS = 1.5 gnits | 14 | AUTOMAKE_OPTIONS = 1.5 gnits |
| 15 | 15 | ||
| @@ -678,6 +678,14 @@ EXTRA_libgnu_a_SOURCES += malloc.c | |||
| 678 | 678 | ||
| 679 | ## end gnulib module malloc-posix | 679 | ## end gnulib module malloc-posix |
| 680 | 680 | ||
| 681 | ## begin gnulib module malloca | ||
| 682 | |||
| 683 | libgnu_a_SOURCES += malloca.c | ||
| 684 | |||
| 685 | EXTRA_DIST += malloca.h malloca.valgrind | ||
| 686 | |||
| 687 | ## end gnulib module malloca | ||
| 688 | |||
| 681 | ## begin gnulib module math | 689 | ## begin gnulib module math |
| 682 | 690 | ||
| 683 | BUILT_SOURCES += math.h | 691 | BUILT_SOURCES += math.h |
| @@ -928,6 +936,15 @@ EXTRA_libgnu_a_SOURCES += safe-write.c | |||
| 928 | 936 | ||
| 929 | ## end gnulib module safe-write | 937 | ## end gnulib module safe-write |
| 930 | 938 | ||
| 939 | ## begin gnulib module setenv | ||
| 940 | |||
| 941 | |||
| 942 | EXTRA_DIST += setenv.c | ||
| 943 | |||
| 944 | EXTRA_libgnu_a_SOURCES += setenv.c | ||
| 945 | |||
| 946 | ## end gnulib module setenv | ||
| 947 | |||
| 931 | ## begin gnulib module size_max | 948 | ## begin gnulib module size_max |
| 932 | 949 | ||
| 933 | libgnu_a_SOURCES += size_max.h | 950 | libgnu_a_SOURCES += size_max.h |
| @@ -1683,6 +1700,15 @@ EXTRA_libgnu_a_SOURCES += dup-safer.c fd-safer.c pipe-safer.c | |||
| 1683 | 1700 | ||
| 1684 | ## end gnulib module unistd-safer | 1701 | ## end gnulib module unistd-safer |
| 1685 | 1702 | ||
| 1703 | ## begin gnulib module unsetenv | ||
| 1704 | |||
| 1705 | |||
| 1706 | EXTRA_DIST += unsetenv.c | ||
| 1707 | |||
| 1708 | EXTRA_libgnu_a_SOURCES += unsetenv.c | ||
| 1709 | |||
| 1710 | ## end gnulib module unsetenv | ||
| 1711 | |||
| 1686 | ## begin gnulib module vasnprintf | 1712 | ## begin gnulib module vasnprintf |
| 1687 | 1713 | ||
| 1688 | 1714 | ||
diff --git a/gl/m4/eealloc.m4 b/gl/m4/eealloc.m4 new file mode 100644 index 00000000..63dd9202 --- /dev/null +++ b/gl/m4/eealloc.m4 | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | # eealloc.m4 serial 2 | ||
| 2 | dnl Copyright (C) 2003, 2009, 2010 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 | AC_DEFUN([gl_EEALLOC], | ||
| 8 | [ | ||
| 9 | AC_REQUIRE([gl_EEMALLOC]) | ||
| 10 | AC_REQUIRE([gl_EEREALLOC]) | ||
| 11 | AC_REQUIRE([AC_C_INLINE]) | ||
| 12 | ]) | ||
| 13 | |||
| 14 | AC_DEFUN([gl_EEMALLOC], | ||
| 15 | [ | ||
| 16 | _AC_FUNC_MALLOC_IF( | ||
| 17 | [gl_cv_func_malloc_0_nonnull=1], | ||
| 18 | [gl_cv_func_malloc_0_nonnull=0]) | ||
| 19 | AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], | ||
| 20 | [If malloc(0) is != NULL, define this to 1. Otherwise define this | ||
| 21 | to 0.]) | ||
| 22 | ]) | ||
| 23 | |||
| 24 | AC_DEFUN([gl_EEREALLOC], | ||
| 25 | [ | ||
| 26 | _AC_FUNC_REALLOC_IF( | ||
| 27 | [gl_cv_func_realloc_0_nonnull=1], | ||
| 28 | [gl_cv_func_realloc_0_nonnull=0]) | ||
| 29 | AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], | ||
| 30 | [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this | ||
| 31 | to 0.]) | ||
| 32 | ]) | ||
diff --git a/gl/m4/environ.m4 b/gl/m4/environ.m4 new file mode 100644 index 00000000..4c6849a3 --- /dev/null +++ b/gl/m4/environ.m4 | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | # environ.m4 serial 4 | ||
| 2 | dnl Copyright (C) 2001-2004, 2006-2010 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 | AC_DEFUN_ONCE([gl_ENVIRON], | ||
| 8 | [ | ||
| 9 | AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) | ||
| 10 | dnl Persuade glibc <unistd.h> to declare environ. | ||
| 11 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 12 | gt_CHECK_VAR_DECL([#include <unistd.h>], environ) | ||
| 13 | if test $gt_cv_var_environ_declaration != yes; then | ||
| 14 | HAVE_DECL_ENVIRON=0 | ||
| 15 | fi | ||
| 16 | ]) | ||
| 17 | |||
| 18 | # Check if a variable is properly declared. | ||
| 19 | # gt_CHECK_VAR_DECL(includes,variable) | ||
| 20 | AC_DEFUN([gt_CHECK_VAR_DECL], | ||
| 21 | [ | ||
| 22 | define([gt_cv_var], [gt_cv_var_]$2[_declaration]) | ||
| 23 | AC_MSG_CHECKING([if $2 is properly declared]) | ||
| 24 | AC_CACHE_VAL([gt_cv_var], [ | ||
| 25 | AC_TRY_COMPILE([$1 | ||
| 26 | extern struct { int foo; } $2;], | ||
| 27 | [$2.foo = 1;], | ||
| 28 | gt_cv_var=no, | ||
| 29 | gt_cv_var=yes)]) | ||
| 30 | AC_MSG_RESULT([$gt_cv_var]) | ||
| 31 | if test $gt_cv_var = yes; then | ||
| 32 | AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1, | ||
| 33 | [Define if you have the declaration of $2.]) | ||
| 34 | fi | ||
| 35 | undefine([gt_cv_var]) | ||
| 36 | ]) | ||
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index f23cb519..22e61333 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | # Specification in the form of a command-line invocation: | 17 | # Specification in the form of a command-line invocation: |
| 18 | # gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex strsep timegm vasprintf vsnprintf | 18 | # gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname floorf fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex setenv strsep timegm unsetenv vasprintf vsnprintf |
| 19 | 19 | ||
| 20 | # Specification in the form of a few gnulib-tool.m4 macro invocations: | 20 | # Specification in the form of a few gnulib-tool.m4 macro invocations: |
| 21 | gl_LOCAL_DIR([]) | 21 | gl_LOCAL_DIR([]) |
| @@ -32,8 +32,10 @@ gl_MODULES([ | |||
| 32 | gettext | 32 | gettext |
| 33 | mountlist | 33 | mountlist |
| 34 | regex | 34 | regex |
| 35 | setenv | ||
| 35 | strsep | 36 | strsep |
| 36 | timegm | 37 | timegm |
| 38 | unsetenv | ||
| 37 | vasprintf | 39 | vasprintf |
| 38 | vsnprintf | 40 | vsnprintf |
| 39 | ]) | 41 | ]) |
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index 73e63654..fc3f3538 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 | |||
| @@ -41,6 +41,7 @@ AC_DEFUN([gl_EARLY], | |||
| 41 | # Code from module dirname-lgpl: | 41 | # Code from module dirname-lgpl: |
| 42 | # Code from module double-slash-root: | 42 | # Code from module double-slash-root: |
| 43 | # Code from module dup2: | 43 | # Code from module dup2: |
| 44 | # Code from module environ: | ||
| 44 | # Code from module errno: | 45 | # Code from module errno: |
| 45 | # Code from module error: | 46 | # Code from module error: |
| 46 | # Code from module exitfail: | 47 | # Code from module exitfail: |
| @@ -74,6 +75,7 @@ AC_DEFUN([gl_EARLY], | |||
| 74 | # Code from module locale: | 75 | # Code from module locale: |
| 75 | # Code from module malloc: | 76 | # Code from module malloc: |
| 76 | # Code from module malloc-posix: | 77 | # Code from module malloc-posix: |
| 78 | # Code from module malloca: | ||
| 77 | # Code from module math: | 79 | # Code from module math: |
| 78 | # Code from module mbrtowc: | 80 | # Code from module mbrtowc: |
| 79 | # Code from module mbsinit: | 81 | # Code from module mbsinit: |
| @@ -89,6 +91,7 @@ AC_DEFUN([gl_EARLY], | |||
| 89 | # Code from module safe-read: | 91 | # Code from module safe-read: |
| 90 | # Code from module safe-write: | 92 | # Code from module safe-write: |
| 91 | # Code from module servent: | 93 | # Code from module servent: |
| 94 | # Code from module setenv: | ||
| 92 | # Code from module size_max: | 95 | # Code from module size_max: |
| 93 | # Code from module snprintf: | 96 | # Code from module snprintf: |
| 94 | # Code from module sockets: | 97 | # Code from module sockets: |
| @@ -115,6 +118,7 @@ AC_DEFUN([gl_EARLY], | |||
| 115 | # Code from module timegm: | 118 | # Code from module timegm: |
| 116 | # Code from module unistd: | 119 | # Code from module unistd: |
| 117 | # Code from module unistd-safer: | 120 | # Code from module unistd-safer: |
| 121 | # Code from module unsetenv: | ||
| 118 | # Code from module vasnprintf: | 122 | # Code from module vasnprintf: |
| 119 | # Code from module vasprintf: | 123 | # Code from module vasprintf: |
| 120 | # Code from module verify: | 124 | # Code from module verify: |
| @@ -178,6 +182,9 @@ AC_DEFUN([gl_INIT], | |||
| 178 | # Code from module dup2: | 182 | # Code from module dup2: |
| 179 | gl_FUNC_DUP2 | 183 | gl_FUNC_DUP2 |
| 180 | gl_UNISTD_MODULE_INDICATOR([dup2]) | 184 | gl_UNISTD_MODULE_INDICATOR([dup2]) |
| 185 | # Code from module environ: | ||
| 186 | gl_ENVIRON | ||
| 187 | gl_UNISTD_MODULE_INDICATOR([environ]) | ||
| 181 | # Code from module errno: | 188 | # Code from module errno: |
| 182 | gl_HEADER_ERRNO_H | 189 | gl_HEADER_ERRNO_H |
| 183 | # Code from module error: | 190 | # Code from module error: |
| @@ -252,6 +259,8 @@ AC_DEFUN([gl_INIT], | |||
| 252 | # Code from module malloc-posix: | 259 | # Code from module malloc-posix: |
| 253 | gl_FUNC_MALLOC_POSIX | 260 | gl_FUNC_MALLOC_POSIX |
| 254 | gl_STDLIB_MODULE_INDICATOR([malloc-posix]) | 261 | gl_STDLIB_MODULE_INDICATOR([malloc-posix]) |
| 262 | # Code from module malloca: | ||
| 263 | gl_MALLOCA | ||
| 255 | # Code from module math: | 264 | # Code from module math: |
| 256 | gl_MATH_H | 265 | gl_MATH_H |
| 257 | # Code from module mbrtowc: | 266 | # Code from module mbrtowc: |
| @@ -289,6 +298,9 @@ AC_DEFUN([gl_INIT], | |||
| 289 | gl_SAFE_WRITE | 298 | gl_SAFE_WRITE |
| 290 | # Code from module servent: | 299 | # Code from module servent: |
| 291 | gl_SERVENT | 300 | gl_SERVENT |
| 301 | # Code from module setenv: | ||
| 302 | gl_FUNC_SETENV | ||
| 303 | gl_STDLIB_MODULE_INDICATOR([setenv]) | ||
| 292 | # Code from module size_max: | 304 | # Code from module size_max: |
| 293 | gl_SIZE_MAX | 305 | gl_SIZE_MAX |
| 294 | # Code from module snprintf: | 306 | # Code from module snprintf: |
| @@ -352,6 +364,9 @@ AC_DEFUN([gl_INIT], | |||
| 352 | gl_UNISTD_H | 364 | gl_UNISTD_H |
| 353 | # Code from module unistd-safer: | 365 | # Code from module unistd-safer: |
| 354 | gl_UNISTD_SAFER | 366 | gl_UNISTD_SAFER |
| 367 | # Code from module unsetenv: | ||
| 368 | gl_FUNC_UNSETENV | ||
| 369 | gl_STDLIB_MODULE_INDICATOR([unsetenv]) | ||
| 355 | # Code from module vasnprintf: | 370 | # Code from module vasnprintf: |
| 356 | gl_FUNC_VASNPRINTF | 371 | gl_FUNC_VASNPRINTF |
| 357 | # Code from module vasprintf: | 372 | # Code from module vasprintf: |
| @@ -586,6 +601,9 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 586 | lib/localcharset.h | 601 | lib/localcharset.h |
| 587 | lib/locale.in.h | 602 | lib/locale.in.h |
| 588 | lib/malloc.c | 603 | lib/malloc.c |
| 604 | lib/malloca.c | ||
| 605 | lib/malloca.h | ||
| 606 | lib/malloca.valgrind | ||
| 589 | lib/math.in.h | 607 | lib/math.in.h |
| 590 | lib/mbrtowc.c | 608 | lib/mbrtowc.c |
| 591 | lib/mbsinit.c | 609 | lib/mbsinit.c |
| @@ -617,6 +635,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 617 | lib/safe-read.h | 635 | lib/safe-read.h |
| 618 | lib/safe-write.c | 636 | lib/safe-write.c |
| 619 | lib/safe-write.h | 637 | lib/safe-write.h |
| 638 | lib/setenv.c | ||
| 620 | lib/sha1.c | 639 | lib/sha1.c |
| 621 | lib/sha1.h | 640 | lib/sha1.h |
| 622 | lib/size_max.h | 641 | lib/size_max.h |
| @@ -648,6 +667,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 648 | lib/unistd--.h | 667 | lib/unistd--.h |
| 649 | lib/unistd-safer.h | 668 | lib/unistd-safer.h |
| 650 | lib/unistd.in.h | 669 | lib/unistd.in.h |
| 670 | lib/unsetenv.c | ||
| 651 | lib/vasnprintf.c | 671 | lib/vasnprintf.c |
| 652 | lib/vasnprintf.h | 672 | lib/vasnprintf.h |
| 653 | lib/vasprintf.c | 673 | lib/vasprintf.c |
| @@ -677,6 +697,8 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 677 | m4/dos.m4 | 697 | m4/dos.m4 |
| 678 | m4/double-slash-root.m4 | 698 | m4/double-slash-root.m4 |
| 679 | m4/dup2.m4 | 699 | m4/dup2.m4 |
| 700 | m4/eealloc.m4 | ||
| 701 | m4/environ.m4 | ||
| 680 | m4/errno_h.m4 | 702 | m4/errno_h.m4 |
| 681 | m4/error.m4 | 703 | m4/error.m4 |
| 682 | m4/extensions.m4 | 704 | m4/extensions.m4 |
| @@ -724,6 +746,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 724 | m4/longlong.m4 | 746 | m4/longlong.m4 |
| 725 | m4/ls-mntd-fs.m4 | 747 | m4/ls-mntd-fs.m4 |
| 726 | m4/malloc.m4 | 748 | m4/malloc.m4 |
| 749 | m4/malloca.m4 | ||
| 727 | m4/math_h.m4 | 750 | m4/math_h.m4 |
| 728 | m4/mbrtowc.m4 | 751 | m4/mbrtowc.m4 |
| 729 | m4/mbsinit.m4 | 752 | m4/mbsinit.m4 |
| @@ -748,6 +771,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 748 | m4/safe-read.m4 | 771 | m4/safe-read.m4 |
| 749 | m4/safe-write.m4 | 772 | m4/safe-write.m4 |
| 750 | m4/servent.m4 | 773 | m4/servent.m4 |
| 774 | m4/setenv.m4 | ||
| 751 | m4/sha1.m4 | 775 | m4/sha1.m4 |
| 752 | m4/size_max.m4 | 776 | m4/size_max.m4 |
| 753 | m4/snprintf.m4 | 777 | m4/snprintf.m4 |
diff --git a/gl/m4/malloca.m4 b/gl/m4/malloca.m4 new file mode 100644 index 00000000..e07c6d93 --- /dev/null +++ b/gl/m4/malloca.m4 | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # malloca.m4 serial 1 | ||
| 2 | dnl Copyright (C) 2003-2004, 2006-2007, 2009-2010 Free Software Foundation, | ||
| 3 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | AC_DEFUN([gl_MALLOCA], | ||
| 9 | [ | ||
| 10 | dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables | ||
| 11 | dnl @ALLOCA@ and @LTALLOCA@. | ||
| 12 | dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. | ||
| 13 | AC_REQUIRE([gl_EEMALLOC]) | ||
| 14 | AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) | ||
| 15 | ]) | ||
diff --git a/gl/m4/setenv.m4 b/gl/m4/setenv.m4 new file mode 100644 index 00000000..58f6d138 --- /dev/null +++ b/gl/m4/setenv.m4 | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | # setenv.m4 serial 16 | ||
| 2 | dnl Copyright (C) 2001-2004, 2006-2010 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 | AC_DEFUN([gl_FUNC_SETENV], | ||
| 8 | [ | ||
| 9 | AC_REQUIRE([gl_FUNC_SETENV_SEPARATE]) | ||
| 10 | if test $HAVE_SETENV$REPLACE_SETENV != 10; then | ||
| 11 | AC_LIBOBJ([setenv]) | ||
| 12 | fi | ||
| 13 | ]) | ||
| 14 | |||
| 15 | # Like gl_FUNC_SETENV, except prepare for separate compilation (no AC_LIBOBJ). | ||
| 16 | AC_DEFUN([gl_FUNC_SETENV_SEPARATE], | ||
| 17 | [ | ||
| 18 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
| 19 | AC_CHECK_FUNCS_ONCE([setenv]) | ||
| 20 | if test $ac_cv_func_setenv = no; then | ||
| 21 | HAVE_SETENV=0 | ||
| 22 | else | ||
| 23 | AC_CACHE_CHECK([whether setenv validates arguments], | ||
| 24 | [gl_cv_func_setenv_works], | ||
| 25 | [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ | ||
| 26 | #include <stdlib.h> | ||
| 27 | #include <errno.h> | ||
| 28 | #include <string.h> | ||
| 29 | ]], [[ | ||
| 30 | if (setenv ("", "", 0) != -1) return 1; | ||
| 31 | if (errno != EINVAL) return 2; | ||
| 32 | if (setenv ("a", "=", 1) != 0) return 3; | ||
| 33 | if (strcmp (getenv ("a"), "=") != 0) return 4; | ||
| 34 | ]])], | ||
| 35 | [gl_cv_func_setenv_works=yes], [gl_cv_func_setenv_works=no], | ||
| 36 | [gl_cv_func_setenv_works="guessing no"])]) | ||
| 37 | if test "$gl_cv_func_setenv_works" != yes; then | ||
| 38 | REPLACE_SETENV=1 | ||
| 39 | AC_LIBOBJ([setenv]) | ||
| 40 | fi | ||
| 41 | fi | ||
| 42 | gl_PREREQ_SETENV | ||
| 43 | ]) | ||
| 44 | |||
| 45 | AC_DEFUN([gl_FUNC_UNSETENV], | ||
| 46 | [ | ||
| 47 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
| 48 | AC_CHECK_FUNCS([unsetenv]) | ||
| 49 | if test $ac_cv_func_unsetenv = no; then | ||
| 50 | HAVE_UNSETENV=0 | ||
| 51 | AC_LIBOBJ([unsetenv]) | ||
| 52 | gl_PREREQ_UNSETENV | ||
| 53 | else | ||
| 54 | dnl Some BSDs return void, failing to do error checking. | ||
| 55 | AC_CACHE_CHECK([for unsetenv() return type], [gt_cv_func_unsetenv_ret], | ||
| 56 | [AC_TRY_COMPILE([#include <stdlib.h> | ||
| 57 | extern | ||
| 58 | #ifdef __cplusplus | ||
| 59 | "C" | ||
| 60 | #endif | ||
| 61 | #if defined(__STDC__) || defined(__cplusplus) | ||
| 62 | int unsetenv (const char *name); | ||
| 63 | #else | ||
| 64 | int unsetenv(); | ||
| 65 | #endif | ||
| 66 | ], , gt_cv_func_unsetenv_ret='int', gt_cv_func_unsetenv_ret='void')]) | ||
| 67 | if test $gt_cv_func_unsetenv_ret = 'void'; then | ||
| 68 | AC_DEFINE([VOID_UNSETENV], [1], [Define to 1 if unsetenv returns void | ||
| 69 | instead of int.]) | ||
| 70 | REPLACE_UNSETENV=1 | ||
| 71 | AC_LIBOBJ([unsetenv]) | ||
| 72 | fi | ||
| 73 | |||
| 74 | dnl Solaris 10 unsetenv does not remove all copies of a name. | ||
| 75 | AC_CACHE_CHECK([whether unsetenv works on duplicates], | ||
| 76 | [gl_cv_func_unsetenv_works], | ||
| 77 | [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ | ||
| 78 | #include <stdlib.h> | ||
| 79 | ]], [[ | ||
| 80 | char entry[] = "b=2"; | ||
| 81 | if (putenv ((char *) "a=1")) return 1; | ||
| 82 | if (putenv (entry)) return 2; | ||
| 83 | entry[0] = 'a'; | ||
| 84 | unsetenv ("a"); | ||
| 85 | if (getenv ("a")) return 3; | ||
| 86 | ]])], | ||
| 87 | [gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no], | ||
| 88 | [gl_cv_func_unsetenv_works="guessing no"])]) | ||
| 89 | if test "$gl_cv_func_unsetenv_works" != yes; then | ||
| 90 | REPLACE_UNSETENV=1 | ||
| 91 | AC_LIBOBJ([unsetenv]) | ||
| 92 | fi | ||
| 93 | fi | ||
| 94 | ]) | ||
| 95 | |||
| 96 | # Prerequisites of lib/setenv.c. | ||
| 97 | AC_DEFUN([gl_PREREQ_SETENV], | ||
| 98 | [ | ||
| 99 | AC_REQUIRE([AC_FUNC_ALLOCA]) | ||
| 100 | AC_REQUIRE([gl_ENVIRON]) | ||
| 101 | AC_CHECK_HEADERS_ONCE([unistd.h]) | ||
| 102 | AC_CHECK_HEADERS([search.h]) | ||
| 103 | AC_CHECK_FUNCS([tsearch]) | ||
| 104 | ]) | ||
| 105 | |||
| 106 | # Prerequisites of lib/unsetenv.c. | ||
| 107 | AC_DEFUN([gl_PREREQ_UNSETENV], | ||
| 108 | [ | ||
| 109 | AC_REQUIRE([gl_ENVIRON]) | ||
| 110 | AC_CHECK_HEADERS_ONCE([unistd.h]) | ||
| 111 | ]) | ||
diff --git a/gl/malloca.c b/gl/malloca.c new file mode 100644 index 00000000..21bbc1f5 --- /dev/null +++ b/gl/malloca.c | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /* Safe automatic memory allocation. | ||
| 2 | Copyright (C) 2003, 2006-2007, 2009-2010 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2003. | ||
| 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, or (at your option) | ||
| 8 | 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, write to the Free Software Foundation, | ||
| 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | /* Specification. */ | ||
| 22 | #include "malloca.h" | ||
| 23 | |||
| 24 | /* Use the system functions, not the gnulib overrides in this file. */ | ||
| 25 | #undef malloc | ||
| 26 | |||
| 27 | /* The speed critical point in this file is freea() applied to an alloca() | ||
| 28 | result: it must be fast, to match the speed of alloca(). The speed of | ||
| 29 | mmalloca() and freea() in the other case are not critical, because they | ||
| 30 | are only invoked for big memory sizes. */ | ||
| 31 | |||
| 32 | #if HAVE_ALLOCA | ||
| 33 | |||
| 34 | /* Store the mmalloca() results in a hash table. This is needed to reliably | ||
| 35 | distinguish a mmalloca() result and an alloca() result. | ||
| 36 | |||
| 37 | Although it is possible that the same pointer is returned by alloca() and | ||
| 38 | by mmalloca() at different times in the same application, it does not lead | ||
| 39 | to a bug in freea(), because: | ||
| 40 | - Before a pointer returned by alloca() can point into malloc()ed memory, | ||
| 41 | the function must return, and once this has happened the programmer must | ||
| 42 | not call freea() on it anyway. | ||
| 43 | - Before a pointer returned by mmalloca() can point into the stack, it | ||
| 44 | must be freed. The only function that can free it is freea(), and | ||
| 45 | when freea() frees it, it also removes it from the hash table. */ | ||
| 46 | |||
| 47 | #define MAGIC_NUMBER 0x1415fb4a | ||
| 48 | #define MAGIC_SIZE sizeof (int) | ||
| 49 | /* This is how the header info would look like without any alignment | ||
| 50 | considerations. */ | ||
| 51 | struct preliminary_header { void *next; char room[MAGIC_SIZE]; }; | ||
| 52 | /* But the header's size must be a multiple of sa_alignment_max. */ | ||
| 53 | #define HEADER_SIZE \ | ||
| 54 | (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) | ||
| 55 | struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; }; | ||
| 56 | /* Verify that HEADER_SIZE == sizeof (struct header). */ | ||
| 57 | typedef int verify1[2 * (HEADER_SIZE == sizeof (struct header)) - 1]; | ||
| 58 | /* We make the hash table quite big, so that during lookups the probability | ||
| 59 | of empty hash buckets is quite high. There is no need to make the hash | ||
| 60 | table resizable, because when the hash table gets filled so much that the | ||
| 61 | lookup becomes slow, it means that the application has memory leaks. */ | ||
| 62 | #define HASH_TABLE_SIZE 257 | ||
| 63 | static void * mmalloca_results[HASH_TABLE_SIZE]; | ||
| 64 | |||
| 65 | #endif | ||
| 66 | |||
| 67 | void * | ||
| 68 | mmalloca (size_t n) | ||
| 69 | { | ||
| 70 | #if HAVE_ALLOCA | ||
| 71 | /* Allocate one more word, that serves as an indicator for malloc()ed | ||
| 72 | memory, so that freea() of an alloca() result is fast. */ | ||
| 73 | size_t nplus = n + HEADER_SIZE; | ||
| 74 | |||
| 75 | if (nplus >= n) | ||
| 76 | { | ||
| 77 | char *p = (char *) malloc (nplus); | ||
| 78 | |||
| 79 | if (p != NULL) | ||
| 80 | { | ||
| 81 | size_t slot; | ||
| 82 | |||
| 83 | p += HEADER_SIZE; | ||
| 84 | |||
| 85 | /* Put a magic number into the indicator word. */ | ||
| 86 | ((int *) p)[-1] = MAGIC_NUMBER; | ||
| 87 | |||
| 88 | /* Enter p into the hash table. */ | ||
| 89 | slot = (unsigned long) p % HASH_TABLE_SIZE; | ||
| 90 | ((struct header *) (p - HEADER_SIZE))->next = mmalloca_results[slot]; | ||
| 91 | mmalloca_results[slot] = p; | ||
| 92 | |||
| 93 | return p; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | /* Out of memory. */ | ||
| 97 | return NULL; | ||
| 98 | #else | ||
| 99 | # if !MALLOC_0_IS_NONNULL | ||
| 100 | if (n == 0) | ||
| 101 | n = 1; | ||
| 102 | # endif | ||
| 103 | return malloc (n); | ||
| 104 | #endif | ||
| 105 | } | ||
| 106 | |||
| 107 | #if HAVE_ALLOCA | ||
| 108 | void | ||
| 109 | freea (void *p) | ||
| 110 | { | ||
| 111 | /* mmalloca() may have returned NULL. */ | ||
| 112 | if (p != NULL) | ||
| 113 | { | ||
| 114 | /* Attempt to quickly distinguish the mmalloca() result - which has | ||
| 115 | a magic indicator word - and the alloca() result - which has an | ||
| 116 | uninitialized indicator word. It is for this test that sa_increment | ||
| 117 | additional bytes are allocated in the alloca() case. */ | ||
| 118 | if (((int *) p)[-1] == MAGIC_NUMBER) | ||
| 119 | { | ||
| 120 | /* Looks like a mmalloca() result. To see whether it really is one, | ||
| 121 | perform a lookup in the hash table. */ | ||
| 122 | size_t slot = (unsigned long) p % HASH_TABLE_SIZE; | ||
| 123 | void **chain = &mmalloca_results[slot]; | ||
| 124 | for (; *chain != NULL;) | ||
| 125 | { | ||
| 126 | if (*chain == p) | ||
| 127 | { | ||
| 128 | /* Found it. Remove it from the hash table and free it. */ | ||
| 129 | char *p_begin = (char *) p - HEADER_SIZE; | ||
| 130 | *chain = ((struct header *) p_begin)->next; | ||
| 131 | free (p_begin); | ||
| 132 | return; | ||
| 133 | } | ||
| 134 | chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | /* At this point, we know it was not a mmalloca() result. */ | ||
| 138 | } | ||
| 139 | } | ||
| 140 | #endif | ||
diff --git a/gl/malloca.h b/gl/malloca.h new file mode 100644 index 00000000..0d5ded3c --- /dev/null +++ b/gl/malloca.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* Safe automatic memory allocation. | ||
| 2 | Copyright (C) 2003-2007, 2009-2010 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2003. | ||
| 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, or (at your option) | ||
| 8 | 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, write to the Free Software Foundation, | ||
| 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
| 18 | |||
| 19 | #ifndef _MALLOCA_H | ||
| 20 | #define _MALLOCA_H | ||
| 21 | |||
| 22 | #include <alloca.h> | ||
| 23 | #include <stddef.h> | ||
| 24 | #include <stdlib.h> | ||
| 25 | |||
| 26 | |||
| 27 | #ifdef __cplusplus | ||
| 28 | extern "C" { | ||
| 29 | #endif | ||
| 30 | |||
| 31 | |||
| 32 | /* safe_alloca(N) is equivalent to alloca(N) when it is safe to call | ||
| 33 | alloca(N); otherwise it returns NULL. It either returns N bytes of | ||
| 34 | memory allocated on the stack, that lasts until the function returns, | ||
| 35 | or NULL. | ||
| 36 | Use of safe_alloca should be avoided: | ||
| 37 | - inside arguments of function calls - undefined behaviour, | ||
| 38 | - in inline functions - the allocation may actually last until the | ||
| 39 | calling function returns. | ||
| 40 | */ | ||
| 41 | #if HAVE_ALLOCA | ||
| 42 | /* The OS usually guarantees only one guard page at the bottom of the stack, | ||
| 43 | and a page size can be as small as 4096 bytes. So we cannot safely | ||
| 44 | allocate anything larger than 4096 bytes. Also care for the possibility | ||
| 45 | of a few compiler-allocated temporary stack slots. | ||
| 46 | This must be a macro, not an inline function. */ | ||
| 47 | # define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) | ||
| 48 | #else | ||
| 49 | # define safe_alloca(N) ((void) (N), NULL) | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /* malloca(N) is a safe variant of alloca(N). It allocates N bytes of | ||
| 53 | memory allocated on the stack, that must be freed using freea() before | ||
| 54 | the function returns. Upon failure, it returns NULL. */ | ||
| 55 | #if HAVE_ALLOCA | ||
| 56 | # define malloca(N) \ | ||
| 57 | ((N) < 4032 - sa_increment \ | ||
| 58 | ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ | ||
| 59 | : mmalloca (N)) | ||
| 60 | #else | ||
| 61 | # define malloca(N) \ | ||
| 62 | mmalloca (N) | ||
| 63 | #endif | ||
| 64 | extern void * mmalloca (size_t n); | ||
| 65 | |||
| 66 | /* Free a block of memory allocated through malloca(). */ | ||
| 67 | #if HAVE_ALLOCA | ||
| 68 | extern void freea (void *p); | ||
| 69 | #else | ||
| 70 | # define freea free | ||
| 71 | #endif | ||
| 72 | |||
| 73 | /* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). | ||
| 74 | It allocates an array of N objects, each with S bytes of memory, | ||
| 75 | on the stack. S must be positive and N must be nonnegative. | ||
| 76 | The array must be freed using freea() before the function returns. */ | ||
| 77 | #if 1 | ||
| 78 | /* Cf. the definition of xalloc_oversized. */ | ||
| 79 | # define nmalloca(n, s) \ | ||
| 80 | ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ | ||
| 81 | ? NULL \ | ||
| 82 | : malloca ((n) * (s))) | ||
| 83 | #else | ||
| 84 | extern void * nmalloca (size_t n, size_t s); | ||
| 85 | #endif | ||
| 86 | |||
| 87 | |||
| 88 | #ifdef __cplusplus | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 92 | |||
| 93 | /* ------------------- Auxiliary, non-public definitions ------------------- */ | ||
| 94 | |||
| 95 | /* Determine the alignment of a type at compile time. */ | ||
| 96 | #if defined __GNUC__ | ||
| 97 | # define sa_alignof __alignof__ | ||
| 98 | #elif defined __cplusplus | ||
| 99 | template <class type> struct sa_alignof_helper { char __slot1; type __slot2; }; | ||
| 100 | # define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2) | ||
| 101 | #elif defined __hpux | ||
| 102 | /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof | ||
| 103 | values. */ | ||
| 104 | # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) | ||
| 105 | #elif defined _AIX | ||
| 106 | /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof | ||
| 107 | values. */ | ||
| 108 | # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) | ||
| 109 | #else | ||
| 110 | # define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2) | ||
| 111 | #endif | ||
| 112 | |||
| 113 | enum | ||
| 114 | { | ||
| 115 | /* The desired alignment of memory allocations is the maximum alignment | ||
| 116 | among all elementary types. */ | ||
| 117 | sa_alignment_long = sa_alignof (long), | ||
| 118 | sa_alignment_double = sa_alignof (double), | ||
| 119 | #if HAVE_LONG_LONG_INT | ||
| 120 | sa_alignment_longlong = sa_alignof (long long), | ||
| 121 | #endif | ||
| 122 | sa_alignment_longdouble = sa_alignof (long double), | ||
| 123 | sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) | ||
| 124 | #if HAVE_LONG_LONG_INT | ||
| 125 | | (sa_alignment_longlong - 1) | ||
| 126 | #endif | ||
| 127 | | (sa_alignment_longdouble - 1) | ||
| 128 | ) + 1, | ||
| 129 | /* The increment that guarantees room for a magic word must be >= sizeof (int) | ||
| 130 | and a multiple of sa_alignment_max. */ | ||
| 131 | sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max | ||
| 132 | }; | ||
| 133 | |||
| 134 | #endif /* _MALLOCA_H */ | ||
diff --git a/gl/malloca.valgrind b/gl/malloca.valgrind new file mode 100644 index 00000000..52f0a50f --- /dev/null +++ b/gl/malloca.valgrind | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # Suppress a valgrind message about use of uninitialized memory in freea(). | ||
| 2 | # This use is OK because it provides only a speedup. | ||
| 3 | { | ||
| 4 | freea | ||
| 5 | Memcheck:Cond | ||
| 6 | fun:freea | ||
| 7 | } | ||
diff --git a/gl/setenv.c b/gl/setenv.c new file mode 100644 index 00000000..ba760d6f --- /dev/null +++ b/gl/setenv.c | |||
| @@ -0,0 +1,390 @@ | |||
| 1 | /* Copyright (C) 1992, 1995-2003, 2005-2010 Free Software Foundation, Inc. | ||
| 2 | This file is part of the GNU C Library. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #if !_LIBC | ||
| 18 | # include <config.h> | ||
| 19 | #endif | ||
| 20 | |||
| 21 | /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc | ||
| 22 | optimizes away the name == NULL test below. */ | ||
| 23 | #define _GL_ARG_NONNULL(params) | ||
| 24 | |||
| 25 | #include <alloca.h> | ||
| 26 | |||
| 27 | /* Specification. */ | ||
| 28 | #include <stdlib.h> | ||
| 29 | |||
| 30 | #include <errno.h> | ||
| 31 | #ifndef __set_errno | ||
| 32 | # define __set_errno(ev) ((errno) = (ev)) | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #include <string.h> | ||
| 36 | #if _LIBC || HAVE_UNISTD_H | ||
| 37 | # include <unistd.h> | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #if !_LIBC | ||
| 41 | # include "malloca.h" | ||
| 42 | #endif | ||
| 43 | |||
| 44 | #if _LIBC || !HAVE_SETENV | ||
| 45 | |||
| 46 | #if !_LIBC | ||
| 47 | # define __environ environ | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #if _LIBC | ||
| 51 | /* This lock protects against simultaneous modifications of `environ'. */ | ||
| 52 | # include <bits/libc-lock.h> | ||
| 53 | __libc_lock_define_initialized (static, envlock) | ||
| 54 | # define LOCK __libc_lock_lock (envlock) | ||
| 55 | # define UNLOCK __libc_lock_unlock (envlock) | ||
| 56 | #else | ||
| 57 | # define LOCK | ||
| 58 | # define UNLOCK | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* In the GNU C library we must keep the namespace clean. */ | ||
| 62 | #ifdef _LIBC | ||
| 63 | # define setenv __setenv | ||
| 64 | # define clearenv __clearenv | ||
| 65 | # define tfind __tfind | ||
| 66 | # define tsearch __tsearch | ||
| 67 | #else | ||
| 68 | /* Use the system functions, not the gnulib overrides in this file. */ | ||
| 69 | # undef malloc | ||
| 70 | # undef realloc | ||
| 71 | #endif | ||
| 72 | |||
| 73 | /* In the GNU C library implementation we try to be more clever and | ||
| 74 | allow arbitrarily many changes of the environment given that the used | ||
| 75 | values are from a small set. Outside glibc this will eat up all | ||
| 76 | memory after a while. */ | ||
| 77 | #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ | ||
| 78 | && defined __GNUC__) | ||
| 79 | # define USE_TSEARCH 1 | ||
| 80 | # include <search.h> | ||
| 81 | typedef int (*compar_fn_t) (const void *, const void *); | ||
| 82 | |||
| 83 | /* This is a pointer to the root of the search tree with the known | ||
| 84 | values. */ | ||
| 85 | static void *known_values; | ||
| 86 | |||
| 87 | # define KNOWN_VALUE(Str) \ | ||
| 88 | ({ \ | ||
| 89 | void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \ | ||
| 90 | value != NULL ? *(char **) value : NULL; \ | ||
| 91 | }) | ||
| 92 | # define STORE_VALUE(Str) \ | ||
| 93 | tsearch (Str, &known_values, (compar_fn_t) strcmp) | ||
| 94 | |||
| 95 | #else | ||
| 96 | # undef USE_TSEARCH | ||
| 97 | |||
| 98 | # define KNOWN_VALUE(Str) NULL | ||
| 99 | # define STORE_VALUE(Str) do { } while (0) | ||
| 100 | |||
| 101 | #endif | ||
| 102 | |||
| 103 | |||
| 104 | /* If this variable is not a null pointer we allocated the current | ||
| 105 | environment. */ | ||
| 106 | static char **last_environ; | ||
| 107 | |||
| 108 | |||
| 109 | /* This function is used by `setenv' and `putenv'. The difference between | ||
| 110 | the two functions is that for the former must create a new string which | ||
| 111 | is then placed in the environment, while the argument of `putenv' | ||
| 112 | must be used directly. This is all complicated by the fact that we try | ||
| 113 | to reuse values once generated for a `setenv' call since we can never | ||
| 114 | free the strings. */ | ||
| 115 | int | ||
| 116 | __add_to_environ (const char *name, const char *value, const char *combined, | ||
| 117 | int replace) | ||
| 118 | { | ||
| 119 | char **ep; | ||
| 120 | size_t size; | ||
| 121 | const size_t namelen = strlen (name); | ||
| 122 | const size_t vallen = value != NULL ? strlen (value) + 1 : 0; | ||
| 123 | |||
| 124 | LOCK; | ||
| 125 | |||
| 126 | /* We have to get the pointer now that we have the lock and not earlier | ||
| 127 | since another thread might have created a new environment. */ | ||
| 128 | ep = __environ; | ||
| 129 | |||
| 130 | size = 0; | ||
| 131 | if (ep != NULL) | ||
| 132 | { | ||
| 133 | for (; *ep != NULL; ++ep) | ||
| 134 | if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') | ||
| 135 | break; | ||
| 136 | else | ||
| 137 | ++size; | ||
| 138 | } | ||
| 139 | |||
| 140 | if (ep == NULL || *ep == NULL) | ||
| 141 | { | ||
| 142 | char **new_environ; | ||
| 143 | #ifdef USE_TSEARCH | ||
| 144 | char *new_value; | ||
| 145 | #endif | ||
| 146 | |||
| 147 | /* We allocated this space; we can extend it. */ | ||
| 148 | new_environ = | ||
| 149 | (char **) (last_environ == NULL | ||
| 150 | ? malloc ((size + 2) * sizeof (char *)) | ||
| 151 | : realloc (last_environ, (size + 2) * sizeof (char *))); | ||
| 152 | if (new_environ == NULL) | ||
| 153 | { | ||
| 154 | /* It's easier to set errno to ENOMEM than to rely on the | ||
| 155 | 'malloc-posix' and 'realloc-posix' gnulib modules. */ | ||
| 156 | __set_errno (ENOMEM); | ||
| 157 | UNLOCK; | ||
| 158 | return -1; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* If the whole entry is given add it. */ | ||
| 162 | if (combined != NULL) | ||
| 163 | /* We must not add the string to the search tree since it belongs | ||
| 164 | to the user. */ | ||
| 165 | new_environ[size] = (char *) combined; | ||
| 166 | else | ||
| 167 | { | ||
| 168 | /* See whether the value is already known. */ | ||
| 169 | #ifdef USE_TSEARCH | ||
| 170 | # ifdef _LIBC | ||
| 171 | new_value = (char *) alloca (namelen + 1 + vallen); | ||
| 172 | __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), | ||
| 173 | value, vallen); | ||
| 174 | # else | ||
| 175 | new_value = (char *) malloca (namelen + 1 + vallen); | ||
| 176 | if (new_value == NULL) | ||
| 177 | { | ||
| 178 | __set_errno (ENOMEM); | ||
| 179 | UNLOCK; | ||
| 180 | return -1; | ||
| 181 | } | ||
| 182 | memcpy (new_value, name, namelen); | ||
| 183 | new_value[namelen] = '='; | ||
| 184 | memcpy (&new_value[namelen + 1], value, vallen); | ||
| 185 | # endif | ||
| 186 | |||
| 187 | new_environ[size] = KNOWN_VALUE (new_value); | ||
| 188 | if (new_environ[size] == NULL) | ||
| 189 | #endif | ||
| 190 | { | ||
| 191 | new_environ[size] = (char *) malloc (namelen + 1 + vallen); | ||
| 192 | if (new_environ[size] == NULL) | ||
| 193 | { | ||
| 194 | #if defined USE_TSEARCH && !defined _LIBC | ||
| 195 | freea (new_value); | ||
| 196 | #endif | ||
| 197 | __set_errno (ENOMEM); | ||
| 198 | UNLOCK; | ||
| 199 | return -1; | ||
| 200 | } | ||
| 201 | |||
| 202 | #ifdef USE_TSEARCH | ||
| 203 | memcpy (new_environ[size], new_value, namelen + 1 + vallen); | ||
| 204 | #else | ||
| 205 | memcpy (new_environ[size], name, namelen); | ||
| 206 | new_environ[size][namelen] = '='; | ||
| 207 | memcpy (&new_environ[size][namelen + 1], value, vallen); | ||
| 208 | #endif | ||
| 209 | /* And save the value now. We cannot do this when we remove | ||
| 210 | the string since then we cannot decide whether it is a | ||
| 211 | user string or not. */ | ||
| 212 | STORE_VALUE (new_environ[size]); | ||
| 213 | } | ||
| 214 | #if defined USE_TSEARCH && !defined _LIBC | ||
| 215 | freea (new_value); | ||
| 216 | #endif | ||
| 217 | } | ||
| 218 | |||
| 219 | if (__environ != last_environ) | ||
| 220 | memcpy ((char *) new_environ, (char *) __environ, | ||
| 221 | size * sizeof (char *)); | ||
| 222 | |||
| 223 | new_environ[size + 1] = NULL; | ||
| 224 | |||
| 225 | last_environ = __environ = new_environ; | ||
| 226 | } | ||
| 227 | else if (replace) | ||
| 228 | { | ||
| 229 | char *np; | ||
| 230 | |||
| 231 | /* Use the user string if given. */ | ||
| 232 | if (combined != NULL) | ||
| 233 | np = (char *) combined; | ||
| 234 | else | ||
| 235 | { | ||
| 236 | #ifdef USE_TSEARCH | ||
| 237 | char *new_value; | ||
| 238 | # ifdef _LIBC | ||
| 239 | new_value = alloca (namelen + 1 + vallen); | ||
| 240 | __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), | ||
| 241 | value, vallen); | ||
| 242 | # else | ||
| 243 | new_value = malloca (namelen + 1 + vallen); | ||
| 244 | if (new_value == NULL) | ||
| 245 | { | ||
| 246 | __set_errno (ENOMEM); | ||
| 247 | UNLOCK; | ||
| 248 | return -1; | ||
| 249 | } | ||
| 250 | memcpy (new_value, name, namelen); | ||
| 251 | new_value[namelen] = '='; | ||
| 252 | memcpy (&new_value[namelen + 1], value, vallen); | ||
| 253 | # endif | ||
| 254 | |||
| 255 | np = KNOWN_VALUE (new_value); | ||
| 256 | if (np == NULL) | ||
| 257 | #endif | ||
| 258 | { | ||
| 259 | np = (char *) malloc (namelen + 1 + vallen); | ||
| 260 | if (np == NULL) | ||
| 261 | { | ||
| 262 | #if defined USE_TSEARCH && !defined _LIBC | ||
| 263 | freea (new_value); | ||
| 264 | #endif | ||
| 265 | __set_errno (ENOMEM); | ||
| 266 | UNLOCK; | ||
| 267 | return -1; | ||
| 268 | } | ||
| 269 | |||
| 270 | #ifdef USE_TSEARCH | ||
| 271 | memcpy (np, new_value, namelen + 1 + vallen); | ||
| 272 | #else | ||
| 273 | memcpy (np, name, namelen); | ||
| 274 | np[namelen] = '='; | ||
| 275 | memcpy (&np[namelen + 1], value, vallen); | ||
| 276 | #endif | ||
| 277 | /* And remember the value. */ | ||
| 278 | STORE_VALUE (np); | ||
| 279 | } | ||
| 280 | #if defined USE_TSEARCH && !defined _LIBC | ||
| 281 | freea (new_value); | ||
| 282 | #endif | ||
| 283 | } | ||
| 284 | |||
| 285 | *ep = np; | ||
| 286 | } | ||
| 287 | |||
| 288 | UNLOCK; | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | int | ||
| 294 | setenv (const char *name, const char *value, int replace) | ||
| 295 | { | ||
| 296 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | ||
| 297 | { | ||
| 298 | __set_errno (EINVAL); | ||
| 299 | return -1; | ||
| 300 | } | ||
| 301 | |||
| 302 | return __add_to_environ (name, value, NULL, replace); | ||
| 303 | } | ||
| 304 | |||
| 305 | /* The `clearenv' was planned to be added to POSIX.1 but probably | ||
| 306 | never made it. Nevertheless the POSIX.9 standard (POSIX bindings | ||
| 307 | for Fortran 77) requires this function. */ | ||
| 308 | int | ||
| 309 | clearenv (void) | ||
| 310 | { | ||
| 311 | LOCK; | ||
| 312 | |||
| 313 | if (__environ == last_environ && __environ != NULL) | ||
| 314 | { | ||
| 315 | /* We allocated this environment so we can free it. */ | ||
| 316 | free (__environ); | ||
| 317 | last_environ = NULL; | ||
| 318 | } | ||
| 319 | |||
| 320 | /* Clear the environment pointer removes the whole environment. */ | ||
| 321 | __environ = NULL; | ||
| 322 | |||
| 323 | UNLOCK; | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | #ifdef _LIBC | ||
| 329 | static void | ||
| 330 | free_mem (void) | ||
| 331 | { | ||
| 332 | /* Remove all traces. */ | ||
| 333 | clearenv (); | ||
| 334 | |||
| 335 | /* Now remove the search tree. */ | ||
| 336 | __tdestroy (known_values, free); | ||
| 337 | known_values = NULL; | ||
| 338 | } | ||
| 339 | text_set_element (__libc_subfreeres, free_mem); | ||
| 340 | |||
| 341 | |||
| 342 | # undef setenv | ||
| 343 | # undef clearenv | ||
| 344 | weak_alias (__setenv, setenv) | ||
| 345 | weak_alias (__clearenv, clearenv) | ||
| 346 | #endif | ||
| 347 | |||
| 348 | #endif /* _LIBC || !HAVE_SETENV */ | ||
| 349 | |||
| 350 | /* The rest of this file is called into use when replacing an existing | ||
| 351 | but buggy setenv. Known bugs include failure to diagnose invalid | ||
| 352 | name, and consuming a leading '=' from value. */ | ||
| 353 | #if HAVE_SETENV | ||
| 354 | |||
| 355 | # undef setenv | ||
| 356 | # define STREQ(a, b) (strcmp (a, b) == 0) | ||
| 357 | |||
| 358 | int | ||
| 359 | rpl_setenv (const char *name, const char *value, int replace) | ||
| 360 | { | ||
| 361 | int result; | ||
| 362 | if (!name || !*name || strchr (name, '=')) | ||
| 363 | { | ||
| 364 | errno = EINVAL; | ||
| 365 | return -1; | ||
| 366 | } | ||
| 367 | /* Call the real setenv even if replace is 0, in case implementation | ||
| 368 | has underlying data to update, such as when environ changes. */ | ||
| 369 | result = setenv (name, value, replace); | ||
| 370 | if (result == 0 && replace && *value == '=') | ||
| 371 | { | ||
| 372 | char *tmp = getenv (name); | ||
| 373 | if (!STREQ (tmp, value)) | ||
| 374 | { | ||
| 375 | int saved_errno; | ||
| 376 | size_t len = strlen (value); | ||
| 377 | tmp = malloca (len + 2); | ||
| 378 | /* Since leading '=' is eaten, double it up. */ | ||
| 379 | *tmp = '='; | ||
| 380 | memcpy (tmp + 1, value, len + 1); | ||
| 381 | result = setenv (name, tmp, replace); | ||
| 382 | saved_errno = errno; | ||
| 383 | freea (tmp); | ||
| 384 | errno = saved_errno; | ||
| 385 | } | ||
| 386 | } | ||
| 387 | return result; | ||
| 388 | } | ||
| 389 | |||
| 390 | #endif /* HAVE_SETENV */ | ||
diff --git a/gl/unsetenv.c b/gl/unsetenv.c new file mode 100644 index 00000000..65a19cca --- /dev/null +++ b/gl/unsetenv.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* Copyright (C) 1992, 1995-2002, 2005-2010 Free Software Foundation, Inc. | ||
| 2 | This file is part of the GNU C Library. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 3 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc | ||
| 20 | optimizes away the name == NULL test below. */ | ||
| 21 | #define _GL_ARG_NONNULL(params) | ||
| 22 | |||
| 23 | /* Specification. */ | ||
| 24 | #include <stdlib.h> | ||
| 25 | |||
| 26 | #include <errno.h> | ||
| 27 | #if !_LIBC | ||
| 28 | # define __set_errno(ev) ((errno) = (ev)) | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include <string.h> | ||
| 32 | #include <unistd.h> | ||
| 33 | |||
| 34 | #if !_LIBC | ||
| 35 | # define __environ environ | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #if _LIBC | ||
| 39 | /* This lock protects against simultaneous modifications of `environ'. */ | ||
| 40 | # include <bits/libc-lock.h> | ||
| 41 | __libc_lock_define_initialized (static, envlock) | ||
| 42 | # define LOCK __libc_lock_lock (envlock) | ||
| 43 | # define UNLOCK __libc_lock_unlock (envlock) | ||
| 44 | #else | ||
| 45 | # define LOCK | ||
| 46 | # define UNLOCK | ||
| 47 | #endif | ||
| 48 | |||
| 49 | /* In the GNU C library we must keep the namespace clean. */ | ||
| 50 | #ifdef _LIBC | ||
| 51 | # define unsetenv __unsetenv | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #if _LIBC || !HAVE_UNSETENV | ||
| 55 | |||
| 56 | int | ||
| 57 | unsetenv (const char *name) | ||
| 58 | { | ||
| 59 | size_t len; | ||
| 60 | char **ep; | ||
| 61 | |||
| 62 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | ||
| 63 | { | ||
| 64 | __set_errno (EINVAL); | ||
| 65 | return -1; | ||
| 66 | } | ||
| 67 | |||
| 68 | len = strlen (name); | ||
| 69 | |||
| 70 | LOCK; | ||
| 71 | |||
| 72 | ep = __environ; | ||
| 73 | while (*ep != NULL) | ||
| 74 | if (!strncmp (*ep, name, len) && (*ep)[len] == '=') | ||
| 75 | { | ||
| 76 | /* Found it. Remove this pointer by moving later ones back. */ | ||
| 77 | char **dp = ep; | ||
| 78 | |||
| 79 | do | ||
| 80 | dp[0] = dp[1]; | ||
| 81 | while (*dp++); | ||
| 82 | /* Continue the loop in case NAME appears again. */ | ||
| 83 | } | ||
| 84 | else | ||
| 85 | ++ep; | ||
| 86 | |||
| 87 | UNLOCK; | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | #ifdef _LIBC | ||
| 93 | # undef unsetenv | ||
| 94 | weak_alias (__unsetenv, unsetenv) | ||
| 95 | #endif | ||
| 96 | |||
| 97 | #else /* HAVE_UNSETENV */ | ||
| 98 | |||
| 99 | # undef unsetenv | ||
| 100 | |||
| 101 | /* Call the underlying unsetenv, in case there is hidden bookkeeping | ||
| 102 | that needs updating beyond just modifying environ. */ | ||
| 103 | int | ||
| 104 | rpl_unsetenv (const char *name) | ||
| 105 | { | ||
| 106 | int result = 0; | ||
| 107 | if (!name || !*name || strchr (name, '=')) | ||
| 108 | { | ||
| 109 | errno = EINVAL; | ||
| 110 | return -1; | ||
| 111 | } | ||
| 112 | while (getenv (name)) | ||
| 113 | # if !VOID_UNSETENV | ||
| 114 | result = | ||
| 115 | # endif | ||
| 116 | unsetenv (name); | ||
| 117 | return result; | ||
| 118 | } | ||
| 119 | |||
| 120 | #endif /* HAVE_UNSETENV */ | ||
