root/opal/util/opal_environ.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_environ_merge
  2. opal_setenv
  3. opal_unsetenv
  4. opal_tmp_directory
  5. opal_home_directory

   1 /*
   2  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2006-2015 Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2007-2013 Los Alamos National Security, LLC.  All rights
  14  *                         reserved.
  15  * Copyright (c) 2014      Intel, Inc. All rights reserved.
  16  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #include "opal_config.h"
  25 
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 #include <string.h>
  29 
  30 #include "opal/util/printf.h"
  31 #include "opal/util/argv.h"
  32 #include "opal/util/opal_environ.h"
  33 #include "opal/constants.h"
  34 
  35 #define OPAL_DEFAULT_TMPDIR "/tmp"
  36 
  37 /*
  38  * Merge two environ-like char arrays, ensuring that there are no
  39  * duplicate entires
  40  */
  41 char **opal_environ_merge(char **minor, char **major)
  42 {
  43     int i;
  44     char **ret = NULL;
  45     char *name, *value;
  46 
  47     /* Check for bozo cases */
  48 
  49     if (NULL == major) {
  50         if (NULL == minor) {
  51             return NULL;
  52         } else {
  53             return opal_argv_copy(minor);
  54         }
  55     }
  56 
  57     /* First, copy major */
  58 
  59     ret = opal_argv_copy(major);
  60 
  61     /* Do we have something in minor? */
  62 
  63     if (NULL == minor) {
  64         return ret;
  65     }
  66 
  67     /* Now go through minor and call opal_setenv(), but with overwrite
  68        as false */
  69 
  70     for (i = 0; NULL != minor[i]; ++i) {
  71         value = strchr(minor[i], '=');
  72         if (NULL == value) {
  73             opal_setenv(minor[i], NULL, false, &ret);
  74         } else {
  75 
  76             /* strdup minor[i] in case it's a constat string */
  77 
  78             name = strdup(minor[i]);
  79             value = name + (value - minor[i]);
  80             *value = '\0';
  81             opal_setenv(name, value + 1, false, &ret);
  82             free(name);
  83         }
  84     }
  85 
  86     /* All done */
  87 
  88     return ret;
  89 }
  90 
  91 /*
  92  * Portable version of setenv(), allowing editing of any environ-like
  93  * array
  94  */
  95 int opal_setenv(const char *name, const char *value, bool overwrite,
  96                 char ***env)
  97 {
  98     int i;
  99     char *newvalue, *compare;
 100     size_t len;
 101 
 102     /* Make the new value */
 103 
 104     if (NULL == value) {
 105         value = "";
 106         opal_asprintf(&newvalue, "%s=", name);
 107     } else {
 108         opal_asprintf(&newvalue, "%s=%s", name, value);
 109     }
 110     if (NULL == newvalue) {
 111         return OPAL_ERR_OUT_OF_RESOURCE;
 112     }
 113 
 114     /* Check the bozo case */
 115 
 116     if( NULL == env ) {
 117         return OPAL_ERR_BAD_PARAM;
 118     } else if (NULL == *env) {
 119         i = 0;
 120         opal_argv_append(&i, env, newvalue);
 121         free(newvalue);
 122         return OPAL_SUCCESS;
 123     }
 124 
 125     /* If this is the "environ" array, use putenv */
 126     if( *env == environ ) {
 127         /* THIS IS POTENTIALLY A MEMORY LEAK!  But I am doing it
 128            so that we don't violate the law of least
 129            astonishment for OPAL developers (i.e., those that don't
 130            check the return code of opal_setenv() and notice that we
 131            returned an error if you passed in the real environ) */
 132 #if defined (HAVE_SETENV)
 133         setenv(name, value, overwrite);
 134         /* setenv copies the value, so we can free it here */
 135         free(newvalue);
 136 #else
 137         len = strlen(name);
 138         for (i = 0; (*env)[i] != NULL; ++i) {
 139             if (0 == strncmp((*env)[i], name, len)) {
 140                 /* if we find the value in the environ, then
 141                  * we need to check the overwrite flag to determine
 142                  * the correct response */
 143                 if (overwrite) {
 144                     /* since it was okay to overwrite, do so */
 145                     putenv(newvalue);
 146                     /* putenv does NOT copy the value, so we
 147                      * cannot free it here */
 148                     return OPAL_SUCCESS;
 149                 }
 150                 /* since overwrite was not allowed, we return
 151                  * an error as we cannot perform the requested action */
 152                 free(newvalue);
 153                 return OPAL_EXISTS;
 154             }
 155         }
 156         /* since the value wasn't found, we can add it */
 157         putenv(newvalue);
 158         /* putenv does NOT copy the value, so we
 159          * cannot free it here */
 160 #endif
 161         return OPAL_SUCCESS;
 162     }
 163 
 164     /* Make something easy to compare to */
 165 
 166     opal_asprintf(&compare, "%s=", name);
 167     if (NULL == compare) {
 168         free(newvalue);
 169         return OPAL_ERR_OUT_OF_RESOURCE;
 170     }
 171     len = strlen(compare);
 172 
 173     /* Look for a duplicate that's already set in the env */
 174 
 175     for (i = 0; (*env)[i] != NULL; ++i) {
 176         if (0 == strncmp((*env)[i], compare, len)) {
 177             if (overwrite) {
 178                 free((*env)[i]);
 179                 (*env)[i] = newvalue;
 180                 free(compare);
 181                 return OPAL_SUCCESS;
 182             } else {
 183                 free(compare);
 184                 free(newvalue);
 185                 return OPAL_EXISTS;
 186             }
 187         }
 188     }
 189 
 190     /* If we found no match, append this value */
 191 
 192     i = opal_argv_count(*env);
 193     opal_argv_append(&i, env, newvalue);
 194 
 195     /* All done */
 196 
 197     free(compare);
 198     free(newvalue);
 199     return OPAL_SUCCESS;
 200 }
 201 
 202 
 203 /*
 204  * Portable version of unsetenv(), allowing editing of any
 205  * environ-like array
 206  */
 207 int opal_unsetenv(const char *name, char ***env)
 208 {
 209     int i;
 210     char *compare;
 211     size_t len;
 212     bool found;
 213 
 214     /* Check for bozo case */
 215 
 216     if (NULL == *env) {
 217         return OPAL_SUCCESS;
 218     }
 219 
 220     /* Make something easy to compare to */
 221 
 222     opal_asprintf(&compare, "%s=", name);
 223     if (NULL == compare) {
 224         return OPAL_ERR_OUT_OF_RESOURCE;
 225     }
 226     len = strlen(compare);
 227 
 228     /* Look for a duplicate that's already set in the env.  If we find
 229        it, free it, and then start shifting all elements down one in
 230        the array. */
 231 
 232     found = false;
 233     for (i = 0; (*env)[i] != NULL; ++i) {
 234         if (0 != strncmp((*env)[i], compare, len))
 235             continue;
 236         if (environ != *env) {
 237             free((*env)[i]);
 238         }
 239         for (; (*env)[i] != NULL; ++i)
 240             (*env)[i] = (*env)[i + 1];
 241         found = true;
 242         break;
 243     }
 244     free(compare);
 245 
 246     /* All done */
 247 
 248     return (found) ? OPAL_SUCCESS : OPAL_ERR_NOT_FOUND;
 249 }
 250 
 251 const char* opal_tmp_directory( void )
 252 {
 253     const char* str;
 254 
 255     if( NULL == (str = getenv("TMPDIR")) )
 256         if( NULL == (str = getenv("TEMP")) )
 257             if( NULL == (str = getenv("TMP")) )
 258                 str = OPAL_DEFAULT_TMPDIR;
 259     return str;
 260 }
 261 
 262 const char* opal_home_directory( void )
 263 {
 264     char* home = getenv("HOME");
 265 
 266     return home;
 267 }
 268 

/* [<][>][^][v][top][bottom][index][help] */