aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-09-03 18:58:49 +0530
committersinanmohd <sinan@sinanmohd.com>2024-09-03 18:58:49 +0530
commit887b31ee12704e8c9da3bf4d26801d9236146192 (patch)
tree210d036978bad153f5e8ee46c14c4fc902ce7d37
parenta1eb8e06c42bf15e916a83180fc0d62c5a86fd37 (diff)
nix: init
-rw-r--r--include/nix.h4
-rw-r--r--meson.build1
-rw-r--r--src/evanix.c51
-rw-r--r--src/jobs.c18
-rw-r--r--src/meson.build9
-rw-r--r--src/nix.c42
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) {
diff --git a/src/jobs.c b/src/jobs.c
index 41fa3f3..fa2e267 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -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;
+}