changeset 34:e52c762d8ba8

misc: cleanups
author David Demelier <markand@malikania.fr>
date Thu, 04 Aug 2022 17:47:19 +0200
parents 1d0ddf9e6efd
children 084dee2bef50
files doc/Doxyfile libsci/apic.h libsci/util.c libsci/util.h sciworkerd/sciworkerd.c sciworkerd/sciworkerd.h sciworkerd/task.c sciworkerd/task.h
diffstat 8 files changed, 513 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/doc/Doxyfile	Thu Aug 04 16:47:10 2022 +0200
+++ b/doc/Doxyfile	Thu Aug 04 17:47:19 2022 +0200
@@ -24,7 +24,7 @@
 WARNINGS               = YES
 WARN_IF_UNDOCUMENTED   = NO
 
-INPUT                  = lib scictl scid sciworkerd doc/mainpage.c
+INPUT                  = libsci scictl scid sciworkerd doc/mainpage.c
 FILE_PATTERNS          = *.c *.h
 RECURSIVE              = YES
 
--- a/libsci/apic.h	Thu Aug 04 16:47:10 2022 +0200
+++ b/libsci/apic.h	Thu Aug 04 17:47:19 2022 +0200
@@ -19,50 +19,176 @@
 #ifndef SCI_APIC_H
 #define SCI_APIC_H
 
+/**
+ * \file apic.h
+ * \brief Synchronous HTTP request.
+ *
+ * This module provides function to retrieve and send data to scid using HTTP
+ * requests.
+ */
+
 #include <jansson.h>
 
+/**
+ * \brief Maximum error message.
+ */
 #define APIC_ERR_MAX 128
+/**
+ * \brief Maximum URL length.
+ */
+#define APIC_URL_MAX 512
 
+/**
+ * \brief Request context.
+ *
+ * This structure contains the error message and the HTTP return status,
+ * nothing has to be free'd.
+ */
 struct apic {
-	char error[APIC_ERR_MAX];
-	long status;
+	char error[APIC_ERR_MAX];       /*!< Error message (empty unless). */
+	long status;                    /*!< HTTP return code. */
 };
 
+/**
+ * \brief Client configuration.
+ */
 extern struct apiconf {
-	char baseurl[512];
+	char baseurl[APIC_URL_MAX];     /*!< Base API URL for requets. */
 } apiconf /*! Global variable. */;
 
+/**
+ * Perform a GET request.
+ *
+ * The URL format will be appended to the base URL using printf(3) format
+ * style.
+ *
+ * \pre req != NULL
+ * \pre fmt != NULL
+ * \param req the request output
+ * \param fmt the format string for URL page
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_get(struct apic *, const char *, ...);
+apic_get(struct apic *req, const char *fmt, ...);
 
+/**
+ * Perform a POST request.
+ *
+ * The URL format will be appended to the base URL using printf(3) format
+ * style.
+ *
+ * \pre req != NULL
+ * \pre fmt != NULL
+ * \param req the request output
+ * \param body the optional document body
+ * \param fmt the format string for URL page
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_post(struct apic *, const json_t *, const char *, ...);
+apic_post(struct apic *req, const json_t *body, const char *fmt, ...);
 
+/**
+ * Add a new job.
+ *
+ * \pre req != NULL
+ * \pre job != NULL
+ * \param req the request output
+ * \param job the job model
+ * \return 0 on success or -1 on error
+ */
 int
-apic_job_add(struct apic *, json_t *);
+apic_job_add(struct apic *req, json_t *job);
 
+/**
+ * Get a list of job to perform for this worker.
+ *
+ * \pre req != NULL
+ * \pre worker != NULL
+ * \param req the request output
+ * \param worker the worker name
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_job_todo(struct apic *, const char *);
+apic_job_todo(struct apic *req, const char *worker);
 
-int
-apic_jobresult_add(struct apic *, json_t *);
-
+/**
+ * Add a new job result.
+ *
+ * \pre req != NULL
+ * \pre jobresult != NULL
+ * \param req the request output
+ * \param jobresult the jobresult model
+ * \return 0 on success or -1 on error
+ */
 int
