tst-environ.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* Copyright (C) 1999-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <errno.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <libc-diag.h>
  19. #define VAR "FOOBAR"
  20. char putenv_val[100] = VAR "=some longer value";
  21. static int
  22. do_test (void)
  23. {
  24. int result = 0;
  25. const char *valp;
  26. /* First test: remove entry FOOBAR, whether it exists or not. */
  27. unsetenv (VAR);
  28. /* Now getting the value should fail. */
  29. if (getenv (VAR) != NULL)
  30. {
  31. printf ("There should be no `%s' value\n", VAR);
  32. result = 1;
  33. }
  34. /* Now add a value, with the replace flag cleared. */
  35. if (setenv (VAR, "one", 0) != 0)
  36. {
  37. printf ("setenv #1 failed: %m\n");
  38. result = 1;
  39. }
  40. /* Getting this value should now be possible. */
  41. valp = getenv (VAR);
  42. if (valp == NULL || strcmp (valp, "one") != 0)
  43. {
  44. puts ("getenv #2 failed");
  45. result = 1;
  46. }
  47. /* Try to replace without the replace flag set. This should fail. */
  48. if (setenv (VAR, "two", 0) != 0)
  49. {
  50. printf ("setenv #2 failed: %m\n");
  51. result = 1;
  52. }
  53. /* The value shouldn't have changed. */
  54. valp = getenv (VAR);
  55. if (valp == NULL || strcmp (valp, "one") != 0)
  56. {
  57. puts ("getenv #3 failed");
  58. result = 1;
  59. }
  60. /* Now replace the value using putenv. */
  61. if (putenv (putenv_val) != 0)
  62. {
  63. printf ("putenv #1 failed: %m\n");
  64. result = 1;
  65. }
  66. /* The value should have changed now. */
  67. valp = getenv (VAR);
  68. if (valp == NULL || strcmp (valp, "some longer value") != 0)
  69. {
  70. printf ("getenv #4 failed (is \"%s\")\n", valp);
  71. result = 1;
  72. }
  73. /* Now one tricky check: changing the variable passed in putenv should
  74. change the environment. */
  75. strcpy (&putenv_val[sizeof VAR], "a short one");
  76. /* The value should have changed again. */
  77. valp = getenv (VAR);
  78. if (valp == NULL || strcmp (valp, "a short one") != 0)
  79. {
  80. puts ("getenv #5 failed");
  81. result = 1;
  82. }
  83. /* It should even be possible to rename the variable. */
  84. strcpy (putenv_val, "XYZZY=some other value");
  85. /* Now a lookup using the old name should fail. */
  86. if (getenv (VAR) != NULL)
  87. {
  88. puts ("getenv #6 failed");
  89. result = 1;
  90. }
  91. /* But using the new name it should work. */
  92. valp = getenv ("XYZZY");
  93. if (valp == NULL || strcmp (valp, "some other value") != 0)
  94. {
  95. puts ("getenv #7 failed");
  96. result = 1;
  97. }
  98. /* Create a new variable with the old name. */
  99. if (setenv (VAR, "a new value", 0) != 0)
  100. {
  101. printf ("setenv #3 failed: %m\n");
  102. result = 1;
  103. }
  104. /* At this point a getenv call must return the new value. */
  105. valp = getenv (VAR);
  106. if (valp == NULL || strcmp (valp, "a new value") != 0)
  107. {
  108. puts ("getenv #8 failed");
  109. result = 1;
  110. }
  111. /* Black magic: rename the variable we added using putenv back. */
  112. strcpy (putenv_val, VAR "=old name new value");
  113. /* This is interesting. We have two variables with the same name.
  114. Getting a value should return one of them. */
  115. valp = getenv (VAR);
  116. if (valp == NULL
  117. || (strcmp (valp, "a new value") != 0
  118. && strcmp (valp, "old name new value") != 0))
  119. {
  120. puts ("getenv #9 failed");
  121. result = 1;
  122. }
  123. /* More fun ahead: we are now removing the variable. This should remove
  124. both values. The cast is ok: this call should never put the string
  125. in the environment and it should never modify it. */
  126. putenv ((char *) VAR);
  127. /* Getting the value should now fail. */
  128. if (getenv (VAR) != NULL)
  129. {
  130. printf ("getenv #10 failed (\"%s\" found)\n", getenv (VAR));
  131. result = 1;
  132. }
  133. /* Now a test with an environment variable that's one character long.
  134. This is to test a special case in the getenv implementation. */
  135. strcpy (putenv_val, "X=one character test");
  136. if (putenv (putenv_val) != 0)
  137. {
  138. printf ("putenv #2 failed: %m\n");
  139. result = 1;
  140. }
  141. valp = getenv ("X");
  142. if (valp == NULL || strcmp (valp, "one character test") != 0)
  143. {
  144. puts ("getenv #11 failed");
  145. result = 1;
  146. }
  147. /* Both setenv and unsetenv should return -1/EINVAL for NULL or "" name
  148. or if name contains '=' character. */
  149. errno = 0;
  150. if (setenv (NULL, "val", 1) >= 0 || errno != EINVAL)
  151. {
  152. puts ("setenv #4 failed");
  153. result = 1;
  154. }
  155. errno = 0;
  156. if (setenv ("", "val", 0) >= 0 || errno != EINVAL)
  157. {
  158. puts ("setenv #5 failed");
  159. result = 1;
  160. }
  161. errno = 0;
  162. if (setenv ("var=val", "val", 1) >= 0 || errno != EINVAL)
  163. {
  164. puts ("setenv #6 failed");
  165. result = 1;
  166. }
  167. /* This deliberately tests supplying a null pointer to a function whose
  168. argument is marked __attribute__ ((nonnull)). */
  169. DIAG_PUSH_NEEDS_COMMENT;
  170. DIAG_IGNORE_NEEDS_COMMENT(5, "-Wnonnull");
  171. errno = 0;
  172. if (unsetenv (NULL) >= 0 || errno != EINVAL)
  173. {
  174. puts ("unsetenv #1 failed");
  175. result = 1;
  176. }
  177. DIAG_POP_NEEDS_COMMENT;
  178. errno = 0;
  179. if (unsetenv ("") >= 0 || errno != EINVAL)
  180. {
  181. puts ("unsetenv #2 failed");
  182. result = 1;
  183. }
  184. errno = 0;
  185. if (unsetenv ("x=y") >= 0 || errno != EINVAL)
  186. {
  187. puts ("unsetenv #3 failed");
  188. result = 1;
  189. }
  190. return result;
  191. }
  192. #define TEST_FUNCTION do_test ()
  193. #include "../test-skeleton.c"