Mercurial > sci
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);