summaryrefslogtreecommitdiff
path: root/src/util/file
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2023-12-31 17:29:19 -0500
committerAndrew Opalach <andrew@akon.city> 2023-12-31 17:29:19 -0500
commit842fed76fdb6762e10d1571255229a80c8505b04 (patch)
treea2d46bc3ba63a91cf6ca00d285716a084cd4da8b /src/util/file
parentb0f53d634813af0a038d4faf6fa71d90d9aa0845 (diff)
downloadlibnaunet-842fed76fdb6762e10d1571255229a80c8505b04.tar.gz
libnaunet-842fed76fdb6762e10d1571255229a80c8505b04.tar.bz2
libnaunet-842fed76fdb6762e10d1571255229a80c8505b04.zip
Update
- Add aki_poll and aki_fs_event - Various aki_file improvments - Add grow mode to aki_packet_pool - aki_packet_stream_pause/resume -> cork - Misc fixes and improvments Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/util/file')
-rw-r--r--src/util/file/file.h11
-rw-r--r--src/util/file/file_linux.c43
-rw-r--r--src/util/file/file_stdio.c4
-rw-r--r--src/util/file/util.c10
4 files changed, 56 insertions, 12 deletions
diff --git a/src/util/file/file.h b/src/util/file/file.h
index 465d76a..a6611bd 100644
--- a/src/util/file/file.h
+++ b/src/util/file/file.h
@@ -14,6 +14,13 @@
#endif
#include <al/str.h>
+#include <al/lib.h>
+
+enum {
+ AKI_FILE_READONLY = 1,
+ AKI_FILE_CREATE = 1 << 1,
+ AKI_FILE_LOCK = 1 << 2
+};
enum {
AKI_ENTRY_FILE = 0,
@@ -60,8 +67,9 @@ struct aki_dir_entry {
str path;
};
-bool aki_file_open(struct aki_file *file, str *path, bool create);
+bool aki_file_open(struct aki_file *file, str *path, s32 flags);
bool aki_file_exists(str *path);
+bool aki_file_create(str *path);
bool aki_file_truncate(struct aki_file *file, off_t size);
off_t aki_file_seek(struct aki_file *file, off_t offset, s32 whence);
size_t aki_file_get_filesize(struct aki_file *file);
@@ -69,6 +77,7 @@ bool aki_file_write(struct aki_file *file, void *buf, size_t size);
bool aki_file_read(struct aki_file *file, void *buf, size_t size);
s32 aki_file_read_as_str(struct aki_file *file, str *out);
s32 aki_file_read_as_c_str(struct aki_file *file, char **out);
+s32 aki_file_replace(struct aki_file *file, str *buf);
void *aki_file_mmap(struct aki_file *file);
void *aki_file_mremap(struct aki_file *file, size_t size, void *old_map);
void aki_file_munmap(struct aki_file *file, void *map);
diff --git a/src/util/file/file_linux.c b/src/util/file/file_linux.c
index 708bd2d..f916e0b 100644
--- a/src/util/file/file_linux.c
+++ b/src/util/file/file_linux.c
@@ -1,16 +1,33 @@
-#include <sys/mman.h>
#include <al/log.h>
+#include <sys/mman.h>
#include "../error.h"
#include "file.h"
-bool aki_file_open(struct aki_file *file, str *path, bool create)
+static bool lock_file_internal(s32 fd)
+{
+ struct flock l = {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0
+ };
+ if (fcntl(fd, F_SETLKW, &l) == -1) {
+ al_log_error("file", "fcntl(F_SETLKW) failed (%s).", aki_strerror(errno));
+ close(fd);
+ return false;
+ }
+ return true;
+}
+
+bool aki_file_open(struct aki_file *file, str *path, s32 flags)
{
+ al_assert(!((flags & AKI_FILE_READONLY) && (flags & AKI_FILE_LOCK)));
char *c_str = al_str_to_c_str(path);
- s32 flags = O_RDWR;
- if (create) flags |= O_CREAT;
- file->fd = open(c_str, flags, 0666);
+ s32 oflags = (flags & AKI_FILE_READONLY) ? O_RDONLY : O_RDWR;
+ if (flags & AKI_FILE_CREATE) oflags |= O_CREAT;
+ file->fd = open(c_str, oflags, 0666);
al_free(c_str);
if (file->fd == -1) {
al_log_error("file", "open(%.*s) failed (%s).", AL_STR_PRINTF(path), aki_strerror(errno));
@@ -24,6 +41,7 @@ bool aki_file_open(struct aki_file *file, str *path, bool create)
return false;
}
file->filesize = sb.st_size;
+ if (flags & AKI_FILE_LOCK) lock_file_internal(file->fd);
return true;
}
@@ -32,12 +50,19 @@ bool aki_file_exists(str *path)
char *c_str = al_str_to_c_str(path);
s32 ret = access(c_str, F_OK);
al_free(c_str);
- if (ret != 0) {
- al_log_error("file", "access(%.*s, F_OK) failed (%s).", AL_STR_PRINTF(path), aki_strerror(errno));
- }
return ret == 0;
}
+bool aki_file_create(str *path)
+{
+ struct aki_file file;
+ if (aki_file_open(&file, path, AKI_FILE_CREATE)) {
+ aki_file_close(&file);
+ return true;
+ }
+ return false;
+}
+
off_t aki_file_seek(struct aki_file *file, off_t offset, s32 whence)
{
off_t res = lseek(file->fd, offset, whence);
@@ -98,7 +123,6 @@ void *aki_file_mmap(struct aki_file *file)
void *aki_file_mremap(struct aki_file *file, size_t size, void *old_map)
{
- printf("old_size: %zu, new_size: %zu\n", file->filesize, size);
void *map = mremap(old_map, file->filesize, size, MREMAP_MAYMOVE);
if (map == MAP_FAILED) {
al_log_error("file", "mremap(%p, %zu, %zu) failed (%s).", old_map,
@@ -152,6 +176,7 @@ bool aki_dir_exists(str *path)
}
return false;
}
+ closedir(dir.dir);
return true;
}
diff --git a/src/util/file/file_stdio.c b/src/util/file/file_stdio.c
index 52d8761..fa1e4ff 100644
--- a/src/util/file/file_stdio.c
+++ b/src/util/file/file_stdio.c
@@ -4,10 +4,10 @@
#include "file.h"
-bool aki_file_open(struct aki_file *file, str *path, bool create)
+bool aki_file_open(struct aki_file *file, str *path, s32 flags)
{
char *c_str = al_str_to_c_str(path);
- const char *mode = create ? "wb+" : "rb+";
+ const char *mode = (flags & AKI_FILE_CREATE) ? "wb+" : "rb+";
#ifndef _WIN32
file->file = fopen(c_str, mode);
#else
diff --git a/src/util/file/util.c b/src/util/file/util.c
index e893de7..fe7785f 100644
--- a/src/util/file/util.c
+++ b/src/util/file/util.c
@@ -23,3 +23,13 @@ s32 aki_file_read_as_c_str(struct aki_file *file, char **out)
(*out)[size] = '\n';
return size;
}
+
+s32 aki_file_replace(struct aki_file *file, str *buf)
+{
+ if (aki_file_seek(file, 0, SEEK_SET) == (off_t)-1 ||
+ !aki_file_write(file, buf->data, buf->len) ||
+ !aki_file_truncate(file, buf->len)) {
+ return -1;
+ }
+ return buf->len;
+}