Changeset 3039 for trunk/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c
- Timestamp:
- May 10, 2017, 12:55:51 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/common-env-and-cwd-opt.c
r2912 r3039 46 46 47 47 /** 48 * Common worker for kBuiltinOptEnvSet and kBuiltinOptEnvAppendPrepend that adds 49 * a new variable to the environment. 50 * 51 * @returns 0 on success, non-zero exit code on error. 52 * @param papszEnv The environment vector. 53 * @param pcEnvVars Pointer to the variable holding the number of 54 * environment variables held by @a papszEnv. 55 * @param pcAllocatedEnvVars Pointer to the variable holding max size of the 56 * environment vector. 57 * @param cVerbosity The verbosity level. 58 * @param pszValue The var=value string to apply. 59 */ 60 static int kBuiltinOptEnvAddVar(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, 61 int cVerbosity, const char *pszValue) 62 { 63 /* Append new variable. We probably need to resize the vector. */ 64 char **papszEnv = *ppapszEnv; 65 unsigned cEnvVars = *pcEnvVars; 66 if ((cEnvVars + 2) > *pcAllocatedEnvVars) 67 { 68 *pcAllocatedEnvVars = (cEnvVars + 2 + 0xf) & ~(unsigned)0xf; 69 papszEnv = (char **)realloc(papszEnv, *pcAllocatedEnvVars * sizeof(papszEnv[0])); 70 if (!papszEnv) 71 return errx(1, "out of memory!"); 72 *ppapszEnv = papszEnv; 73 } 74 papszEnv[cEnvVars] = strdup(pszValue); 75 if (!papszEnv[cEnvVars]) 76 return errx(1, "out of memory!"); 77 papszEnv[++cEnvVars] = NULL; 78 *pcEnvVars = cEnvVars; 79 if (cVerbosity > 0) 80 warnx("added '%s'", papszEnv[cEnvVars - 1]); 81 return 0; 82 } 83 84 85 /** 86 * Common worker for kBuiltinOptEnvSet and kBuiltinOptEnvAppendPrepend that 87 * remove duplicates. 88 * 89 * @returns 0 on success, non-zero exit code on error. 90 * @param papszEnv The environment vector. 91 * @param cEnvVars Number of environment variables. 92 * @param cVerbosity The verbosity level. 93 * @param pszValue The var=value string to apply. 94 * @param cchVar The length of the variable part of @a pszValue. 95 * @param iEnvVar Where to start searching after. 96 */ 97 static int kBuiltinOptEnvRemoveDuplicates(char **papszEnv, unsigned cEnvVars, int cVerbosity, 98 const char *pszValue, size_t cchVar, unsigned iEnvVar) 99 { 100 for (iEnvVar++; iEnvVar < cEnvVars; iEnvVar++) 101 if ( KSUBMIT_ENV_NCMP(papszEnv[iEnvVar], pszValue, cchVar) == 0 102 && papszEnv[iEnvVar][cchVar] == '=') 103 { 104 if (cVerbosity > 0) 105 warnx("removing duplicate '%s'", papszEnv[iEnvVar]); 106 free(papszEnv[iEnvVar]); 107 cEnvVars--; 108 if (iEnvVar != cEnvVars) 109 papszEnv[iEnvVar] = papszEnv[cEnvVars]; 110 papszEnv[cEnvVars] = NULL; 111 iEnvVar--; 112 } 113 return 0; 114 } 115 116 117 /** 48 118 * Handles the --set var=value option. 49 119 * 50 120 * @returns 0 on success, non-zero exit code on error. 51 * @param p apszEnv The environment vector.121 * @param ppapszEnv The environment vector pointer. 52 122 * @param pcEnvVars Pointer to the variable holding the number of 53 123 * environment variables held by @a papszEnv. … … 78 148 if (!papszEnv[iEnvVar]) 79 149 return errx(1, "out of memory!"); 80 break; 81 } 82 } 83 if (iEnvVar == cEnvVars) 84 { 85 /* Append new variable. We probably need to resize the vector. */ 86 if ((cEnvVars + 2) > *pcAllocatedEnvVars) 87 { 88 *pcAllocatedEnvVars = (cEnvVars + 2 + 0xf) & ~(unsigned)0xf; 89 papszEnv = (char **)realloc(papszEnv, *pcAllocatedEnvVars * sizeof(papszEnv[0])); 90 if (!papszEnv) 150 151 return kBuiltinOptEnvRemoveDuplicates(papszEnv, cEnvVars, cVerbosity, pszValue, cchVar, iEnvVar); 152 } 153 } 154 return kBuiltinOptEnvAddVar(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue); 155 } 156 return errx(1, "Missing '=': -E %s", pszValue); 157 } 158 159 160 /** 161 * Common worker for kBuiltinOptEnvAppend and kBuiltinOptEnvPrepend. 162 * 163 * @returns 0 on success, non-zero exit code on error. 164 * @param ppapszEnv The environment vector pointer. 165 * @param pcEnvVars Pointer to the variable holding the number of 166 * environment variables held by @a papszEnv. 167 * @param pcAllocatedEnvVars Pointer to the variable holding max size of the 168 * environment vector. 169 * @param cVerbosity The verbosity level. 170 * @param pszValue The var=value string to apply. 171 */ 172 static int kBuiltinOptEnvAppendPrepend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, 173 int cVerbosity, const char *pszValue, int fAppend) 174 { 175 const char *pszEqual = strchr(pszValue, '='); 176 if (pszEqual) 177 { 178 char **papszEnv = *ppapszEnv; 179 unsigned iEnvVar; 180 unsigned cEnvVars = *pcEnvVars; 181 size_t const cchVar = pszEqual - pszValue; 182 for (iEnvVar = 0; iEnvVar < cEnvVars; iEnvVar++) 183 { 184 char *pszCur = papszEnv[iEnvVar]; 185 if ( KSUBMIT_ENV_NCMP(pszCur, pszValue, cchVar) == 0 186 && pszCur[cchVar] == '=') 187 { 188 size_t cchOldValue = strlen(papszEnv[iEnvVar]) - cchVar - 1; 189 size_t cchNewValue = strlen(pszValue) - cchVar - 1; 190 char *pszNew = malloc(cchVar + 1 + cchOldValue + cchNewValue); 191 if (!papszEnv[iEnvVar]) 91 192 return errx(1, "out of memory!"); 92 *ppapszEnv = papszEnv; 93 } 94 papszEnv[cEnvVars] = strdup(pszValue); 95 if (!papszEnv[cEnvVars]) 96 return errx(1, "out of memory!"); 97 papszEnv[++cEnvVars] = NULL; 98 *pcEnvVars = cEnvVars; 99 if (cVerbosity > 0) 100 warnx("added '%s'", papszEnv[iEnvVar]); 101 } 102 else 103 { 104 /* Check for duplicates. */ 105 for (iEnvVar++; iEnvVar < cEnvVars; iEnvVar++) 106 if ( KSUBMIT_ENV_NCMP(papszEnv[iEnvVar], pszValue, cchVar) == 0 107 && papszEnv[iEnvVar][cchVar] == '=') 193 if (fAppend) 108 194 { 109 if (cVerbosity > 0) 110 warnx("removing duplicate '%s'", papszEnv[iEnvVar]); 111 free(papszEnv[iEnvVar]); 112 cEnvVars--; 113 if (iEnvVar != cEnvVars) 114 papszEnv[iEnvVar] = papszEnv[cEnvVars]; 115 papszEnv[cEnvVars] = NULL; 116 iEnvVar--; 195 memcpy(pszNew, papszEnv[iEnvVar], cchVar + 1 + cchOldValue); 196 memcpy(&pszNew[cchVar + 1 + cchOldValue], &pszValue[cchVar + 1], cchNewValue + 1); 117 197 } 118 } 119 } 120 else 121 return errx(1, "Missing '=': -E %s", pszValue); 122 123 return 0; 198 else 199 { 200 memcpy(pszNew, papszEnv[iEnvVar], cchVar + 1); /* preserve variable name case */ 201 memcpy(&pszNew[cchVar + 1], &pszValue[cchVar + 1], cchNewValue); 202 memcpy(&pszNew[cchVar + 1 + cchNewValue], &papszEnv[iEnvVar][cchVar + 1], cchOldValue + 1); 203 } 204 205 if (cVerbosity > 0) 206 warnx("replacing '%s' with '%s'", papszEnv[iEnvVar], pszNew); 207 free(papszEnv[iEnvVar]); 208 papszEnv[iEnvVar] = pszNew; 209 210 return kBuiltinOptEnvRemoveDuplicates(papszEnv, cEnvVars, cVerbosity, pszValue, cchVar, iEnvVar); 211 } 212 } 213 return kBuiltinOptEnvAddVar(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue); 214 } 215 return errx(1, "Missing '=': -E %s", pszValue); 216 } 217 218 219 /** 220 * Handles the --append var=value option. 221 * 222 * @returns 0 on success, non-zero exit code on error. 223 * @param ppapszEnv The environment vector pointer. 224 * @param pcEnvVars Pointer to the variable holding the number of 225 * environment variables held by @a papszEnv. 226 * @param pcAllocatedEnvVars Pointer to the variable holding max size of the 227 * environment vector. 228 * @param cVerbosity The verbosity level. 229 * @param pszValue The var=value string to apply. 230 */ 231 int kBuiltinOptEnvAppend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity, const char *pszValue) 232 { 233 return kBuiltinOptEnvAppendPrepend(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue, 1 /*fAppend*/); 234 } 235 236 237 /** 238 * Handles the --prepend var=value option. 239 * 240 * @returns 0 on success, non-zero exit code on error. 241 * @param ppapszEnv The environment vector pointer. 242 * @param pcEnvVars Pointer to the variable holding the number of 243 * environment variables held by @a papszEnv. 244 * @param pcAllocatedEnvVars Pointer to the variable holding max size of the 245 * environment vector. 246 * @param cVerbosity The verbosity level. 247 * @param pszValue The var=value string to apply. 248 */ 249 int kBuiltinOptEnvPrepend(char ***ppapszEnv, unsigned *pcEnvVars, unsigned *pcAllocatedEnvVars, int cVerbosity, const char *pszValue) 250 { 251 return kBuiltinOptEnvAppendPrepend(ppapszEnv, pcEnvVars, pcAllocatedEnvVars, cVerbosity, pszValue, 0 /*fAppend*/); 124 252 } 125 253
Note:
See TracChangeset
for help on using the changeset viewer.