Initialize and populate SPT to allow a future setproctitle() * call. * * As setproctitle() basically needs to overwrite argv[0], we're * trying to determine what is the largest contiguous block * starting at argv[0] we can use for this purpose. * * As this range will overwrite some or all of the argv and environ * strings, a deep copy of these two arrays is performed. */
| 189 | * strings, a deep copy of these two arrays is performed. |
| 190 | */ |
| 191 | void spt_init(int argc, char *argv[]) { |
| 192 | char **envp = environ; |
| 193 | char *base, *end, *nul, *tmp; |
| 194 | int i, error, envc; |
| 195 | |
| 196 | if (!(base = argv[0])) |
| 197 | return; |
| 198 | |
| 199 | /* We start with end pointing at the end of argv[0] */ |
| 200 | nul = &base[strlen(base)]; |
| 201 | end = nul + 1; |
| 202 | |
| 203 | /* Attempt to extend end as far as we can, while making sure |
| 204 | * that the range between base and end is only allocated to |
| 205 | * argv, or anything that immediately follows argv (presumably |
| 206 | * envp). |
| 207 | */ |
| 208 | for (i = 0; i < argc || (i >= argc && argv[i]); i++) { |
| 209 | if (!argv[i] || argv[i] < end) |
| 210 | continue; |
| 211 | |
| 212 | if (end >= argv[i] && end <= argv[i] + strlen(argv[i])) |
| 213 | end = argv[i] + strlen(argv[i]) + 1; |
| 214 | } |
| 215 | |
| 216 | /* In case the envp array was not an immediate extension to argv, |
| 217 | * scan it explicitly. |
| 218 | */ |
| 219 | for (i = 0; envp[i]; i++) { |
| 220 | if (envp[i] < end) |
| 221 | continue; |
| 222 | |
| 223 | if (end >= envp[i] && end <= envp[i] + strlen(envp[i])) |
| 224 | end = envp[i] + strlen(envp[i]) + 1; |
| 225 | } |
| 226 | envc = i; |
| 227 | |
| 228 | /* We're going to deep copy argv[], but argv[0] will still point to |
| 229 | * the old memory for the purpose of updating the title so we need |
| 230 | * to keep the original value elsewhere. |
| 231 | */ |
| 232 | if (!(SPT.arg0 = strdup(argv[0]))) |
| 233 | goto syerr; |
| 234 | |
| 235 | #if __linux__ |
| 236 | if (!(tmp = strdup(program_invocation_name))) |
| 237 | goto syerr; |
| 238 | |
| 239 | program_invocation_name = tmp; |
| 240 | |
| 241 | if (!(tmp = strdup(program_invocation_short_name))) |
| 242 | goto syerr; |
| 243 | |
| 244 | program_invocation_short_name = tmp; |
| 245 | #elif __APPLE__ |
| 246 | if (!(tmp = strdup(getprogname()))) |
| 247 | goto syerr; |
| 248 |
no test coverage detected