diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2025-06-18 16:06:26 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2025-06-18 16:10:33 -0400 |
commit | 097af10cea19537610c168f4107fdb958bcca9a4 (patch) | |
tree | 23971a19a4ac1675f18ebf89bebcf4cae374bb79 /src | |
parent | a556cb03777ec708fa193d46dba86e91b7ffec36 (diff) | |
download | stasis-097af10cea19537610c168f4107fdb958bcca9a4.tar.gz |
Dynamically allocate memory for system commands
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/core/conda.c | 72 | ||||
-rw-r--r-- | src/lib/delivery/delivery_install.c | 52 |
2 files changed, 82 insertions, 42 deletions
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c index 07128e6..fb7ee25 100644 --- a/src/lib/core/conda.c +++ b/src/lib/core/conda.c @@ -62,37 +62,38 @@ int micromamba(const struct MicromambaInfo *info, char *command, ...) { } int python_exec(const char *args) { - int result = -1; const char *command_base = "python "; - const size_t required_len = strlen(command_base) + strlen(args) + 1; + const char *command_fmt = "%s%s"; - char *command = calloc(required_len, sizeof(*command)); + const int len = snprintf(NULL, 0, command_fmt, command_base, args); + char *command = calloc(len + 1, sizeof(*command)); if (!command) { - SYSERROR("Unable to allocate %zu bytes for command string", required_len); - return result; + SYSERROR("Unable to allocate %d bytes for command string", len); + return -1; } - snprintf(command, required_len, "%s%s", command_base, args); + + snprintf(command, len + 1, command_fmt, command_base, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - result = system(command); + const int result = system(command); guard_free(command); return result; } int pip_exec(const char *args) { - int result = -1; const char *command_base = "python -m pip "; - const size_t required_len = strlen(command_base) + strlen(args) + 1; + const char *command_fmt = "%s%s"; - char *command = calloc(required_len, sizeof(*command)); + const int len = snprintf(NULL, 0, command_fmt, command_base, args); + char *command = calloc(len + 1, sizeof(*command)); if (!command) { - SYSERROR("Unable to allocate %zu bytes for command string", required_len); - return result; + SYSERROR("Unable to allocate %d bytes for command string", len); + return -1; } - snprintf(command, required_len, "%s%s", command_base, args); + snprintf(command, len + 1, command_fmt, command_base, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - result = system(command); + const int result = system(command); guard_free(command); return result; } @@ -199,7 +200,6 @@ int pkg_index_provides(int mode, const char *index, const char *spec) { } int conda_exec(const char *args) { - char command[PATH_MAX]; const char *mamba_commands[] = { "build", "install", @@ -224,9 +224,18 @@ int conda_exec(const char *args) { } } - snprintf(command, sizeof(command) - 1, "%s %s", conda_as, args); + const char *command_fmt = "%s %s"; + const int len = snprintf(NULL, 0, command_fmt, conda_as, args); + char *command = calloc(len + 1, sizeof(*command)); + if (!command) { + return -1; + } + + snprintf(command, len + 1, command_fmt, conda_as, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - return system(command); + const int result = system(command); + guard_free(command); + return result; } static int conda_prepend_bin(const char *root) { @@ -521,10 +530,8 @@ int conda_setup_headless() { } int conda_env_create_from_uri(char *name, char *uri, char *python_version) { - char env_command[PATH_MAX]; char *uri_fs = NULL; - // Convert a bare system path to a file:// path if (!strstr(uri, "://")) { uri_fs = calloc(strlen(uri) + strlen("file://") + 1, sizeof(*uri_fs)); @@ -553,17 +560,34 @@ int conda_env_create_from_uri(char *name, char *uri, char *python_version) { snprintf(spec, sizeof(spec) - 1, "- python=%s\n", python_version); file_replace_text(tempfile, "- python\n", spec, 0); - sprintf(env_command, "env create -n '%s' --file='%s'", name, tempfile); - int status = conda_exec(env_command); + const char *fmt = "env create -n '%s' --file='%s'"; + int len = snprintf(NULL, 0, fmt, name, tempfile); + char *env_command = calloc(len + 1, sizeof(*env_command)); + if (!env_command) { + return -1; + } + + snprintf(env_command, len + 1, fmt, name, tempfile); + const int status = conda_exec(env_command); unlink(tempfile); + guard_free(env_command); return status; } int conda_env_create(char *name, char *python_version, char *packages) { - char env_command[PATH_MAX]; - sprintf(env_command, "create -n %s python=%s %s", name, python_version, packages ? packages : ""); - return conda_exec(env_command); + const char *fmt = "create -n %s python=%s %s"; + const int len = snprintf(NULL, 0, fmt, name, python_version, packages ? packages : ""); + char *env_command = calloc(len + 1, sizeof(*env_command)); + if (!env_command) { + return -1; + } + + snprintf(env_command, len + 1, fmt, name, python_version, packages ? packages : ""); + const int result = conda_exec(env_command); + guard_free(env_command); + + return result; } int conda_env_remove(char *name) { diff --git a/src/lib/delivery/delivery_install.c b/src/lib/delivery/delivery_install.c index 7c900cb..0009c04 100644 --- a/src/lib/delivery/delivery_install.c +++ b/src/lib/delivery/delivery_install.c @@ -190,7 +190,6 @@ int delivery_purge_packages(struct Delivery *ctx, const char *env_name, int use_ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, char *env_name, int type, struct StrList **manifest) { char command_base[PATH_MAX]; - char pkgs[STASIS_BUFSIZ]; const char *env_current = getenv("CONDA_DEFAULT_ENV"); if (env_current) { @@ -204,7 +203,6 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } memset(command_base, 0, sizeof(command_base)); - memset(pkgs, 0, sizeof(pkgs)); strcat(command_base, "install"); typedef int (*Runner)(const char *); @@ -227,8 +225,8 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } sprintf(command_base + strlen(command_base), " --extra-index-url 'file://%s'", ctx->storage.wheel_artifact_dir); - size_t args_alloc_len = STASIS_BUFSIZ + 1; - char *args = calloc(args_alloc_len, sizeof(*args)); + size_t args_alloc_len = STASIS_BUFSIZ; + char *args = calloc(args_alloc_len + 1, sizeof(*args)); if (!args) { SYSERROR("%s", "Unable to allocate bytes for command arguments"); return -1; @@ -297,20 +295,17 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } } - const size_t required_len = strlen(args) - strlen(info->name) - strlen(info->version) + 5 + 1; - if (required_len + args_alloc_len > args_alloc_len) { - args_alloc_len += required_len; - char *tmp = realloc(args, args_alloc_len * sizeof(*args)); - if (!tmp) { + const char *fmt_append = "%s '%s==%s'"; + const char *fmt = " '%s==%s'"; + const int required_len = snprintf(NULL, 0, fmt_append, args, req, info->version); + if (required_len > (int) args_alloc_len) { + if (grow(required_len, &args_alloc_len, &args)) { + SYSERROR("Unable to allocate %d bytes for command arguments", required_len); guard_free(args); - SYSERROR("%s", "Unable to reallocate memory for args"); return -1; } - args = tmp; } - snprintf(args + strlen(args), - required_len, - " '%s==%s'", req, info->version); + snprintf(args + strlen(args), required_len, fmt, req, info->version); } else { fprintf(stderr, "Deferred package '%s' is not present in the tested package list!\n", name); guard_free(args); @@ -318,9 +313,29 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } } else { if (startswith(name, "--") || startswith(name, "-")) { - sprintf(args + strlen(args), " %s", name); + const char *fmt_append = "%s %s"; + const char *fmt = " %s"; + const int required_len = snprintf(NULL, 0, fmt_append, args, name); + if (required_len > (int) args_alloc_len) { + if (grow(required_len, &args_alloc_len, &args)) { + SYSERROR("Unable to allocate %d bytes for command arguments", required_len); + guard_free(args); + return -1; + } + } + sprintf(args + strlen(args), fmt, name); } else { - sprintf(args + strlen(args), " '%s'", name); + const char *fmt_append = "%s '%s'"; + const char *fmt = " '%s'"; + const int required_len = snprintf(NULL, 0, fmt_append, args, name); + if (required_len > (int) args_alloc_len) { + if (grow(required_len, &args_alloc_len, &args)) { + SYSERROR("Unable to allocate %d bytes for command arguments", required_len); + guard_free(args); + return -1; + } + } + sprintf(args + strlen(args), fmt, name); } } } @@ -332,9 +347,10 @@ int delivery_install_packages(struct Delivery *ctx, char *conda_install_dir, cha } int status = runner(command); + guard_free(args); + guard_free(command); if (status) { - guard_free(args); - guard_free(command); + // fail quickly return status; } } |