-apic_project_save(struct apic *, json_t *);
+apic_jobresult_add(struct apic *req, json_t *jobresult);
 
+/**
+ * Add or update a project.
+ *
+ * \pre req != NULL
+ * \pre project != NULL
+ * \param req the request output
+ * \param project the project model
+ * \return 0 on success or -1 on error
+ */
+int
+apic_project_save(struct apic *req, json_t *project);
+
+/**
+ * Get a list of projects.
+ *
+ * \pre req != NULL
+ * \param req the request output
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_project_list(struct apic *);
-
-json_t *
-apic_project_find(struct apic *, const char *);
+apic_project_list(struct apic *req);
 
-int
-apic_worker_save(struct apic *, json_t *);
-
+/**
+ * Get a project by name.
+ *
+ * \pre req != NULL
+ * \pre name != NULL
+ * \param name the project name
+ * \param req the request output
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_worker_list(struct apic *);
+apic_project_find(struct apic *req, const char *name);
+
+/**
+ * Add or update a worker.
+ *
+ * \pre req != NULL
+ * \pre worker != NULL
+ * \param req the request output
+ * \param worker the worker model
+ * \return 0 on success or -1 on error
+ */
+int
+apic_worker_save(struct apic *req, json_t *worker);
 
+/**
+ * Get a list of workers.
+ *
+ * \pre req != NULL
+ * \param req the request output
+ * \return the JSON document received from the server or NULL on failure
+ */
 json_t *
-apic_worker_find(struct apic *, const char *);
+apic_worker_list(struct apic *req);
+
+/**
+ * Get a worker by name.
+ *
+ * \pre req != NULL
+ * \pre name != NULL
+ * \param name the worker name
+ * \param req the request output
+ * \return the JSON document received from the server or NULL on failure
+ */
+json_t *
+apic_worker_find(struct apic *req, const char *name);
 
 #endif /* !SCI_APIC_H */
--- a/libsci/util.c	Thu Aug 04 16:47:10 2022 +0200
+++ b/libsci/util.c	Thu Aug 04 17:47:19 2022 +0200
@@ -63,17 +63,6 @@
 	return ret;
 }
 
-void *
-util_memdup(const void *ptr, size_t size)
-{
-	void *ret;
-
-	if (!(ret = malloc(size)))
-		util_die("malloc: %s\n", strerror(errno));
-
-	return memcpy(ret, ptr, size);
-}
-
 char *
 util_strdup(const char *src)
 {
@@ -123,17 +112,6 @@
 }
 
 FILE *
