diff options
-rw-r--r-- | include/nix.h | 4 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | src/evanix.c | 51 | ||||
-rw-r--r-- | src/jobs.c | 18 | ||||
-rw-r--r-- | src/meson.build | 9 | ||||
-rw-r--r-- | src/nix.c | 42 |
6 files changed, 110 insertions, 15 deletions
diff --git a/include/nix.h b/include/nix.h new file mode 100644 index 0000000..8533a82 --- /dev/null +++ b/include/nix.h @@ -0,0 +1,4 @@ +#include <nix/nix_api_value.h> + +void _nix_get_string_strdup(const char *str, unsigned n, void *user_data); +int _nix_init(nix_c_context **nix_ctx); diff --git a/meson.build b/meson.build index 46c59d3..edb1055 100644 --- a/meson.build +++ b/meson.build @@ -19,6 +19,7 @@ add_project_arguments( ) cjson_dep = dependency('libcjson') +nix_store_dep = dependency('nix-store-c') highs_dep = dependency('highs') sqlite_dep = dependency('sqlite3') evanix_inc = include_directories('include') diff --git a/src/evanix.c b/src/evanix.c index 92f9596..25bbd8e 100644 --- a/src/evanix.c +++ b/src/evanix.c @@ -1,10 +1,12 @@ #include <errno.h> #include <getopt.h> +#include <nix/nix_api_value.h> #include <stdlib.h> #include <string.h> #include "build.h" #include "evanix.h" +#include "nix.h" #include "queue.h" #include "solver_conformity.h" #include "solver_highs.h" @@ -52,6 +54,8 @@ static int evanix(char *expr); static int evanix_free(struct evanix_opts_t *opts); static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, char *argv[]); +static int evanix_opts_system_set(struct evanix_opts_t *opts, + nix_c_context *nix_ctx); /* This function returns errno on failure, consistent with the POSIX threads * functions, rather than returning -errno. */ @@ -71,13 +75,42 @@ static int evanix_build_thread_create(struct build_thread *build_thread) return 0; } +static int evanix_opts_system_set(struct evanix_opts_t *opts, + nix_c_context *nix_ctx) +{ + nix_err nix_ret; + + if (opts->system) + return 0; + + nix_ret = nix_setting_get(nix_ctx, "system", _nix_get_string_strdup, + &opts->system); + if (nix_ret != NIX_OK) { + print_err("%s", nix_err_msg(NULL, nix_ctx, NULL)); + return -EPERM; + } else if (opts->system == NULL) { + return -EPERM; + } + + return 0; +} + static int evanix(char *expr) { + nix_c_context *nix_ctx = NULL; struct queue_thread *queue_thread = NULL; struct build_thread *build_thread = NULL; FILE *jobs_stream = NULL; /* nix-eval-jobs stdout */ int ret = 0; + ret = _nix_init(&nix_ctx); + if (ret < 0) + goto out_free; + + ret = evanix_opts_system_set(&evanix_opts, nix_ctx); + if (ret < 0) + goto out_free; + ret = jobs_init(&jobs_stream, expr); if (ret < 0) goto out_free; @@ -127,6 +160,7 @@ static int evanix(char *expr) } out_free: + nix_c_context_free(nix_ctx); fclose(jobs_stream); queue_thread_free(queue_thread); free(build_thread); @@ -182,7 +216,13 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, opts->isdryrun = true; break; case 's': - opts->system = optarg; + opts->system = strdup(optarg); + if (opts->system == NULL) { + print_err("%s", strerror(errno)); + ret = -errno; + goto out_free_evanix; + } + break; case 'r': opts->solver_report = true; @@ -194,7 +234,8 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, "Try 'evanix --help' for more " "information.\n", c); - return -EINVAL; + ret = -EINVAL; + goto out_free_evanix; } ret = sqlite3_open_v2(optarg, &opts->statistics.db, @@ -212,7 +253,8 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, NULL); if (ret != SQLITE_OK) { print_err("%s", "Failed to prepare sql"); - return -EPERM; + ret = -EPERM; + goto out_free_evanix; } break; @@ -351,11 +393,12 @@ static int evanix_free(struct evanix_opts_t *opts) { int ret; + free(opts->system); + if (opts->statistics.statement) { sqlite3_finalize(opts->statistics.statement); opts->statistics.statement = NULL; } - if (opts->statistics.db) { ret = sqlite3_close(opts->statistics.db); if (ret != SQLITE_OK) { @@ -508,16 +508,14 @@ int job_read(FILE *stream, struct job **job) goto out_free; } - if (evanix_opts.system != NULL) { - temp = cJSON_GetObjectItemCaseSensitive(root, "system"); - if (!cJSON_IsString(temp)) { - ret = JOB_READ_JSON_INVAL; - goto out_free; - } - if (strcmp(evanix_opts.system, temp->valuestring)) { - ret = JOB_READ_SYS_MISMATCH; - goto out_free; - } + temp = cJSON_GetObjectItemCaseSensitive(root, "system"); + if (!cJSON_IsString(temp)) { + ret = JOB_READ_JSON_INVAL; + goto out_free; + } + if (strcmp(evanix_opts.system, temp->valuestring)) { + ret = JOB_READ_SYS_MISMATCH; + goto out_free; } temp = cJSON_GetObjectItemCaseSensitive(root, "name"); diff --git a/src/meson.build b/src/meson.build index 03f045b..8a4158a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,10 +11,17 @@ e = executable( 'solver_conformity.c', 'solver_highs.c', 'solver_sjf.c', + 'nix.c', + ], + + dependencies: [ + cjson_dep, + highs_dep, + sqlite_dep, + nix_store_dep ], include_directories: evanix_inc, - dependencies: [ cjson_dep, highs_dep, sqlite_dep ], install: true, c_args: [f'-DNIX_EVAL_JOBS_PATH=@NIX_EVAL_JOBS_PATH@'], ) diff --git a/src/nix.c b/src/nix.c new file mode 100644 index 0000000..f1b3a5a --- /dev/null +++ b/src/nix.c @@ -0,0 +1,42 @@ +#include <errno.h> +#include <string.h> + +#include "nix.h" +#include "util.h" + +void _nix_get_string_strdup(const char *str, unsigned n, void *user_data) +{ + char **s = user_data; + + *s = strndup(str, n); + if (*s == NULL) + print_err("%s", strerror(errno)); +} + +int _nix_init(nix_c_context **nix_ctx) +{ + nix_err nix_ret; + nix_c_context *nc; + int ret = 0; + + nc = nix_c_context_create(); + if (nix_ctx == NULL) { + print_err("%s", "Failed to create nix context"); + return -EPERM; + } + + nix_ret = nix_libstore_init(nc); + if (nix_ret != NIX_OK) { + print_err("%s", nix_err_msg(NULL, nc, NULL)); + ret = -EPERM; + goto out_free_nc; + } + +out_free_nc: + if (ret < 0) + nix_c_context_free(nc); + else + *nix_ctx = nc; + + return ret; +} |