1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3f08c3bdfSopenharmony_ci * 4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it 5f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as 6f08c3bdfSopenharmony_ci * published by the Free Software Foundation. 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but 9f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it is 13f08c3bdfSopenharmony_ci * free of the rightful claim of any third person regarding infringement 14f08c3bdfSopenharmony_ci * or the like. Any license provided herein, whether implied or 15f08c3bdfSopenharmony_ci * otherwise, applies only to this software file. Patent licenses, if 16f08c3bdfSopenharmony_ci * any, provided herein do not apply to combinations of this program with 17f08c3bdfSopenharmony_ci * other software, or any other product whatsoever. 18f08c3bdfSopenharmony_ci * 19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along 20f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc., 21f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24f08c3bdfSopenharmony_ci * Mountain View, CA 94043, or: 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * http://www.sgi.com 27f08c3bdfSopenharmony_ci * 28f08c3bdfSopenharmony_ci * For further information regarding this notice, see: 29f08c3bdfSopenharmony_ci * 30f08c3bdfSopenharmony_ci * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31f08c3bdfSopenharmony_ci * 32f08c3bdfSopenharmony_ci * 33f08c3bdfSopenharmony_ci * OS Test - Silicon Graphics, Inc. 34f08c3bdfSopenharmony_ci * TEST IDENTIFIER : fork04 35f08c3bdfSopenharmony_ci * TEST TITLE : Child inheritance of Environment Variables after fork() 36f08c3bdfSopenharmony_ci * PARENT DOCUMENT : frktds01 37f08c3bdfSopenharmony_ci * TEST CASE TOTAL : 3 38f08c3bdfSopenharmony_ci * WALL CLOCK TIME : 1 39f08c3bdfSopenharmony_ci * CPU TYPES : ALL 40f08c3bdfSopenharmony_ci * AUTHOR : Kathy Olmsted 41f08c3bdfSopenharmony_ci * CO-PILOT : Steve Shaw 42f08c3bdfSopenharmony_ci * DATE STARTED : 06/17/92 43f08c3bdfSopenharmony_ci * INITIAL RELEASE : UNICOS 7.0 44f08c3bdfSopenharmony_ci * 45f08c3bdfSopenharmony_ci * TEST CASES 46f08c3bdfSopenharmony_ci * Test these environment variables correctly inherited by child: 47f08c3bdfSopenharmony_ci * 1. TERM 48f08c3bdfSopenharmony_ci * 2. NoTSetzWq 49f08c3bdfSopenharmony_ci * 3. TESTPROG 50f08c3bdfSopenharmony_ci * 51f08c3bdfSopenharmony_ci * INPUT SPECIFICATIONS 52f08c3bdfSopenharmony_ci * The standard options for system call tests are accepted. 53f08c3bdfSopenharmony_ci * (See the parse_opts(3) man page). 54f08c3bdfSopenharmony_ci * 55f08c3bdfSopenharmony_ci * DURATION 56f08c3bdfSopenharmony_ci * Terminates - with frequency and infinite modes. 57f08c3bdfSopenharmony_ci * 58f08c3bdfSopenharmony_ci * SIGNALS 59f08c3bdfSopenharmony_ci * Uses SIGUSR1 to pause before test if option set. 60f08c3bdfSopenharmony_ci * (See the parse_opts(3) man page). 61f08c3bdfSopenharmony_ci * 62f08c3bdfSopenharmony_ci * ENVIRONMENTAL NEEDS 63f08c3bdfSopenharmony_ci * No run-time environmental needs. 64f08c3bdfSopenharmony_ci * 65f08c3bdfSopenharmony_ci * DETAILED DESCRIPTION 66f08c3bdfSopenharmony_ci * 67f08c3bdfSopenharmony_ci * Setup: 68f08c3bdfSopenharmony_ci * Setup signal handling. 69f08c3bdfSopenharmony_ci * Make and change to a temporary directory. 70f08c3bdfSopenharmony_ci * Pause for SIGUSR1 if option specified. 71f08c3bdfSopenharmony_ci * Add TESTPROG variable to the environment 72f08c3bdfSopenharmony_ci * 73f08c3bdfSopenharmony_ci * Test: 74f08c3bdfSopenharmony_ci * Loop if the proper options are given. 75f08c3bdfSopenharmony_ci * fork() 76f08c3bdfSopenharmony_ci * Check return code, if system call failed (return=-1) 77f08c3bdfSopenharmony_ci * Log the errno 78f08c3bdfSopenharmony_ci * CHILD: 79f08c3bdfSopenharmony_ci * open a temp file 80f08c3bdfSopenharmony_ci * Determine environment values and write to file 81f08c3bdfSopenharmony_ci * close file containing test values. 82f08c3bdfSopenharmony_ci * exit. 83f08c3bdfSopenharmony_ci * PARENT: 84f08c3bdfSopenharmony_ci * Wait for child to exit. 85f08c3bdfSopenharmony_ci * Verify exit status 86f08c3bdfSopenharmony_ci * Open file containing test values. 87f08c3bdfSopenharmony_ci * For each test case: 88f08c3bdfSopenharmony_ci * Read the value from the file. 89f08c3bdfSopenharmony_ci * Determine and report PASS/FAIL result. 90f08c3bdfSopenharmony_ci * 91f08c3bdfSopenharmony_ci * Cleanup: 92f08c3bdfSopenharmony_ci * Print errno log and/or timing stats if options given 93f08c3bdfSopenharmony_ci * Remove the temporary directory and exit. 94f08c3bdfSopenharmony_ci */ 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci#include <stdlib.h> 97f08c3bdfSopenharmony_ci#include <sys/types.h> 98f08c3bdfSopenharmony_ci#include <sys/wait.h> 99f08c3bdfSopenharmony_ci#include <unistd.h> 100f08c3bdfSopenharmony_ci#include <fcntl.h> 101f08c3bdfSopenharmony_ci#include <string.h> 102f08c3bdfSopenharmony_ci#include <sys/param.h> 103f08c3bdfSopenharmony_ci#include <signal.h> 104f08c3bdfSopenharmony_ci#include <errno.h> 105f08c3bdfSopenharmony_ci#include "test.h" 106f08c3bdfSopenharmony_ci#include "safe_macros.h" 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_cichar *TCID = "fork04"; 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci#define KIDEXIT 42 111f08c3bdfSopenharmony_ci#define MAX_LINE_LENGTH 256 112f08c3bdfSopenharmony_ci#define OUTPUT_FILE "env.out" 113f08c3bdfSopenharmony_ci#define ENV_NOT_SET "getenv() does not find variable set" 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci/* list of environment variables to test */ 116f08c3bdfSopenharmony_cichar *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" }; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci#define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *)) 119f08c3bdfSopenharmony_ciint TST_TOTAL = NUMBER_OF_ENVIRON; 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_cistatic void cleanup(void) 122f08c3bdfSopenharmony_ci{ 123f08c3bdfSopenharmony_ci tst_rmdir(); 124f08c3bdfSopenharmony_ci} 125f08c3bdfSopenharmony_ci 126f08c3bdfSopenharmony_cistatic void setup(void) 127f08c3bdfSopenharmony_ci{ 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci tst_sig(FORK, DEF_HANDLER, cleanup); 130f08c3bdfSopenharmony_ci TEST_PAUSE; 131f08c3bdfSopenharmony_ci tst_tmpdir(); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci /* add a variable to the environment */ 134f08c3bdfSopenharmony_ci putenv("TESTPROG=FRKTCS04"); 135f08c3bdfSopenharmony_ci} 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_cistatic void child_environment(void) 138f08c3bdfSopenharmony_ci{ 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_ci int fildes; 141f08c3bdfSopenharmony_ci int index; 142f08c3bdfSopenharmony_ci char msg[MAX_LINE_LENGTH]; 143f08c3bdfSopenharmony_ci char *var; 144f08c3bdfSopenharmony_ci 145f08c3bdfSopenharmony_ci fildes = creat(OUTPUT_FILE, 0700); 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci for (index = 0; index < (int)NUMBER_OF_ENVIRON; index++) { 148f08c3bdfSopenharmony_ci memset(msg, 0, MAX_LINE_LENGTH); 149f08c3bdfSopenharmony_ci 150f08c3bdfSopenharmony_ci var = getenv(environ_list[index]); 151f08c3bdfSopenharmony_ci if (var == NULL) 152f08c3bdfSopenharmony_ci (void)sprintf(msg, "%s:%s", environ_list[index], 153f08c3bdfSopenharmony_ci ENV_NOT_SET); 154f08c3bdfSopenharmony_ci else 155f08c3bdfSopenharmony_ci (void)sprintf(msg, "%s:%s", environ_list[index], var); 156f08c3bdfSopenharmony_ci /* includes extra null chars */ 157f08c3bdfSopenharmony_ci write(fildes, msg, sizeof(msg)); 158f08c3bdfSopenharmony_ci } 159f08c3bdfSopenharmony_ci 160f08c3bdfSopenharmony_ci close(fildes); 161f08c3bdfSopenharmony_ci} 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci/* 164f08c3bdfSopenharmony_ci * Compare parent env string to child's string. 165f08c3bdfSopenharmony_ci * Each string is in the format: <env var>:<value> 166f08c3bdfSopenharmony_ci */ 167f08c3bdfSopenharmony_cistatic int cmp_env_strings(char *pstring, char *cstring) 168f08c3bdfSopenharmony_ci{ 169f08c3bdfSopenharmony_ci char *penv, *cenv, *pvalue, *cvalue; 170f08c3bdfSopenharmony_ci 171f08c3bdfSopenharmony_ci /* 172f08c3bdfSopenharmony_ci * Break pstring into env and value 173f08c3bdfSopenharmony_ci */ 174f08c3bdfSopenharmony_ci penv = pstring; 175f08c3bdfSopenharmony_ci pvalue = strchr(pstring, ':'); 176f08c3bdfSopenharmony_ci if (pvalue == NULL) { 177f08c3bdfSopenharmony_ci tst_resm(TBROK, 178f08c3bdfSopenharmony_ci "internal error - parent's env string not in correct format:'%s'", 179f08c3bdfSopenharmony_ci pstring); 180f08c3bdfSopenharmony_ci return -1; 181f08c3bdfSopenharmony_ci } else { 182f08c3bdfSopenharmony_ci *pvalue = '\0'; 183f08c3bdfSopenharmony_ci pvalue++; 184f08c3bdfSopenharmony_ci if (*pvalue == '\0') { 185f08c3bdfSopenharmony_ci tst_resm(TBROK, 186f08c3bdfSopenharmony_ci "internal error - missing parent's env value"); 187f08c3bdfSopenharmony_ci return -1; 188f08c3bdfSopenharmony_ci } 189f08c3bdfSopenharmony_ci } 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci /* 192f08c3bdfSopenharmony_ci * Break cstring into env and value 193f08c3bdfSopenharmony_ci */ 194f08c3bdfSopenharmony_ci cenv = cstring; 195f08c3bdfSopenharmony_ci cvalue = strchr(cstring, ':'); 196f08c3bdfSopenharmony_ci if (cvalue == NULL) { 197f08c3bdfSopenharmony_ci tst_resm(TBROK, 198f08c3bdfSopenharmony_ci "internal error - parent's env string not in correct format:'%s'", 199f08c3bdfSopenharmony_ci cstring); 200f08c3bdfSopenharmony_ci return -1; 201f08c3bdfSopenharmony_ci } else { 202f08c3bdfSopenharmony_ci *cvalue = '\0'; 203f08c3bdfSopenharmony_ci cvalue++; 204f08c3bdfSopenharmony_ci if (*cvalue == '\0') { 205f08c3bdfSopenharmony_ci tst_resm(TBROK, 206f08c3bdfSopenharmony_ci "internal error - missing child's env value"); 207f08c3bdfSopenharmony_ci return -1; 208f08c3bdfSopenharmony_ci } 209f08c3bdfSopenharmony_ci } 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci if (strcmp(penv, cenv) != 0) { 212f08c3bdfSopenharmony_ci tst_resm(TBROK, "internal error - parent(%s) != child (%s) env", 213f08c3bdfSopenharmony_ci penv, cenv); 214f08c3bdfSopenharmony_ci return -1; 215f08c3bdfSopenharmony_ci } 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci if (strcmp(pvalue, cvalue) != 0) { 218f08c3bdfSopenharmony_ci tst_resm(TFAIL, 219f08c3bdfSopenharmony_ci "Env var %s changed after fork(), parent's %s, child's %s", 220f08c3bdfSopenharmony_ci penv, pvalue, cvalue); 221f08c3bdfSopenharmony_ci } else { 222f08c3bdfSopenharmony_ci tst_resm(TPASS, "Env var %s unchanged after fork(): %s", 223f08c3bdfSopenharmony_ci penv, cvalue); 224f08c3bdfSopenharmony_ci } 225f08c3bdfSopenharmony_ci return 0; 226f08c3bdfSopenharmony_ci 227f08c3bdfSopenharmony_ci} 228f08c3bdfSopenharmony_ci 229f08c3bdfSopenharmony_ci/*************************************************************** 230f08c3bdfSopenharmony_ci * parent_environment - the parent side of the environment tests 231f08c3bdfSopenharmony_ci * determine values for the variables 232f08c3bdfSopenharmony_ci * read the values determined by the child 233f08c3bdfSopenharmony_ci * compare values 234f08c3bdfSopenharmony_ci ***************************************************************/ 235f08c3bdfSopenharmony_civoid parent_environment(void) 236f08c3bdfSopenharmony_ci{ 237f08c3bdfSopenharmony_ci 238f08c3bdfSopenharmony_ci int fildes; 239f08c3bdfSopenharmony_ci char tmp_line[MAX_LINE_LENGTH]; 240f08c3bdfSopenharmony_ci char parent_value[MAX_LINE_LENGTH]; 241f08c3bdfSopenharmony_ci unsigned int index; 242f08c3bdfSopenharmony_ci int ret; 243f08c3bdfSopenharmony_ci char *var; 244f08c3bdfSopenharmony_ci 245f08c3bdfSopenharmony_ci fildes = SAFE_OPEN(cleanup, OUTPUT_FILE, O_RDWR); 246f08c3bdfSopenharmony_ci for (index = 0; index < NUMBER_OF_ENVIRON; index++) { 247f08c3bdfSopenharmony_ci ret = read(fildes, tmp_line, MAX_LINE_LENGTH); 248f08c3bdfSopenharmony_ci if (ret == 0) { 249f08c3bdfSopenharmony_ci tst_resm(TBROK, 250f08c3bdfSopenharmony_ci "fork() test. parent_environment: failed to read from file with %d (%s)", 251f08c3bdfSopenharmony_ci errno, strerror(errno)); 252f08c3bdfSopenharmony_ci } else { 253f08c3bdfSopenharmony_ci 254f08c3bdfSopenharmony_ci var = getenv(environ_list[index]); 255f08c3bdfSopenharmony_ci if (var == NULL) 256f08c3bdfSopenharmony_ci sprintf(parent_value, "%s:%s", 257f08c3bdfSopenharmony_ci environ_list[index], ENV_NOT_SET); 258f08c3bdfSopenharmony_ci else 259f08c3bdfSopenharmony_ci sprintf(parent_value, "%s:%s", 260f08c3bdfSopenharmony_ci environ_list[index], var); 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci cmp_env_strings(parent_value, tmp_line); 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci } 265f08c3bdfSopenharmony_ci } 266f08c3bdfSopenharmony_ci 267f08c3bdfSopenharmony_ci close(fildes); 268f08c3bdfSopenharmony_ci} 269f08c3bdfSopenharmony_ci 270f08c3bdfSopenharmony_ciint main(int ac, char **av) 271f08c3bdfSopenharmony_ci{ 272f08c3bdfSopenharmony_ci int lc; 273f08c3bdfSopenharmony_ci int kid_status; 274f08c3bdfSopenharmony_ci int wait_status; 275f08c3bdfSopenharmony_ci int fails; 276f08c3bdfSopenharmony_ci 277f08c3bdfSopenharmony_ci tst_parse_opts(ac, av, NULL, NULL); 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_ci setup(); 280f08c3bdfSopenharmony_ci 281f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 282f08c3bdfSopenharmony_ci tst_count = 0; 283f08c3bdfSopenharmony_ci fails = 0; 284f08c3bdfSopenharmony_ci 285f08c3bdfSopenharmony_ci TEST(fork()); 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci if (TEST_RETURN == -1) { 288f08c3bdfSopenharmony_ci /* fork failed */ 289f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, 290f08c3bdfSopenharmony_ci "fork() failed with %d (%s)", 291f08c3bdfSopenharmony_ci TEST_ERRNO, strerror(TEST_ERRNO)); 292f08c3bdfSopenharmony_ci } else if (TEST_RETURN == 0) { 293f08c3bdfSopenharmony_ci /* child */ 294f08c3bdfSopenharmony_ci /* determine environment variables */ 295f08c3bdfSopenharmony_ci child_environment(); 296f08c3bdfSopenharmony_ci /* exit with known value */ 297f08c3bdfSopenharmony_ci exit(KIDEXIT); 298f08c3bdfSopenharmony_ci } else { 299f08c3bdfSopenharmony_ci /* parent of successful fork */ 300f08c3bdfSopenharmony_ci /* wait for the child to complete */ 301f08c3bdfSopenharmony_ci wait_status = waitpid(TEST_RETURN, &kid_status, 0); 302f08c3bdfSopenharmony_ci /* validate the child exit status */ 303f08c3bdfSopenharmony_ci if (wait_status == TEST_RETURN) { 304f08c3bdfSopenharmony_ci if (kid_status != KIDEXIT << 8) { 305f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 306f08c3bdfSopenharmony_ci "fork(): Incorrect child status returned on wait(): %d", 307f08c3bdfSopenharmony_ci kid_status); 308f08c3bdfSopenharmony_ci fails++; 309f08c3bdfSopenharmony_ci } 310f08c3bdfSopenharmony_ci } else { 311f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, 312f08c3bdfSopenharmony_ci "fork(): wait() for child status failed with %d errno: %d : %s", 313f08c3bdfSopenharmony_ci wait_status, errno, 314f08c3bdfSopenharmony_ci strerror(errno)); 315f08c3bdfSopenharmony_ci fails++; 316f08c3bdfSopenharmony_ci } 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci if (fails == 0) { 319f08c3bdfSopenharmony_ci /* verification tests */ 320f08c3bdfSopenharmony_ci parent_environment(); 321f08c3bdfSopenharmony_ci } 322f08c3bdfSopenharmony_ci } 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ci } 325f08c3bdfSopenharmony_ci 326f08c3bdfSopenharmony_ci cleanup(); 327f08c3bdfSopenharmony_ci tst_exit(); 328f08c3bdfSopenharmony_ci} 329