summaryrefslogtreecommitdiffstats
path: root/src/io.c
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2020-02-14 14:17:26 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2020-02-14 14:17:26 +0200
commit6bd9b777f28db4d1c7927f7bb3dced339b0decb5 (patch)
treee95f8a770f54d18b55bf47afd6bbfd16c2f97615 /src/io.c
parentf8a4fbeeb230157f73789dc860ffbe84f76d0002 (diff)
downloadalgos-ld1-6bd9b777f28db4d1c7927f7bb3dced339b0decb5.tar.gz
algos-ld1-6bd9b777f28db4d1c7927f7bb3dced339b0decb5.tar.bz2
algos-ld1-6bd9b777f28db4d1c7927f7bb3dced339b0decb5.zip
add first bits of the I/O wrapper.
Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/io.c')
-rw-r--r--src/io.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/io.c b/src/io.c
new file mode 100644
index 0000000..74ea274
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,91 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include "io.h"
+
+int openstream(struct stream *in)
+{
+ struct stat st;
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP;
+ char *dname = NULL;
+ int ret = 0;
+
+ in->fd = -1;
+
+ if (!in->name) {
+ ret = EINVAL;
+ goto err;
+ }
+
+ if (in->out) {
+ char *tmp[2];
+
+ tmp[0] = strdup(in->name);
+ tmp[1] = dirname(tmp[0]);
+ dname = strdup(tmp[1]);
+ free(tmp[0]);
+
+ if (stat(dname, &st)) {
+ ret = errno;
+ /* TODO: error message */
+ goto err;
+ }
+
+ if(!(st.st_mode & S_IFDIR)) {
+ ret = EINVAL;
+ /* TODO: error message */
+ goto err;
+ }
+
+ if (!stat(in->name, &st)) {
+ if (!(st.st_mode & S_IFREG)) {
+ ret = EINVAL;
+ /* TODO: error message */
+ goto err;
+ }
+ mode = st.st_mode;
+ }
+ } else if (stat(in->name, &st)) {
+ ret = errno;
+ /* TODO: error message */
+ goto err;
+ } else if (!(st.st_mode & S_IFREG) || !st.st_size || (st.st_size % in->stride)) {
+ ret = EINVAL;
+ /* TODO: error message */
+ goto err;
+ } else {
+ in->n = st.st_size / in->stride;
+ }
+
+ if (in->out) {
+ in->fd = open(dname, O_TMPFILE | O_WRONLY, mode);
+ if (in->fd < 0) {
+ ret = errno;
+ /* TODO: error message */
+ goto err;
+ }
+
+ if (ftruncate(in->fd, in->stride * in->n)) {
+ ret = errno;
+ /* TODO: error message */
+ goto err;
+ }
+ } else {
+ in->fd = open(in->name, O_RDONLY | O_NOATIME);
+ if (in->fd < 0) {
+ ret = errno;
+ /* TODO: error message */
+ goto err;
+ }
+ }
+
+err:
+ free(dname);
+ return ret;
+}