-util_fmemopen(void *buf, size_t size, const char *mode)
-{
-	FILE *fp;
-
-	if (!(fp = fmemopen(buf, size, mode)))
-		util_die("fmemopen: %s\n", strerror(errno));
-
-	return fp;
-}
-
-FILE *
 util_open_memstream(char **out, size_t *outsz)
 {
 	assert(out);
--- a/libsci/util.h	Thu Aug 04 16:47:10 2022 +0200
+++ b/libsci/util.h	Thu Aug 04 17:47:19 2022 +0200
@@ -16,6 +16,14 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/**
+ * \file util.h
+ * \brief Miscellaneous utilities.
+ *
+ * Most of the allocations functions will exit with code 1 on memory
+ * exhaustion.
+ */
+
 #ifndef SCI_UTIL_H
 #define SCI_UTIL_H
 
@@ -24,59 +32,166 @@
 
 #include <jansson.h>
 
+/**
+ * Compute fixed size array length.
+ */
 #define UTIL_SIZE(x) (sizeof (x) / sizeof (x[0]))
 
+/**
+ * Wrap malloc or exit with code 1.
+ *
+ * \param w the bytes to allocate
+ * \return the pointer to the memory
+ */
 void *
-util_malloc(size_t);
+util_malloc(size_t w);
 
-void *
-util_calloc(size_t, size_t);
-
+/**
+ * Wrap calloc or exit with code 1.
+ *
+ * \param n the number of items
+ * \param w the bytes per item
+ * \return the pointer to the memory
+ */
 void *
-util_realloc(void *, size_t);
+util_calloc(size_t n, size_t w);
 
+/**
+ * Wrap realloc or exit with code 1.
+ *
+ * \param ptr the old memory
+ * \param w the bytes to allocate
+ * \return the pointer to the memory
+ */
 void *
-util_reallocarray(void *, size_t, size_t);
+util_realloc(void *ptr, size_t w);
 
+/**
+ * Wrap reallocarray or exit with code 1.
+ *
+ * \param ptr the old memory
+ * \param n the number of items
+ * \param w the bytes per item
+ * \return the pointer to the memory
+ */
 void *
-util_memdup(const void *, size_t);
+util_reallocarray(void *ptr, size_t n, size_t w);
 
+/**
+ * Wrap strdup or exit with code 1.
+ *
+ * \pre str != NULL
+ * \param str the string to duplicate
+ * \return the copied string
+ */
 char *
-util_strdup(const char *);
+util_strdup(const char *str);
 
+/**
+ * Wrap strndup or exit with code 1.
+ *
+ * \pre str != NULL
+ * \param str the string to duplicate
+ * \param n the maximum string to not exceed
+ * \return the copied string
+ */
 char *
-util_strndup(const char *, size_t);
+util_strndup(const char *str, size_t n);
 
-char *
-util_basename(const char *);
-
+/**
+ * Get the base name component from a path.
+ *
+ * \pre path != NULL
+ * \param path the path to extract
+ * \return a static thread local value containing the base name
+ */
 char *
-util_dirname(const char *);
+util_basename(const char *path);
 
+/**
+ * Get the directory name component from a path.
+ *
+ * \pre path != NULL
+ * \param path the path to extract
+ * \return a static thread local value containing the directory name
+ */
+char *
+util_dirname(const char *path);
+
+/**
+ * Wrap open_memstream or exit with code 1.
+ *
+ * \pre out != NULL
+ * \pre outsz != NULL
+ * \param out the destination string
+ * \param outsz the destination string length
+ * \return a non-NULL file pointer
+ */
 FILE *
-util_fmemopen(void *, size_t, const char *);
+util_open_memstream(char **out, size_t *outsz);
 
-FILE *
-util_open_memstream(char **, size_t *);
-
+/**
+ * Read the whole content from the given file.
+ *
+ * \pre path != NULL
+ * \param path the file to read
+ * \return the file content or NULL on error (and errno is set)
+ */
 char *
 util_read(const char *);
 
+/**
+ * Write an error message to error output and exit with code 1.
+ *
+ * \pre fmt != NULL
+ * \param fmt the format string
+ */
 void
-util_die(const char *, ...);
+util_die(const char *fmt, ...);
 
+/**
+ * Wrap json_pack or exit with code 1.
+ *
+ * \pre fmt != NULL
+ * \param fmt the json_pack format string and its arguments
+ * \return a non-NULL JSON document
+ */
 json_t *
-util_json_pack(const char *, ...);
+util_json_pack(const char *fmt, ...);
 
+/**
+ * Wrap json_dump or exit with code 1.
+ *
+ * \pre json != NULL
+ * \param json the JSON value to transform to string
+ */
 char *
-util_json_dump(const json_t *);
+util_json_dump(const json_t *json);
 
-/* defined in extern/ */
-
+/**
+ * OpenBSD strlcpy extension builtin.
+ *
+ * \pre dst != NULL
+ * \pre src != NULL
+ * \param dst the destination string
+ * \param src the source string
+ * \param size the maximum size in dst
+ * \return the number of bytes written
+ */
 size_t
-util_strlcpy(char *, const char *, size_t);
+util_strlcpy(char *dst, const char *src, size_t size);
 
+/**
+ * OpenBSD strtonum extension builtin.
+ *
+ * \pre str != NULL
+ * \param str the string to convert
+ * \param min the lower bound (included)
+ * \param max the upper bound (included)
+ * \param errstr the error string pointer to be set on error (not dynamically allocated)
+ * \return the converted value
+ */
 long long
-util_strtonum(const char *, long long, long long, const char **);
+util_strtonum(const char *str, long long min, long long max, const char **errstr);
 
 #endif /* !SCI_UTIL_H */
--- a/sciworkerd/sciworkerd.c	Thu Aug 04 16:47:10 2022 +0200
+++ b/sciworkerd/sciworkerd.c	Thu Aug 04 17:47:19 2022 +0200
@@ -1,3 +1,21 @@
+/*
+ * sciworkerd.c -- main sciworkerd file
+ *
+ * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include <errno.h>
 #include <poll.h>
 #include <signal.h>
@@ -375,8 +393,10 @@
 
 	LL_FOREACH_SAFE(taskpending, iter, tmp)
 		taskentry_free(iter);
-	LL_FOREACH_SAFE(tasks, iter, tmp)
+	LL_FOREACH_SAFE(tasks, iter, tmp) {
+		task_kill(iter->task);
 		taskentry_free(iter);
+	}
 	LL_FOREACH_SAFE(taskfinished, iter, tmp)
 		taskentry_free(iter);
 }
--- a/sciworkerd/sciworkerd.h	Thu Aug 04 16:47:10 2022 +0200
+++ b/sciworkerd/sciworkerd.h	Thu Aug 04 17:47:19 2022 +0200
@@ -1,23 +1,64 @@
+/*
+ * sciworkerd.h -- main sciworkerd file
+ *
+ * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef SCIWORKERD_H
 #define SCIWORKERD_H
 
+/**
+ * \file sciworkerd.h
+ * \brief Main sciworkerd file.
+ */
+
+/**
+ * \brief Maximum URL length.
+ */
 #define SCIWORKERD_URL_MAX      512
+/**
+ * \brief Maximum worker name.
+ */
 #define SCIWORKERD_NAME_MAX     64
 
+/**
+ * \brief Main sciworkerd configuration structure.
+ */
 extern struct sciworkerd {
-	char url[SCIWORKERD_URL_MAX];
-	char name[SCIWORKERD_NAME_MAX];
-	unsigned int fetchinterval;
-	unsigned int maxjobs;
-	unsigned int timeout;
-} sciworkerd;
+	char url[SCIWORKERD_URL_MAX];   /*!< API URL. */
+	char name[SCIWORKERD_NAME_MAX]; /*!< This worker name to use. */
+	unsigned int fetchinterval;     /*!< Delay in seconds before fetching jobs. */
+	unsigned int maxjobs;           /*!< Maximum parallel jobs. */
+	unsigned int timeout;           /*!< Maximum time in seconds before killing a job. */
+} sciworkerd /*! Global variable. */;
 
