1 /* $NetBSD: t_getenv.c,v 1.3 2015/02/27 08:55:35 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __RCSID("$NetBSD: t_getenv.c,v 1.3 2015/02/27 08:55:35 martin Exp $"); 37 38 #include <atf-c.h> 39 #include <errno.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 extern char **environ; 45 46 ATF_TC(clearenv_basic); 47 ATF_TC_HEAD(clearenv_basic, tc) 48 { 49 atf_tc_set_md_var(tc, "descr", 50 "Test user clearing environment directly"); 51 } 52 53 ATF_TC_BODY(clearenv_basic, tc) 54 { 55 char name[1024], value[1024]; 56 57 for (size_t i = 0; i < 1024; i++) { 58 snprintf(name, sizeof(name), "crap%zu", i); 59 snprintf(value, sizeof(value), "%zu", i); 60 ATF_CHECK(setenv(name, value, 1) != -1); 61 } 62 63 *environ = NULL; 64 65 for (size_t i = 0; i < 1; i++) { 66 snprintf(name, sizeof(name), "crap%zu", i); 67 snprintf(value, sizeof(value), "%zu", i); 68 ATF_CHECK(setenv(name, value, 1) != -1); 69 } 70 71 ATF_CHECK_STREQ(getenv("crap0"), "0"); 72 ATF_CHECK(getenv("crap1") == NULL); 73 ATF_CHECK(getenv("crap2") == NULL); 74 } 75 76 ATF_TC(getenv_basic); 77 ATF_TC_HEAD(getenv_basic, tc) 78 { 79 atf_tc_set_md_var(tc, "descr", 80 "Test setenv(3), getenv(3)"); 81 } 82 83 ATF_TC_BODY(getenv_basic, tc) 84 { 85 ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1); 86 ATF_CHECK_STREQ(getenv("EVIL"), "very=bad"); 87 ATF_CHECK(getenv("EVIL=very") == NULL); 88 ATF_CHECK(unsetenv("EVIL") != -1); 89 } 90 91 ATF_TC(putenv_basic); 92 ATF_TC_HEAD(putenv_basic, tc) 93 { 94 atf_tc_set_md_var(tc, "descr", 95 "Test putenv(3), getenv(3), unsetenv(3)"); 96 } 97 98 99 ATF_TC_BODY(putenv_basic, tc) 100 { 101 char string[1024]; 102 103 snprintf(string, sizeof(string), "crap=true"); 104 ATF_CHECK(putenv(string) != -1); 105 ATF_CHECK_STREQ(getenv("crap"), "true"); 106 string[1] = 'l'; 107 ATF_CHECK_STREQ(getenv("clap"), "true"); 108 ATF_CHECK(getenv("crap") == NULL); 109 string[1] = 'r'; 110 ATF_CHECK(unsetenv("crap") != -1); 111 ATF_CHECK(getenv("crap") == NULL); 112 113 ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1); 114 ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1); 115 ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1); 116 } 117 118 ATF_TC(setenv_basic); 119 ATF_TC_HEAD(setenv_basic, tc) 120 { 121 atf_tc_set_md_var(tc, "descr", 122 "Test setenv(3), getenv(3), unsetenv(3)"); 123 atf_tc_set_md_var(tc, "timeout", "600"); 124 } 125 126 ATF_TC_BODY(setenv_basic, tc) 127 { 128 const size_t numvars = 8192; 129 size_t i, offset; 130 char name[1024]; 131 char value[1024]; 132 133 offset = lrand48(); 134 for (i = 0; i < numvars; i++) { 135 (void)snprintf(name, sizeof(name), "var%zu", 136 (i * 7 + offset) % numvars); 137 (void)snprintf(value, sizeof(value), "value%ld", lrand48()); 138 ATF_CHECK(setenv(name, value, 1) != -1); 139 ATF_CHECK(setenv(name, "foo", 0) != -1); 140 ATF_CHECK_STREQ(getenv(name), value); 141 } 142 143 offset = lrand48(); 144 for (i = 0; i < numvars; i++) { 145 (void)snprintf(name, sizeof(name), "var%zu", 146 (i * 11 + offset) % numvars); 147 ATF_CHECK(unsetenv(name) != -1); 148 ATF_CHECK(getenv(name) == NULL); 149 ATF_CHECK(unsetenv(name) != -1); 150 } 151 152 ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); 153 ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); 154 ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); 155 ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1); 156 157 ATF_CHECK(setenv("var", "=val", 1) == 0); 158 ATF_CHECK_STREQ(getenv("var"), "=val"); 159 } 160 161 ATF_TC(setenv_mixed); 162 ATF_TC_HEAD(setenv_mixed, tc) 163 { 164 atf_tc_set_md_var(tc, "descr", 165 "Test mixing setenv(3), unsetenv(3) and putenv(3)"); 166 } 167 168 ATF_TC_BODY(setenv_mixed, tc) 169 { 170 char string[32]; 171 172 (void)strcpy(string, "mixedcrap=putenv"); 173 174 ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); 175 ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); 176 ATF_CHECK(putenv(string) != -1); 177 ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); 178 ATF_CHECK(unsetenv("mixedcrap") != -1); 179 ATF_CHECK(getenv("mixedcrap") == NULL); 180 181 ATF_CHECK(putenv(string) != -1); 182 ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); 183 ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); 184 ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); 185 ATF_CHECK(unsetenv("mixedcrap") != -1); 186 ATF_CHECK(getenv("mixedcrap") == NULL); 187 } 188 189 ATF_TP_ADD_TCS(tp) 190 { 191 192 ATF_TP_ADD_TC(tp, clearenv_basic); 193 ATF_TP_ADD_TC(tp, getenv_basic); 194 ATF_TP_ADD_TC(tp, putenv_basic); 195 ATF_TP_ADD_TC(tp, setenv_basic); 196 ATF_TP_ADD_TC(tp, setenv_mixed); 197 198 return atf_no_error(); 199 } 200