aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-06-16 13:17:35 +0530
committersinanmohd <sinan@sinanmohd.com>2024-06-16 13:20:24 +0530
commitd136b3c1b70d7ae687b763c59d1bc03d4ad3dbc2 (patch)
treecda33c21907a219fe18032f92b0bb8fedaf0c4d2
parentf407bbb1b00194fdc89ca382f4cf2f1f536ab18e (diff)
c: improve memory management
-rw-r--r--flake.nix1
-rw-r--r--include/util.h14
-rw-r--r--src/jobs.c14
-rw-r--r--src/queue.c9
-rw-r--r--src/util.c15
5 files changed, 34 insertions, 19 deletions
diff --git a/flake.nix b/flake.nix
index 33f3798..a1192f6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -29,6 +29,7 @@
gdb
ccls
+ valgrind
clang-tools # clang-format
];
diff --git a/include/util.h b/include/util.h
index c5aa0ab..5279a07 100644
--- a/include/util.h
+++ b/include/util.h
@@ -5,5 +5,19 @@
#define print_err(fmt, ...) \
fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
+#define LIST_FOREACH_FREE(cur, next, head, field, func_free) \
+ for ((cur) = ((head)->lh_first); (cur);) { \
+ (next) = ((cur)->field.le_next); \
+ func_free((cur)); \
+ (cur) = (next); \
+ }
+
+#define CIRCLEQ_FOREACH_FREE(cur, next, head, field, func_free) \
+ for ((cur) = ((head)->cqh_first); (cur) != (const void *)(head);) { \
+ (next) = ((cur)->field.cqe_next); \
+ func_free((cur)); \
+ (cur) = (next); \
+ }
+
int json_streaming_read(FILE *stream, cJSON **json);
int vpopen(FILE **stream, const char *file, char *const argv[]);
diff --git a/src/jobs.c b/src/jobs.c
index c6141e6..a7c3953 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -213,8 +213,8 @@ out_free:
void job_free(struct job *job)
{
- struct job *j;
- struct output *o;
+ struct job *job_cur, *job_next;
+ struct output *op_cur, *op_next;
if (job == NULL)
return;
@@ -222,11 +222,8 @@ void job_free(struct job *job)
free(job->name);
free(job->drv_path);
- LIST_FOREACH (o, &job->outputs, dlist)
- output_free(o);
-
- LIST_FOREACH (j, &job->deps, dlist)
- job_free(j);
+ LIST_FOREACH_FREE(op_cur, op_next, &job->outputs, dlist, output_free);
+ LIST_FOREACH_FREE(job_cur, job_next, &job->deps, dlist, job_free);
free(job);
}
@@ -257,7 +254,8 @@ int jobs_init(FILE **stream)
/* TODO: proproperly handle args */
char *const args[] = {
"nix-eval-jobs",
- "<nixpkgs>",
+ "--flake",
+ "github:sinanmohd/evanix#packages.x86_64-linux",
NULL,
};
diff --git a/src/queue.c b/src/queue.c
index e1e41ec..191c3f8 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -65,16 +65,14 @@ static void queue_push(struct queue *queue, struct job *job)
void queue_thread_free(struct queue_thread *queue_thread)
{
- struct job *job;
+ struct job *cur, *next;
int ret;
if (queue_thread == NULL)
return;
- CIRCLEQ_FOREACH (job, &queue_thread->queue->jobs, clist) {
- CIRCLEQ_REMOVE(&queue_thread->queue->jobs, job, clist);
- free(job);
- }
+ CIRCLEQ_FOREACH_FREE(cur, next, &queue_thread->queue->jobs, clist,
+ job_free);
ret = sem_destroy(&queue_thread->queue->sem);
if (ret < 0)
@@ -85,6 +83,7 @@ void queue_thread_free(struct queue_thread *queue_thread)
free(queue_thread->queue);
fclose(queue_thread->stream);
+ free(queue_thread);
}
int queue_thread_new(struct queue_thread **queue_thread, FILE *stream)
diff --git a/src/util.c b/src/util.c
index 001180e..e84a72a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -10,28 +10,31 @@
int json_streaming_read(FILE *stream, cJSON **json)
{
- int ret;
size_t n;
+ int ret;
char *line = NULL;
ret = getline(&line, &n, stream);
if (ret < 0) {
if (errno != 0) {
print_err("%s", strerror(errno));
- return -errno;
+ ret = -errno;
}
+ ret = -EOF;
- return -EOF;
+ goto out_free_line;
}
*json = cJSON_Parse(line);
- free(line);
if (cJSON_IsInvalid(*json)) {
print_err("%s", "Invalid JSON");
- return -EPERM;
+ ret = -EPERM;
+ goto out_free_line;
}
- return 0;
+out_free_line:
+ free(line);
+ return ret;
}
int vpopen(FILE **stream, const char *file, char *const argv[])