aboutsummaryrefslogtreecommitdiffstats
path: root/shared.c
diff options
context:
space:
mode:
authorGravatar Lars Hjemli <hjemli@gmail.com>2011-03-26 19:22:35 (JST)
committerGravatar Lars Hjemli <hjemli@gmail.com>2011-03-26 19:27:29 (JST)
commitc2b58ed8539fcfa4f05cc9da316bbc782f4b8f10 (patch)
tree96fc98e1cff5caebbd73725d4ca0605211ebe83f /shared.c
parentb2cf630a4b423bbda6507b7f658042563e76b36e (diff)
downloadcgit-c2b58ed8539fcfa4f05cc9da316bbc782f4b8f10.zip
cgit-c2b58ed8539fcfa4f05cc9da316bbc782f4b8f10.tar.gz
shared.c: use execvp() to execute filter commands
This reintroduces the use of execvp(), since the filter commands doesn't always contain an absolute path (i.e. snapshot compression filters). Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (limited to 'shared.c')
-rw-r--r--shared.c68
1 files changed, 11 insertions, 57 deletions
diff --git a/shared.c b/shared.c
index 8c3d18a..986f965 100644
--- a/shared.c
+++ b/shared.c
@@ -383,7 +383,7 @@ typedef struct {
383 char * value; 383 char * value;
384} cgit_env_var; 384} cgit_env_var;
385 385
386static char * prepare_env(struct cgit_repo * repo) { 386static 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
445int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) 407int 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 }