aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/daemon.c8
-rw-r--r--src/daemon.h22
-rw-r--r--src/satd-add.c45
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;
}