root/opal/mca/pmix/pmix4x/pmix/src/util/pmix_environ.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmix_environ_merge
  2. pmix_setenv
  3. pmix_unsetenv
  4. pmix_tmp_directory
  5. pmix_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      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2007-2013 Los Alamos National Security, LLC.  All rights
  14  *                         reserved.
  15  * Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
  16  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #include <src/include/pmix_config.h>
  25 
  26 #include <pmix_common.h>
  27 
  28 #include <stdio.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 
  32 #include "src/util/printf.h"
  33 #include "src/util/argv.h"
  34 #include "src/util/pmix_environ.h"
  35 
  36 #define PMIX_DEFAULT_TMPDIR "/tmp"
  37 
  38 /*
  39  * Merge two environ-like char arrays, ensuring that there are no
  40  * duplicate entires
  41  */
  42 char **pmix_environ_merge(char **minor, char **major)
  43 {
  44     int i;
  45     char **ret = NULL;
  46     char *name, *value;
  47 
  48     /* Check for bozo cases */
  49 
  50     if (NULL == major) {
  51         if (NULL == minor) {
  52             return NULL;
  53         } else {
  54             return pmix_argv_copy(minor);
  55         }
  56     }
  57 
  58     /* First, copy major */
  59 
  60     ret = pmix_argv_copy(major);
  61 
  62     /* Do we have something in minor? */
  63 
  64     if (NULL == minor) {
  65         return ret;
  66     }
  67 
  68     /* Now go through minor and call pmix_setenv(), but with overwrite
  69        as false */
  70 
  71     for (i = 0; NULL != minor[i]; ++i) {
  72         value = strchr(minor[i], '=');
  73         if (NULL == value) {
  74             pmix_setenv(minor[i], NULL, false, &ret);
  75         } else {
  76 
  77             /* strdup minor[i] in case it's a constat string */
  78 
  79             name = strdup(minor[i]);
  80             value = name + (value - minor[i]);
  81             *value = '\0';
  82             pmix_setenv(name, value + 1, false, &ret);
  83             free(name);
  84         }
  85     }
  86 
  87     /* All done */
  88 
  89     return ret;
  90 }
  91 
  92 /*
  93  * Portable version of setenv(), allowing editing of any environ-like
  94  * array
  95  */
  96  pmix_status_t pmix_setenv(const char *name, const char *value, bool overwrite,
  97                 char ***env)
  98 {
  99     int i;
 100     char *newvalue, *compare;
 101     size_t len;
 102 
 103     /* Make the new value */
 104 
 105     if (NULL == value) {
 106         i = asprintf(&newvalue, "%s=", name);
 107     } else {
 108         i = asprintf(&newvalue, "%s=%s", name, value);
 109     }
 110     if (NULL == newvalue || 0 > i) {
 111         return PMIX_ERR_OUT_OF_RESOURCE;
 112     }
 113 
 114     /* Check the bozo case */
 115 
 116     if( NULL == env ) {
 117         return PMIX_ERR_BAD_PARAM;
 118     } else if (NULL == *env) {
 119         i = 0;
 120         pmix_argv_append(&i, env, newvalue);
 121         free(newvalue);
 122         return PMIX_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            because so that we don't violate the law of least
 129            astonishmet for PMIX developers (i.e., those that don't
 130            check the return code of pmix_setenv() and notice that we
 131            returned an error if you passed in the real environ) */
 132         putenv(newvalue);
 133         return PMIX_SUCCESS;
 134     }
 135 
 136     /* Make something easy to compare to */
 137 
 138     i = asprintf(&compare, "%s=", name);
 139     if (NULL == compare || 0 > i) {
 140         free(newvalue);
 141         return PMIX_ERR_OUT_OF_RESOURCE;
 142     }
 143     len = strlen(compare);
 144 
 145     /* Look for a duplicate that's already set in the env */
 146 
 147     for (i = 0; (*env)[i] != NULL; ++i) {
 148         if (0 == strncmp((*env)[i], compare, len)) {
 149             if (overwrite) {
 150                 free((*env)[i]);
 151                 (*env)[i] = newvalue;
 152                 free(compare);
 153                 return PMIX_SUCCESS;
 154             } else {
 155                 free(compare);
 156                 free(newvalue);
 157                 return PMIX_EXISTS;
 158             }
 159         }
 160     }
 161 
 162     /* If we found no match, append this value */
 163 
 164     i = pmix_argv_count(*env);
 165     pmix_argv_append(&i, env, newvalue);
 166 
 167     /* All done */
 168 
 169     free(compare);
 170     free(newvalue);
 171     return PMIX_SUCCESS;
 172 }
 173 
 174 
 175 /*
 176  * Portable version of unsetenv(), allowing editing of any
 177  * environ-like array
 178  */
 179  pmix_status_t pmix_unsetenv(const char *name, char ***env)
 180 {
 181     int i;
 182     char *compare;
 183     size_t len;
 184     bool found;
 185 
 186     /* Check for bozo case */
 187 
 188     if (NULL == *env) {
 189         return PMIX_SUCCESS;
 190     }
 191 
 192     /* Make something easy to compare to */
 193 
 194     i = asprintf(&compare, "%s=", name);
 195     if (NULL == compare || 0 > i) {
 196         return PMIX_ERR_OUT_OF_RESOURCE;
 197     }
 198     len = strlen(compare);
 199 
 200     /* Look for a duplicate that's already set in the env.  If we find
 201        it, free it, and then start shifting all elements down one in
 202        the array. */
 203 
 204     found = false;
 205     for (i = 0; (*env)[i] != NULL; ++i) {
 206         if (0 != strncmp((*env)[i], compare, len))
 207             continue;
 208         if (environ != *env) {
 209             free((*env)[i]);
 210         }
 211         for (; (*env)[i] != NULL; ++i)
 212             (*env)[i] = (*env)[i + 1];
 213         found = true;
 214         break;
 215     }
 216     free(compare);
 217 
 218     /* All done */
 219 
 220     return (found) ? PMIX_SUCCESS : PMIX_ERR_NOT_FOUND;
 221 }
 222 
 223 const char* pmix_tmp_directory( void )
 224 {
 225     const char* str;
 226 
 227     if( NULL == (str = getenv("TMPDIR")) )
 228         if( NULL == (str = getenv("TEMP")) )
 229             if( NULL == (str = getenv("TMP")) )
 230                 str = PMIX_DEFAULT_TMPDIR;
 231     return str;
 232 }
 233 
 234 const char* pmix_home_directory( void )
 235 {
 236     char* home = getenv("HOME");
 237 
 238     return home;
 239 }

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