diff options
-rw-r--r-- | src/daemon.c | 8 | ||||
-rw-r--r-- | src/daemon.h | 22 | ||||
-rw-r--r-- | src/satd-add.c | 45 |
3 files changed, 67 insertions, 8 deletions
diff --git a/src/daemon.c b/src/daemon.c index d262749..88e1b93 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -64,7 +64,7 @@ extern char **environ; * @param offset See pread(3). * @return See pread(3), only short if the file is shorter. */ -static ssize_t +ssize_t preadn(int fildes, void *buf, size_t nbyte, size_t offset) { PIO(pread); @@ -80,7 +80,7 @@ preadn(int fildes, void *buf, size_t nbyte, size_t offset) * @param offset See pwrite(3). * @return See pwrite(3). */ -static ssize_t +ssize_t pwriten(int fildes, void *buf, size_t nbyte, size_t offset) { PIO(pwrite); @@ -327,7 +327,7 @@ remove_job(const char *jobno, int runjob) { char *end; char *buf = NULL; - size_t no = 0, off = 0, n; + size_t no = 0, off = sizeof(size_t), n; ssize_t r; struct stat attr; struct job job; @@ -398,7 +398,7 @@ fail: struct job ** get_jobs(void) { - size_t off = 0, n, j = 0; + size_t off = sizeof(size_t), n, j = 0; struct stat attr; struct job **js = NULL; struct job job; diff --git a/src/daemon.h b/src/daemon.h index ddb2854..562ec52 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -117,6 +117,28 @@ struct job { /** + * Wrapper for `pread` that reads the required amount of data. + * + * @param fildes See pread(3). + * @param buf See pread(3). + * @param nbyte See pread(3). + * @param offset See pread(3). + * @return See pread(3), only short if the file is shorter. + */ +ssize_t preadn(int fildes, void *buf, size_t nbyte, size_t offset); + +/** + * Wrapper for `pwrite` that writes all specified data. + * + * @param fildes See pwrite(3). + * @param buf See pwrite(3). + * @param nbyte See pwrite(3). + * @param offset See pwrite(3). + * @return See pwrite(3). + */ +ssize_t pwriten(int fildes, void *buf, size_t nbyte, size_t offset); + +/** * Wrapper for `read` that reads all available data. * * Sets `errno` to `EBADMSG` on success. diff --git a/src/satd-add.c b/src/satd-add.c index 5afcf2d..0fec460 100644 --- a/src/satd-add.c +++ b/src/satd-add.c @@ -20,6 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ #include "daemon.h" +#include <sys/file.h> +#include <sys/stat.h> @@ -36,8 +38,12 @@ int main(int argc, char *argv[]) { size_t n = 0, elements = 0, i; + ssize_t r; char *message = NULL; int msg_argc; + int rc = 0; + struct job *job = NULL; + struct stat attr; assert(argc == 3); t (reopen(STATE_FILENO, O_RDWR)); @@ -51,13 +57,44 @@ main(int argc, char *argv[]) t ((msg_argc < 1) || !n || message[n - 1]); for (i = n; i--; elements += !message[i]); t (elements < (size_t)msg_argc); - n += sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec); - /* TODO main */ - (void) argv; + /* Parse message. */ + t (!(job = malloc(sizeof(*job) + n))); + job->argc = msg_argc; + job->clk = *(clockid_t *)(message + n + sizeof(int)); + job->ts = *(struct timespec *)(message + n + sizeof(int) + sizeof(clockid_t)); + job->n = n; + memcpy(job->payload, message, n); - return 0; + /* Update state file. */ + t (flock(STATE_FILENO, LOCK_EX)); + t (fstat(STATE_FILENO, &attr)); + r = preadn(STATE_FILENO, &(job->no), sizeof(job->no), 0); + t (r < 0); + if (r < (ssize_t)sizeof(job->no)) + job->no = 0; + else + job->no += 1; + t (pwriten(STATE_FILENO, &(job->no), sizeof(job->no), 0) < (ssize_t)sizeof(job->no)); + if (attr.st_size < (off_t)sizeof(job->no)) + attr.st_size = (off_t)sizeof(job->no); + n += sizeof(*job); + t (pwriten(STATE_FILENO, job, n, attr.st_size) < (ssize_t)n); + fsync(STATE_FILENO); + t (flock(STATE_FILENO, LOCK_UN)); + +done: + /* Cleanup. */ + shutdown(SOCK_FILENO, SHUT_WR); + close(SOCK_FILENO); + free(message); + free(job); + return rc; fail: + if (send_string(SOCK_FILENO, STDERR_FILENO, argv[0], ": ", strerror(errno), "\n", NULL)) + perror(argv[0]); + rc = 1; + goto done; (void) argc; } |