diff options
| -rw-r--r-- | shared.c | 68 |
1 files changed, 11 insertions, 57 deletions
| @@ -383,7 +383,7 @@ typedef struct { | |||
| 383 | char * value; | 383 | char * value; |
| 384 | } cgit_env_var; | 384 | } cgit_env_var; |
| 385 | 385 | ||
| 386 | static char * prepare_env(struct cgit_repo * repo) { | 386 | static void prepare_env(struct cgit_repo * repo) { |
| 387 | cgit_env_var env_vars[] = { | 387 | cgit_env_var env_vars[] = { |
| 388 | { .name = "CGIT_REPO_URL", .value = repo->url }, | 388 | { .name = "CGIT_REPO_URL", .value = repo->url }, |
| 389 | { .name = "CGIT_REPO_NAME", .value = repo->name }, | 389 | { .name = "CGIT_REPO_NAME", .value = repo->name }, |
| @@ -394,52 +394,14 @@ static char * prepare_env(struct cgit_repo * repo) { | |||
| 394 | { .name = "CGIT_REPO_CLONE_URL", .value = repo->clone_url } | 394 | { .name = "CGIT_REPO_CLONE_URL", .value = repo->clone_url } |
| 395 | }; | 395 | }; |
| 396 | int env_var_count = ARRAY_SIZE(env_vars); | 396 | int env_var_count = ARRAY_SIZE(env_vars); |
| 397 | long values_space = (env_var_count * (PATH_MAX + 64)); | 397 | cgit_env_var *p, *q; |
| 398 | 398 | static char *warn = "cgit warning: failed to set env: %s=%s\n"; | |
| 399 | void * buffer; | 399 | |
| 400 | char ** vars; | 400 | p = env_vars; |
| 401 | char * values; | 401 | q = p + env_var_count; |
| 402 | int vars_index = 0; | 402 | for (; p < q; p++) |
| 403 | unsigned int chars_printed; | 403 | if (setenv(p->name, p->value, 1)) |
| 404 | 404 | fprintf(stderr, warn, p->name, p->value); | |
| 405 | /* Allocate buffer for environment variables: first in the buffer is an | ||
| 406 | * array of pointers to argument strings, terminated with a NULL pointer. | ||
| 407 | * After that the argument strings are placed after each other */ | ||
| 408 | buffer = malloc(((env_var_count + 1) * sizeof(char *)) + values_space); | ||
| 409 | if (!buffer) | ||
| 410 | return NULL; | ||
| 411 | |||
| 412 | vars = buffer; | ||
| 413 | values = (char *) &vars[env_var_count + 1]; | ||
| 414 | |||
| 415 | /* loop over all defined environment variables and their values */ | ||
| 416 | while (vars_index < env_var_count) { | ||
| 417 | char * name = env_vars[vars_index].name; | ||
| 418 | char * value = env_vars[vars_index].value; | ||
| 419 | |||
| 420 | if (!value) | ||
| 421 | value = ""; | ||
| 422 | |||
| 423 | chars_printed = snprintf(values, (values_space - 1), "%s=%s", name, | ||
| 424 | value); | ||
| 425 | if (chars_printed > (values_space - 1)) { | ||
| 426 | /* Buffer space exhausted: stop adding variables. | ||
| 427 | * Not all environment variables are defined, but the best we can | ||
| 428 | * do is to provide the ones that _are_ defined */ | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | |||
| 432 | values[chars_printed] = '\0'; | ||
| 433 | *&vars[vars_index] = values; | ||
| 434 | values += (chars_printed + 1); | ||
| 435 | values_space -= (chars_printed + 1); | ||
| 436 | vars_index++; | ||
| 437 | } | ||
| 438 | |||
| 439 | /* terminate the array with pointers */ | ||
| 440 | *&vars[vars_index] = NULL; | ||
| 441 | |||
| 442 | return (char *) buffer; | ||
| 443 | } | 405 | } |
| 444 | 406 | ||
| 445 | int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | 407 | int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) |
| @@ -450,20 +412,12 @@ int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) | |||
| 450 | chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); | 412 | chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); |
| 451 | filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); | 413 | filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); |
| 452 | if (filter->pid == 0) { | 414 | if (filter->pid == 0) { |
| 453 | char * env = NULL; | ||
| 454 | |||
| 455 | close(filter->pipe_fh[1]); | 415 | close(filter->pipe_fh[1]); |
| 456 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), | 416 | chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), |
| 457 | "Unable to use pipe as STDIN"); | 417 | "Unable to use pipe as STDIN"); |
| 458 | |||
| 459 | if (repo) | 418 | if (repo) |
| 460 | env = prepare_env(repo); | 419 | prepare_env(repo); |
| 461 | 420 | execvp(filter->cmd, filter->argv); | |
| 462 | execve(filter->cmd, filter->argv, (char **)env); | ||
| 463 | |||
| 464 | if (env) | ||
| 465 | free(env); | ||
| 466 | |||
| 467 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, | 421 | die("Unable to exec subprocess %s: %s (%d)", filter->cmd, |
| 468 | strerror(errno), errno); | 422 | strerror(errno), errno); |
| 469 | } | 423 | } |