+/**
+ * Initialize sciworkerd.
+ */
 void
 sciworkerd_init(void);
 
+/**
+ * Run forever.
+ */
 void
 sciworkerd_run(void);
 
+/**
+ * Cleanup sciworkerd resources and kill remaining tasks.
+ */
 void
 sciworkerd_finish(void);
 
--- a/sciworkerd/task.c	Thu Aug 04 16:47:10 2022 +0200
+++ b/sciworkerd/task.c	Thu Aug 04 17:47:19 2022 +0200
@@ -1,3 +1,21 @@
+/*
+ * task.c -- worker task management
+ *
+ * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <assert.h>
--- a/sciworkerd/task.h	Thu Aug 04 16:47:10 2022 +0200
+++ b/sciworkerd/task.h	Thu Aug 04 17:47:19 2022 +0200
@@ -1,59 +1,194 @@
+/*
+ * task.h -- worker task management
+ *
+ * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef SCIWORKERD_TASK_H
 #define SCIWORKERD_TASK_H
 
+/**
+ * \file task.h
+ * \brief Worker task management.
+ */
+
 #include <sys/types.h>
 
 struct pollfd;
 struct task;
 
+/**
+ * \brief Task status.
+ */
 enum taskstatus {
-	TASKSTATUS_PENDING,     /* not started yet. */
-	TASKSTATUS_RUNNING,     /* currently running. */
-	TASKSTATUS_EXITED,      /* process exited normally. */
-	TASKSTATUS_KILLED       /* process killed killed. */
+	TASKSTATUS_PENDING,     /*!< not started yet. */
+	TASKSTATUS_RUNNING,     /*!< currently running. */
+	TASKSTATUS_EXITED,      /*!< process exited normally. */
+	TASKSTATUS_KILLED       /*!< process killed killed. */
 };
 
