| 103 | |
| 104 | |
| 105 | static int spt_copyenv(int envc, char *oldenv[]) { |
| 106 | extern char **environ; |
| 107 | char **envcopy = NULL; |
| 108 | char *eq; |
| 109 | int i, error; |
| 110 | int envsize; |
| 111 | |
| 112 | if (environ != oldenv) |
| 113 | return 0; |
| 114 | |
| 115 | /* Copy environ into envcopy before clearing it. Shallow copy is |
| 116 | * enough as clearenv() only clears the environ array. |
| 117 | */ |
| 118 | envsize = (envc + 1) * sizeof(char *); |
| 119 | envcopy = malloc(envsize); |
| 120 | if (!envcopy) |
| 121 | return ENOMEM; |
| 122 | memcpy(envcopy, oldenv, envsize); |
| 123 | |
| 124 | /* Note that the state after clearenv() failure is undefined, but we'll |
| 125 | * just assume an error means it was left unchanged. |
| 126 | */ |
| 127 | if ((error = spt_clearenv())) { |
| 128 | environ = oldenv; |
| 129 | free(envcopy); |
| 130 | return error; |
| 131 | } |
| 132 | |
| 133 | /* Set environ from envcopy */ |
| 134 | for (i = 0; envcopy[i]; i++) { |
| 135 | if (!(eq = strchr(envcopy[i], '='))) |
| 136 | continue; |
| 137 | |
| 138 | *eq = '\0'; |
| 139 | error = (0 != setenv(envcopy[i], eq + 1, 1))? errno : 0; |
| 140 | *eq = '='; |
| 141 | |
| 142 | /* On error, do our best to restore state */ |
| 143 | if (error) { |
| 144 | #ifdef HAVE_CLEARENV |
| 145 | /* We don't assume it is safe to free environ, so we |
| 146 | * may leak it. As clearenv() was shallow using envcopy |
| 147 | * here is safe. |
| 148 | */ |
| 149 | environ = envcopy; |
| 150 | #else |
| 151 | free(envcopy); |
| 152 | free(environ); /* Safe to free, we have just alloc'd it */ |
| 153 | environ = oldenv; |
| 154 | #endif |
| 155 | return error; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | free(envcopy); |
| 160 | return 0; |
| 161 | } /* spt_copyenv() */ |
| 162 |
no test coverage detected