diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2023-04-11 10:15:52 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2023-04-11 10:15:52 -0400 |
commit | a824fc549497d8f35f16a270f12ff95ba36a03b3 (patch) | |
tree | 321fb075c21c8c5b9958241e72b725b18e47e768 /src/util | |
parent | 2f17a37c23a39571678e7d7244d99c1fc2672b40 (diff) | |
download | libgit2-ethomson/ssh_exec_2.tar.gz |
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/strvec.c | 91 | ||||
-rw-r--r-- | src/util/strvec.h | 40 | ||||
-rw-r--r-- | src/util/unix/process.c | 86 |
3 files changed, 141 insertions, 76 deletions
diff --git a/src/util/strvec.c b/src/util/strvec.c new file mode 100644 index 000000000..1e34c4c03 --- /dev/null +++ b/src/util/strvec.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "strvec.h" + +GIT_INLINE(int) copy_strings(git_strvec *out, const char **in, size_t len) +{ + size_t i; + + GIT_ERROR_CHECK_ALLOC(out->ptr); + + for (i = 0; i < len; i++) { + out->ptr[i] = git__strdup(in[i]); + GIT_ERROR_CHECK_ALLOC(out->ptr[i]); + } + + out->len = len; + return 0; +} + +int git_strvec_copy_strings(git_strvec *out, const char **in, size_t len) +{ + out->ptr = git__calloc(len, sizeof(char *)); + + return copy_strings(out, in, len); +} + +int git_strvec_copy_strings_with_null( + git_strvec *out, + const char **in, + size_t len) +{ + size_t new_len; + + GIT_ERROR_CHECK_ALLOC_ADD(&new_len, len, 1); + + if (copy_strings(out, in, len) < 0) + return -1; + + out->len = new_len; + return 0; +} + +bool git_strvec_contains_prefix( + const git_strvec *strings, + const char *str, + size_t n) +{ + size_t i; + + for (i = 0; i < strings->len; i++) { + if (strncmp(strings->ptr[i], str, n) == 0) + return true; + } + + return false; +} + +bool git_strvec_contains_key( + const git_strvec *strings, + const char *key, + char delimiter) +{ + const char *c; + + for (c = key; *c; c++) { + if (*c == delimiter) + break; + } + + return *c ? + git_strvec_contains_prefix(strings, key, (c - key)) : + false; +} + +void git_strvec_dispose(git_strvec *strings) +{ + size_t i; + + if (!strings) + return; + + for (i = 0; i < strings->len; i++) + git__free(strings->ptr[i]); + + git__free(strings->ptr); +} diff --git a/src/util/strvec.h b/src/util/strvec.h new file mode 100644 index 000000000..1fb4754cc --- /dev/null +++ b/src/util/strvec.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_strvec_h__ +#define INCLUDE_strvec_h__ + +#include "git2_util.h" + +typedef struct { + char **ptr; + size_t len; +} git_strvec; + +extern int git_strvec_copy_strings( + git_strvec *out, + const char **in, + size_t len); + +extern int git_strvec_copy_strings_with_null( + git_strvec *out, + const char **in, + size_t len); + +extern bool git_strvec_contains_prefix( + const git_strvec *strings, + const char *str, + size_t n); + +extern bool git_strvec_contains_key( + const git_strvec *strings, + const char *key, + char delimiter); + +extern void git_strvec_dispose(git_strvec *strings); + +#endif diff --git a/src/util/unix/process.c b/src/util/unix/process.c index ce28705a9..a12a8f724 100644 --- a/src/util/unix/process.c +++ b/src/util/unix/process.c @@ -12,13 +12,13 @@ #include "git2_util.h" #include "vector.h" #include "process.h" -#include "git2/strarray.h" +#include "strvec.h" extern char **environ; struct git_process { - char **args; - char **env; + git_strvec args; + git_strvec env; char *cwd; @@ -34,72 +34,6 @@ struct git_process { git_process_result_status status; }; -static void strings_free_deep(char **strings) -{ - char **s; - - if (!strings) - return; - - for (s = strings; *s; s++) - git__free(*s); - - git__free(strings); -} - -static int strlist_copy_with_null(char ***out, const char **in, size_t len) -{ - char **dup; - size_t new_len, i; - - GIT_ERROR_CHECK_ALLOC_ADD(&new_len, len, 1); - - dup = git__calloc(new_len, sizeof(char *)); - GIT_ERROR_CHECK_ALLOC(dup); - - for (i = 0; i < len; i++) { - dup[i] = git__strdup(in[i]); - GIT_ERROR_CHECK_ALLOC(dup[i]); - } - - *out = dup; - return 0; -} - -static bool strlist_contains_prefix( - const char **strings, - size_t len, - const char *str, - size_t n) -{ - size_t i; - - for (i = 0; i < len; i++) { - if (strncmp(strings[i], str, n) == 0) - return true; - } - - return false; -} - -static bool strlist_contains_key( - const char **strings, - size_t len, - const char *key, - char delimiter) -{ - const char *c; - - for (c = key; *c; c++) { - if (*c == delimiter) - break; - } - - return *c ? - strlist_contains_prefix(strings, len, key, (c - key)) : - false; -} - GIT_INLINE(bool) is_delete_env(const char *env) { char *c = index(env, '='); @@ -140,7 +74,7 @@ static int merge_env( if (!exclude_env) { for (kv = environ; *kv; kv++) { - if (env && strlist_contains_key(env, env_len, *kv, '=')) + if (env && git_strvec_contains_key(env, env_len, *kv, '=')) continue; dup = git__strdup(*kv); @@ -185,7 +119,7 @@ int git_process_new( process = git__calloc(sizeof(git_process), 1); GIT_ERROR_CHECK_ALLOC(process); - if (strlist_copy_with_null(&process->args, args, args_len) < 0 || + if (git_strvec_copy_with_null(&process->args, args, args_len) < 0 || merge_env(&process->env, env, env_len, opts->exclude_env) < 0) { git_process_free(process); return -1; @@ -376,9 +310,9 @@ int git_process_start(git_process *process) * call fails. If it succeeds, we'll close the status * pipe (via CLOEXEC) and the parent will know. */ - error = execve(process->args[0], - process->args, - process->env); + error = execve(process->args.ptr[0], + process->args.ptr, + process->env.ptr); write_status(status[1], "execve", error, errno); exit(0); @@ -568,7 +502,7 @@ void git_process_free(git_process *process) git_process_close(process); git__free(process->cwd); - strings_free_deep(process->args); - strings_free_deep(process->env); + git_strvec_dispose(&process->args); + git_strvec_dispose(&process->env); git__free(process); } |