+/**
+ * \brief Task termination code.
+ */
 struct taskcode {
-	int exitcode;
-	int sigcode;
+	int exitcode;           /*!< Normal exit code (if sigcode == 0). */
+	int sigcode;            /*!< Signal termination code (exitcode == 0). */
 };
 
+/**
+ * Construct a new task with the given tag.
+ *
+ * The task is just initialized, you need to call setup and start before
+ * continuing
+ *
+ * \pre tag != NULL
+ * \param tag the task tag
+ * \return a new initialized task
+ */
 struct task *
 task_new(const char *tag);
 
+/**
+ * Create a temporary file containing the script code to execute for this task.
+ *
+ * \pre self != NULL
+ * \pre script != NULL
+ * \param self the task object
+ * \param script the script code to execute
+ * \return 0 on success or -1 on error
+ */
 int
 task_setup(struct task *self, const char *script);
 
+/**
+ * Fork the process to start the task.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return the child PID on success or -1 on error
+ */
 pid_t
 task_start(struct task *self);
 
+/**
+ * Wait for the task to complete.
+ *
+ * You should usually call this function when you're sure that the task is over
+ * otherwise it would block until it's complete.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return 0 on success or -1 one error
+ */
 int
 task_wait(struct task *self);
 
+/**
+ * Send a termination signal to the task.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return 0 on success or -1 one error
+ */
 int
 task_kill(struct task *self);
 
+/**
+ * Prepare the pollfd structure with the task pipe.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \param fd the pollfd structure to fill
+ */
 void
 task_prepare(struct task *self, struct pollfd *fd);
 
+/**
+ * Synchronize the child output.
+ *
+ * The following return values are possible:
+ *
+ * == 0: child exited
+ * >= 0: data has been received, keep going
+ *  < 0: I/O error, you should kill and wait
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \param fd the pollfd structure result
+ * \return various condition as described
+ */
 int
 task_sync(struct task *self, const struct pollfd *fd);
 
+/**
+ * Tells when the task has been started.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ */
 time_t
 task_uptime(const struct task *self);
 
+/**
+ * Returns the task PID.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return the task PID
+ * \warning the task must be running
+ */
 pid_t
 task_pid(const struct task *self);
 
+/**
+ * Return the task console output.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return the console output or NULL if none
+ */
 const char *
 task_console(const struct task *self);
 
+/**
+ * Get the task status.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return the current task status
+ */
 enum taskstatus
 task_status(const struct task *self);
 
+/**
+ * Get the task exit or signal code
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \return the task exit/signal codes
+ */
 struct taskcode
 task_code(const struct task *self);
 
+/**
+ * Free the task and its resources.
+ *
+ * \pre self != NULL
+ * \param self the task object
+ * \warning the task must not be running
+ */
 void
 task_free(struct task *self);