* Return absolute path to executable by searching PATH. * @param argv0 name of executable * @return (malloc'd) absolute path to executable (or NULL) */
| 406 | * @return (malloc'd) absolute path to executable (or NULL) |
| 407 | */ |
| 408 | static |
| 409 | const char * findProgramPath(const char * argv0) |
| 410 | { |
| 411 | char *path = NULL, *s = NULL, *se; |
| 412 | char *t = NULL; |
| 413 | |
| 414 | if (argv0 == NULL) return NULL; /* XXX can't happen */ |
| 415 | |
| 416 | /* If there is a / in argv[0], it has to be an absolute path. */ |
| 417 | /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */ |
| 418 | if (strchr(argv0, '/')) |
| 419 | return xstrdup(argv0); |
| 420 | |
| 421 | if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL) |
| 422 | return NULL; |
| 423 | |
| 424 | /* The return buffer in t is big enough for any path. */ |
| 425 | if ((t = malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL) |
| 426 | for (s = path; s && *s; s = se) { |
| 427 | |
| 428 | /* Snip PATH element into [s,se). */ |
| 429 | if ((se = strchr(s, ':'))) |
| 430 | *se++ = '\0'; |
| 431 | |
| 432 | /* Append argv0 to PATH element. */ |
| 433 | (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0); |
| 434 | |
| 435 | /* If file is executable, bingo! */ |
| 436 | if (!access(t, X_OK)) |
| 437 | break; |
| 438 | } |
| 439 | |
| 440 | /* If no executable was found in PATH, return NULL. */ |
| 441 | if (!(s && *s) && t != NULL) |
| 442 | t = _free(t); |
| 443 | path = _free(path); |
| 444 | |
| 445 | return t; |
| 446 | } |
| 447 | |
| 448 | static int execCommand(poptContext con) |
| 449 | { |
no test coverage detected