summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2023-09-15 22:09:46 +0200
committerMitya Selivanov <automainint@guattari.tech>2023-09-15 22:09:46 +0200
commit94c01870418373c93744b73d29ebc74986cedd5c (patch)
tree1635e46a41fba46f5a632d8b594da901f8afe871 /source
parentbdcfa4e239d2c913c7045d0aa835ddd5a47e5436 (diff)
downloadkit-94c01870418373c93744b73d29ebc74986cedd5c.zip
file mapping
Diffstat (limited to 'source')
-rw-r--r--source/kit/async_function.h14
-rw-r--r--source/kit/file.c234
-rw-r--r--source/kit/file.h46
-rw-r--r--source/kit/kit_test.h4
-rw-r--r--source/kit/shared_memory.h11
-rw-r--r--source/kit/shared_memory.posix.c36
-rw-r--r--source/kit/shared_memory.win32.c23
-rw-r--r--source/kit/status.h40
-rw-r--r--source/tests/file.test.c76
-rw-r--r--source/tests/test_interprocess.c2
10 files changed, 400 insertions, 86 deletions
diff --git a/source/kit/async_function.h b/source/kit/async_function.h
index 4e725e7..e94fc31 100644
--- a/source/kit/async_function.h
+++ b/source/kit/async_function.h
@@ -35,16 +35,16 @@ typedef struct {
#define KIT_AF_INTERNAL(coro_) (*((kit_af_type_void *) (coro_)))
#ifdef KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH
-/* Application should implement this function if custom async
- * function dispatch is enabled.
- *
- * See KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH macro.
- */
+// Application should implement this function if custom async
+// function dispatch is enabled.
+//
+// See KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH macro.
+//
void kit_async_function_dispatch(void *promise);
#else
static void kit_async_function_dispatch(void *promise) {
- /* Dynamic dispatch by default.
- */
+ // Dynamic dispatch by default.
+ //
KIT_AF_INTERNAL(promise)._state_machine(promise);
}
#endif
diff --git a/source/kit/file.c b/source/kit/file.c
index c82ef35..7b80e67 100644
--- a/source/kit/file.c
+++ b/source/kit/file.c
@@ -7,19 +7,21 @@
enum { PATH_BUF_SIZE = 4096 };
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <stdint.h>
-
# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN 1
+# define WIN32_LEAN_AND_MEAN
# endif
-
-# include <Windows.h>
-
-# include <Shlwapi.h>
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include <windows.h>
+# include <shlwapi.h>
#else
# include <dirent.h>
+# include <sys/mman.h>
# include <sys/stat.h>
+# include <fcntl.h>
# include <unistd.h>
+# include <limits.h>
#endif
#ifdef __APPLE__
@@ -227,7 +229,7 @@ kit_str_t kit_path_take(kit_str_t path, i64 count) {
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-static void win32_prepare_path_(WCHAR *buf, kit_str_t path) {
+static void kit_win32_prepare_path_(WCHAR *buf, kit_str_t path) {
assert(path.size == 0 || path.values != NULL);
assert(path.size + 5 < PATH_BUF_SIZE);
@@ -246,9 +248,9 @@ static void win32_prepare_path_(WCHAR *buf, kit_str_t path) {
}
# define PREPARE_PATH_BUF_ \
WCHAR buf[PATH_BUF_SIZE]; \
- win32_prepare_path_(buf, path)
+ kit_win32_prepare_path_(buf, path)
#else
-static void unix_prepare_path_(char *buf, kit_str_t path) {
+static void kit_unix_prepare_path_(char *buf, kit_str_t path) {
assert(path.size == 0 || path.values != NULL);
assert(path.size + 1 < PATH_BUF_SIZE);
@@ -258,20 +260,20 @@ static void unix_prepare_path_(char *buf, kit_str_t path) {
}
# define PREPARE_PATH_BUF_ \
char buf[PATH_BUF_SIZE]; \
- unix_prepare_path_(buf, path)
+ kit_unix_prepare_path_(buf, path)
#endif
-kit_status_t kit_file_create_folder(kit_str_t path) {
+kit_status_t kit_folder_create(kit_str_t path) {
PREPARE_PATH_BUF_;
#if defined(_WIN32) && !defined(__CYGWIN__)
return CreateDirectoryW(buf, NULL) ? KIT_OK
: KIT_ERROR_MKDIR_FAILED;
#else
- return mkdir(buf, 0755) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED;
+ return mkdir(buf, 0775) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED;
#endif
}
-kit_status_t kit_file_create_folder_recursive(kit_str_t path) {
+kit_status_t kit_folder_create_recursive(kit_str_t path) {
i64 i;
for (i = 0;; i++) {
@@ -280,7 +282,7 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t path) {
if (type == KIT_PATH_FILE)
return KIT_ERROR_FILE_ALREADY_EXISTS;
if (type == KIT_PATH_NONE) {
- kit_status_t s = kit_file_create_folder(part);
+ kit_status_t s = kit_folder_create(part);
if (s != KIT_OK)
return s;
}
@@ -300,7 +302,7 @@ kit_status_t kit_file_remove(kit_str_t path) {
#endif
}
-kit_status_t kit_file_remove_folder(kit_str_t path) {
+kit_status_t kit_folder_remove(kit_str_t path) {
PREPARE_PATH_BUF_;
#if defined(_WIN32) && !defined(__CYGWIN__)
return RemoveDirectoryW(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED;
@@ -315,27 +317,41 @@ kit_status_t kit_file_remove_recursive(kit_str_t path,
i64 i;
switch (type) {
- case KIT_PATH_FILE: return kit_file_remove(path);
+ case KIT_PATH_FILE: {
+ kit_status_t s = kit_file_remove(path);
+ assert(s == KIT_OK);
+ return s;
+ }
case KIT_PATH_FOLDER: {
- kit_path_list_t list = kit_file_enum_folder(path, alloc);
+ kit_path_list_t list = kit_folder_enum(path, alloc);
+
+ assert(list.status == KIT_OK);
if (list.status != KIT_OK) {
kit_path_list_destroy(list);
return list.status;
}
+
for (i = 0; i < list.files.size; i++) {
- str_t s = { .size = list.files.values[i].size,
- .values = list.files.values[i].values };
- kit_file_remove_recursive(s, alloc);
+ str_builder_t full_path = kit_path_join(
+ path, WRAP_STR(list.files.values[i]), alloc);
+ kit_status_t s = kit_file_remove_recursive(
+ WRAP_STR(full_path), alloc);
+ DA_DESTROY(full_path);
+ assert(s == KIT_OK);
}
+
kit_path_list_destroy(list);
- return kit_file_remove_folder(path);
+
+ kit_status_t s = kit_folder_remove(path);
+ assert(s == KIT_OK);
+ return s;
}
default:;
}
- return KIT_ERROR_FILE_DO_NOT_EXIST;
+ return KIT_ERROR_FILE_DOES_NOT_EXIST;
}
kit_path_type_t kit_path_type(kit_str_t path) {
@@ -393,8 +409,8 @@ kit_file_info_t kit_file_info(kit_str_t path) {
if (stat(buf, &info) == 0 && S_ISREG(info.st_mode)) {
result.size = (i64) info.st_size;
# ifndef st_mtime
- /* No support for nanosecond timestamps.
- */
+ // No support for nanosecond timestamps.
+ //
result.time_modified_sec = (i64) info.st_mtime;
# else
result.time_modified_sec = (i64) info.st_mtim.tv_sec;
@@ -405,12 +421,12 @@ kit_file_info_t kit_file_info(kit_str_t path) {
}
#endif
- result.status = KIT_ERROR_FILE_DO_NOT_EXIST;
+ result.status = KIT_ERROR_FILE_DOES_NOT_EXIST;
return result;
}
-kit_path_list_t kit_file_enum_folder(kit_str_t path,
- kit_allocator_t *alloc) {
+kit_path_list_t kit_folder_enum(kit_str_t path,
+ kit_allocator_t *alloc) {
PREPARE_PATH_BUF_;
kit_path_list_t result = { .status = KIT_OK };
@@ -499,3 +515,165 @@ void kit_path_list_destroy(kit_path_list_t list) {
DA_DESTROY(list.files.values[i]);
DA_DESTROY(list.files);
}
+
+kit_mapped_file_t kit_file_map(kit_str_t path, i64 size, i32 mode) {
+ assert(size > 0);
+ assert(path.size > 0);
+ assert(path.size <= PATH_MAX);
+ assert(path.values != NULL);
+
+ kit_mapped_file_t mf;
+ memset(&mf, 0, sizeof mf);
+
+ if (size <= 0) {
+ mf.status = KIT_ERROR_INVALID_SIZE;
+ return mf;
+ }
+
+ if (path.size <= 0) {
+ mf.status = KIT_ERROR_INVALID_ARGUMENT;
+ return mf;
+ }
+
+ if (path.size > PATH_MAX) {
+ mf.status = KIT_ERROR_PATH_TOO_LONG;
+ return mf;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char buf[MAX_PATH + 1];
+ memcpy(buf, path.values, path.size);
+ buf[path.size] = '\0';
+
+ HANDLE file = CreateFileA(
+ buf, GENERIC_READ | GENERIC_WRITE,
+ mode == FILE_MAP_SHARED ? FILE_SHARE_READ | FILE_SHARE_WRITE
+ : 0,
+ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (file == INVALID_HANDLE_VALUE) {
+ mf.status = KIT_ERROR_OPEN_FAILED;
+ return mf;
+ }
+
+ LONG high = (LONG) (size >> 32);
+
+ if (SetFilePointer(file, (LONG) size, &high, FILE_BEGIN) ==
+ INVALID_SET_FILE_POINTER) {
+ CloseHandle(file);
+ assert(0);
+ mf.status = KIT_ERROR_TRUNCATE_FAILED;
+ return mf;
+ }
+
+ if (!SetEndOfFile(file)) {
+ CloseHandle(file);
+ assert(0);
+ mf.status = KIT_ERROR_TRUNCATE_FAILED;
+ return mf;
+ }
+
+ HANDLE map = CreateFileMappingA(file, NULL, PAGE_READWRITE,
+ (DWORD) (size >> 32), (DWORD) size,
+ NULL);
+
+ if (map == INVALID_HANDLE_VALUE) {
+ CloseHandle(file);
+ assert(0);
+ mf.status = KIT_ERROR_MAP_FAILED;
+ return mf;
+ }
+
+ void *p = MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0,
+ (SIZE_T) size);
+
+ if (p == NULL) {
+ CloseHandle(map);
+ CloseHandle(file);
+ assert(0);
+ mf.status = KIT_ERROR_MAP_FAILED;
+ return mf;
+ }
+
+ mf.status = KIT_OK;
+ mf.size = size;
+ mf.bytes = p;
+ mf._file = file;
+ mf._map = map;
+#else
+ char buf[PATH_MAX + 1];
+ memcpy(buf, path.values, path.size);
+ buf[path.size] = '\0';
+
+ i32 fd = open(buf, O_RDWR | O_CREAT, 0664);
+
+ if (fd == -1) {
+ mf.status = KIT_ERROR_OPEN_FAILED;
+ return mf;
+ }
+
+ if (ftruncate(fd, size) == -1) {
+ close(fd);
+ assert(0);
+ mf.status = KIT_ERROR_TRUNCATE_FAILED;
+ return mf;
+ }
+
+ void *p = mmap(
+ NULL, size, PROT_READ | PROT_WRITE,
+ mode == KIT_FILE_MAP_SHARED ? MAP_SHARED : MAP_PRIVATE, fd, 0);
+
+ if (p == MAP_FAILED) {
+ close(fd);
+ assert(0);
+ mf.status = KIT_ERROR_MAP_FAILED;
+ return mf;
+ }
+
+ mf.status = KIT_OK;
+ mf.size = size;
+ mf.bytes = (u8 *) p;
+ mf._fd = fd;
+#endif
+
+ return mf;
+}
+
+kit_status_t kit_file_sync(kit_mapped_file_t *mf) {
+ assert(mf != NULL);
+
+ if (mf == NULL)
+ return KIT_ERROR_INVALID_ARGUMENT;
+
+ kit_status_t status = KIT_OK;
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ if (msync(mf->bytes, mf->size, MS_SYNC) != 0)
+ status |= KIT_ERROR_SYNC_FAILED;
+#endif
+
+ return status;
+}
+
+kit_status_t kit_file_unmap(kit_mapped_file_t *mf) {
+ assert(mf != NULL);
+
+ if (mf == NULL)
+ return KIT_ERROR_INVALID_ARGUMENT;
+
+ kit_status_t status = KIT_OK;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!UnmapViewOfFile(mf->bytes))
+ status |= KIT_ERROR_UNMAP_FAILED;
+ if (!CloseHandle(mf->_map) || !CloseHandle(mf->_file))
+ status |= KIT_ERROR_CLOSE_FAILED;
+#else
+ if (munmap(mf->bytes, mf->size) != 0)
+ status |= KIT_ERROR_UNMAP_FAILED;
+ if (close(mf->_fd) != 0)
+ status |= KIT_ERROR_CLOSE_FAILED;
+#endif
+
+ return status;
+}
diff --git a/source/kit/file.h b/source/kit/file.h
index c0a8f23..b2e4f20 100644
--- a/source/kit/file.h
+++ b/source/kit/file.h
@@ -5,6 +5,8 @@
#include "status.h"
#include "string_builder.h"
+#include <stdio.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -28,6 +30,20 @@ typedef struct {
KIT_DA(kit_str_builder_t) files;
} kit_path_list_t;
+enum { KIT_FILE_MAP_PRIVATE, KIT_FILE_MAP_SHARED };
+
+typedef struct {
+ kit_status_t status;
+ i64 size;
+ u8 *bytes;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ void *_file;
+ void *_map;
+#else
+ int _fd;
+#endif
+} kit_mapped_file_t;
+
#if defined(_WIN32) && !defined(__CYGWIN__)
# define KIT_PATH_DELIM_C '\\'
# define KIT_PATH_DELIM "\\"
@@ -52,13 +68,13 @@ kit_str_t kit_path_index(kit_str_t path, i64 index);
kit_str_t kit_path_take(kit_str_t path, i64 count);
-kit_status_t kit_file_create_folder(kit_str_t path);
+kit_status_t kit_folder_create(kit_str_t path);
-kit_status_t kit_file_create_folder_recursive(kit_str_t path);
+kit_status_t kit_folder_create_recursive(kit_str_t path);
kit_status_t kit_file_remove(kit_str_t path);
-kit_status_t kit_file_remove_folder(kit_str_t path);
+kit_status_t kit_folder_remove(kit_str_t path);
kit_status_t kit_file_remove_recursive(kit_str_t path,
kit_allocator_t *alloc);
@@ -67,11 +83,15 @@ kit_path_type_t kit_path_type(kit_str_t path);
kit_file_info_t kit_file_info(kit_str_t path);
-kit_path_list_t kit_file_enum_folder(kit_str_t path,
- kit_allocator_t *alloc);
+kit_path_list_t kit_folder_enum(kit_str_t path,
+ kit_allocator_t *alloc);
void kit_path_list_destroy(kit_path_list_t list);
+kit_mapped_file_t kit_file_map(kit_str_t path, i64 size, i32 mode);
+kit_status_t kit_file_sync(kit_mapped_file_t *mf);
+kit_status_t kit_file_unmap(kit_mapped_file_t *mf);
+
#ifdef __cplusplus
}
#endif
@@ -83,19 +103,25 @@ void kit_path_list_destroy(kit_path_list_t list);
# define path_cache kit_path_cache
# define path_index kit_path_index
# define path_take kit_path_take
-# define file_create_folder kit_file_create_folder
-# define file_create_folder_recursive \
- kit_file_create_folder_recursive
+# define folder_create kit_folder_create
+# define folder_create_recursive kit_folder_create_recursive
# define file_remove kit_file_remove
-# define file_remove_folder kit_file_remove_folder
+# define folder_remove kit_folder_remove
# define file_remove_recursive kit_file_remove_recursive
# define path_type_t kit_path_type_t
# define path_type kit_path_type
# define file_info_t kit_file_info_t
# define file_info kit_file_info
# define path_list_t kit_path_list_t
-# define file_enum_folder kit_file_enum_folder
+# define folder_enum kit_folder_enum
# define path_list_destroy kit_path_list_destroy
+# define mapped_file_t kit_mapped_file_t
+# define file_map kit_file_map
+# define file_sync kit_file_sync
+# define file_unmap kit_file_unmap
+
+# define FILE_MAP_PRIVATE KIT_FILE_MAP_PRIVATE
+# define FILE_MAP_SHARED KIT_FILE_MAP_SHARED
# define PATH_DELIM_C KIT_PATH_DELIM_C
# define PATH_DELIM KIT_PATH_DELIM
diff --git a/source/kit/kit_test.h b/source/kit/kit_test.h
index f51516f..b6f43a6 100644
--- a/source/kit/kit_test.h
+++ b/source/kit/kit_test.h
@@ -672,7 +672,7 @@ int kit_run_tests(int argc, char **argv) {
no_color || kit_print_color_(kit_red_);
printf(" -> ");
no_color || kit_print_color_(kit_light_);
- printf("Got wrong value");
+ printf("Got wrong value ");
no_color || kit_print_color_(kit_white_);
printf("%10lld",
(long long) kit_tests_list.v[i].value[j]);
@@ -686,7 +686,7 @@ int kit_run_tests(int argc, char **argv) {
no_color || kit_print_color_(kit_green_);
printf(" -> ");
no_color || kit_print_color_(kit_light_);
- printf("Expected value ");
+ printf("Expected value ");
no_color || kit_print_color_(kit_white_);
printf("%10lld",
(long long) kit_tests_list.v[i].expected[j]);
diff --git a/source/kit/shared_memory.h b/source/kit/shared_memory.h
index fc9a082..594d4a4 100644
--- a/source/kit/shared_memory.h
+++ b/source/kit/shared_memory.h
@@ -20,7 +20,6 @@ typedef struct {
void *_handle;
#else
i8 _owned;
- i32 _fd;
char _name[NAME_MAX + 1];
#endif
} kit_shared_memory_t;
@@ -33,9 +32,19 @@ enum {
kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
i32 mode);
kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem);
+kit_status_t kit_shared_memory_clean(kit_str_t name);
#ifdef __cplusplus
}
#endif
+#ifndef KIT_DISABLE_SHORT_NAMES
+# define shared_memory_t kit_shared_memory_t
+# define shared_memory_open kit_shared_memory_open
+# define shared_memory_close kit_shared_memory_close
+
+# define SHARED_MEMORY_OPEN KIT_SHARED_MEMORY_OPEN
+# define SHARED_MEMORY_CREATE KIT_SHARED_MEMORY_CREATE
+#endif
+
#endif
diff --git a/source/kit/shared_memory.posix.c b/source/kit/shared_memory.posix.c
index 1695f14..edb8794 100644
--- a/source/kit/shared_memory.posix.c
+++ b/source/kit/shared_memory.posix.c
@@ -52,24 +52,26 @@ kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
mode == KIT_SHARED_MEMORY_CREATE ? 0660 : 0);
if (fd == -1) {
- mem.status = KIT_ERROR_SHM_OPEN_FAILED;
+ mem.status = KIT_ERROR_OPEN_FAILED;
return mem;
}
if (mode == KIT_SHARED_MEMORY_CREATE && ftruncate(fd, size) == -1) {
shm_unlink(mem._name);
assert(0);
- mem.status = KIT_ERROR_FTRUNCATE_FAILED;
+ mem.status = KIT_ERROR_TRUNCATE_FAILED;
return mem;
}
void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
0);
+ close(fd);
+
if (p == MAP_FAILED) {
shm_unlink(mem._name);
assert(0);
- mem.status = KIT_ERROR_MMAP_FAILED;
+ mem.status = KIT_ERROR_MAP_FAILED;
return mem;
}
@@ -77,7 +79,6 @@ kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
mem.size = size;
mem.bytes = (u8 *) p;
mem._owned = (mode == KIT_SHARED_MEMORY_CREATE);
- mem._fd = fd;
return mem;
}
@@ -90,10 +91,35 @@ kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
kit_status_t status = KIT_OK;
if (munmap(mem->bytes, mem->size) != 0)
- status |= KIT_ERROR_MUNMAP_FAILED;
+ status |= KIT_ERROR_UNMAP_FAILED;
if (mem->_owned && shm_unlink(mem->_name) != 0)
status |= KIT_ERROR_UNLINK_FAILED;
return status;
}
+
+kit_status_t kit_shared_memory_clean(kit_str_t name) {
+ assert(name.size > 0);
+ assert(name.size + 1 <= NAME_MAX);
+ assert(name.values != NULL);
+
+ if (name.size <= 0)
+ return KIT_ERROR_INVALID_NAME;
+
+ if (name.size + 1 > NAME_MAX)
+ return KIT_ERROR_NAME_TOO_LONG;
+
+ for (i64 i = 0; i < name.size; i++)
+ if (name.values[i] == '/' || name.values[i] == '\\')
+ return KIT_ERROR_INVALID_NAME;
+
+ char buf[NAME_MAX + 1] = "/";
+ memcpy(buf + 1, name.values, name.size);
+ buf[1 + name.size] = '\0';
+
+ if (shm_unlink(buf) != 0)
+ return KIT_ERROR_UNLINK_FAILED;
+
+ return KIT_OK;
+}
#endif
diff --git a/source/kit/shared_memory.win32.c b/source/kit/shared_memory.win32.c
index 5b5c1b0..73175b1 100644
--- a/source/kit/shared_memory.win32.c
+++ b/source/kit/shared_memory.win32.c
@@ -41,21 +41,23 @@ kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
buf[7 + name.size] = '\0';
HANDLE h = mode == KIT_SHARED_MEMORY_CREATE
- ? CreateFileMappingA(INVALID_HANDLE_VALUE, NULL,
- PAGE_READWRITE, 0, size, buf)
+ ? CreateFileMappingA(
+ INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+ (DWORD) (size >> 32), (DWORD) size, buf)
: OpenFileMappingA(FILE_MAP_ALL_ACCESS, 0, buf);
- if (h == NULL) {
- mem.status = KIT_ERROR_SHM_OPEN_FAILED;
+ if (h == INVALID_HANDLE_VALUE) {
+ mem.status = KIT_ERROR_OPEN_FAILED;
return mem;
}
- void *p = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, size);
+ void *p = MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0,
+ (SIZE_T) size);
assert(p != NULL);
if (p == NULL) {
CloseHandle(h);
- mem.status = KIT_ERROR_MMAP_FAILED;
+ mem.status = KIT_ERROR_MAP_FAILED;
return mem;
}
@@ -72,10 +74,17 @@ kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
i32 status = KIT_OK;
if (!UnmapViewOfFile(mem->bytes))
- status |= KIT_ERROR_MUNMAP_FAILED;
+ status |= KIT_ERROR_UNMAP_FAILED;
if (!CloseHandle(mem->_handle))
status |= KIT_ERROR_UNLINK_FAILED;
return status;
}
+
+kit_status_t kit_shared_memory_clean(kit_str_t name) {
+ // Do nothing.
+ //
+
+ return KIT_OK;
+}
#endif
diff --git a/source/kit/status.h b/source/kit/status.h
index 983e263..35139e3 100644
--- a/source/kit/status.h
+++ b/source/kit/status.h
@@ -5,25 +5,27 @@
enum {
KIT_OK = 0,
- KIT_ERROR_NOT_IMPLEMENTED = 1,
- KIT_ERROR_BAD_ALLOC = (1 << 1),
- KIT_ERROR_INVALID_ARGUMENT = (1 << 2),
- KIT_ERROR_MKDIR_FAILED = (1 << 3),
- KIT_ERROR_RMDIR_FAILED = (1 << 4),
- KIT_ERROR_UNLINK_FAILED = (1 << 5),
- KIT_ERROR_FILE_ALREADY_EXISTS = (1 << 6),
- KIT_ERROR_FILE_DO_NOT_EXIST = (1 << 7),
- KIT_ERROR_PATH_TOO_LONG = (1 << 8),
- KIT_ERROR_SOCKETS_STARTUP_FAILED = (1 << 9),
- KIT_ERROR_SOCKET_CONTROL_FAILED = (1 << 10),
- KIT_ERROR_NAME_TOO_LONG = (1 << 11),
- KIT_ERROR_INVALID_SIZE = (1 << 12),
- KIT_ERROR_INVALID_NAME = (1 << 13),
- KIT_ERROR_SHM_OPEN_FAILED = (1 << 14),
- KIT_ERROR_SHM_UNLINK_FAILED = (1 << 15),
- KIT_ERROR_FTRUNCATE_FAILED = (1 << 16),
- KIT_ERROR_MMAP_FAILED = (1 << 17),
- KIT_ERROR_MUNMAP_FAILED = (1 << 18),
+ KIT_ERROR_BAD_ALLOC = 1,
+ KIT_ERROR_INVALID_ARGUMENT = (1 << 1),
+ KIT_ERROR_MKDIR_FAILED = (1 << 2),
+ KIT_ERROR_RMDIR_FAILED = (1 << 3),
+ KIT_ERROR_UNLINK_FAILED = (1 << 4),
+ KIT_ERROR_FILE_ALREADY_EXISTS = (1 << 5),
+ KIT_ERROR_FILE_DOES_NOT_EXIST = (1 << 6),
+ KIT_ERROR_PATH_TOO_LONG = (1 << 7),
+ KIT_ERROR_SOCKETS_STARTUP_FAILED = (1 << 8),
+ KIT_ERROR_SOCKET_CONTROL_FAILED = (1 << 9),
+ KIT_ERROR_NAME_TOO_LONG = (1 << 10),
+ KIT_ERROR_INVALID_SIZE = (1 << 11),
+ KIT_ERROR_INVALID_NAME = (1 << 12),
+ KIT_ERROR_INVALID_PATH = (1 << 13),
+ KIT_ERROR_OPEN_FAILED = (1 << 14),
+ KIT_ERROR_TRUNCATE_FAILED = (1 << 15),
+ KIT_ERROR_MAP_FAILED = (1 << 16),
+ KIT_ERROR_UNMAP_FAILED = (1 << 17),
+ KIT_ERROR_SYNC_FAILED = (1 << 18),
+ KIT_ERROR_CLOSE_FAILED = (1 << 19),
+ KIT_ERROR_NOT_IMPLEMENTED = (1 << 30),
};
typedef i32 kit_status_t;
diff --git a/source/tests/file.test.c b/source/tests/file.test.c
index e6071a1..2a37c07 100644
--- a/source/tests/file.test.c
+++ b/source/tests/file.test.c
@@ -1,6 +1,5 @@
#include "../kit/file.h"
#include "../kit/string_ref.h"
-#include <string.h>
#define KIT_TEST_FILE file
#include "../kit/kit_test.h"
@@ -205,16 +204,79 @@ TEST("file path take windows disk name") {
REQUIRE(AR_EQUAL(path_take(foobar, 2), bar));
}
-TEST("file create folder") { }
+TEST("file create folder") {
+ str_t folder_name = SZ("test_folder");
-TEST("file create folder recursive") { }
+ REQUIRE_EQ(folder_create(folder_name), KIT_OK);
+ REQUIRE_EQ(path_type(folder_name), PATH_FOLDER);
+ REQUIRE_EQ(folder_remove(folder_name), KIT_OK);
+ REQUIRE_EQ(path_type(folder_name), PATH_NONE);
+}
+
+TEST("file create folder recursive") {
+ REQUIRE_EQ(folder_create_recursive(
+ SZ("test_folder" PATH_DELIM "foo" PATH_DELIM "bar")),
+ KIT_OK);
+ REQUIRE_EQ(path_type(SZ("test_folder")), PATH_FOLDER);
+ REQUIRE_EQ(path_type(SZ("test_folder" PATH_DELIM "foo")),
+ PATH_FOLDER);
+ REQUIRE_EQ(
+ path_type(SZ("test_folder" PATH_DELIM "foo" PATH_DELIM "bar")),
+ PATH_FOLDER);
+ REQUIRE_EQ(file_remove_recursive(SZ("test_folder"), NULL), KIT_OK);
+ REQUIRE_EQ(path_type(SZ("test_folder")), PATH_NONE);
+}
+
+TEST("file remove") {
+ FILE *f = fopen("test_file", "wb");
+ fclose(f);
+
+ REQUIRE_EQ(path_type(SZ("test_file")), PATH_FILE);
+ REQUIRE_EQ(file_remove(SZ("test_file")), KIT_OK);
+ REQUIRE_EQ(path_type(SZ("test_file")), PATH_NONE);
+ REQUIRE_EQ(file_remove(SZ("unexisted_file_foo_bar")),
+ KIT_ERROR_UNLINK_FAILED);
+}
+
+TEST("file map read") {
+ char buf[] = "bar";
-TEST("file remove") { }
+ FILE *f = fopen("foo", "wb");
+ fwrite(buf, 1, 3, f);
+ fclose(f);
-TEST("file remove folder") { }
+ mapped_file_t mf = file_map(SZ("foo"), 3, FILE_MAP_PRIVATE);
-TEST("file remove recursive") { }
+ REQUIRE_EQ(mf.status, KIT_OK);
+ if (mf.status == KIT_OK) {
+ REQUIRE_EQ(memcmp(buf, mf.bytes, 3), 0);
+ file_unmap(&mf);
+ }
-TEST("file enum folder") { }
+ file_remove(SZ("foo"));
+}
+
+TEST("file map write") {
+ mapped_file_t mf = file_map(SZ("foo"), 3, FILE_MAP_SHARED);
+
+ REQUIRE_EQ(mf.status, KIT_OK);
+ if (mf.status == KIT_OK) {
+ memcpy(mf.bytes, "bar", 3);
+ file_unmap(&mf);
+
+ char buf[3];
+ FILE *f = fopen("foo", "rb");
+ i64 n = (i64) fread(buf, 1, 3, f);
+ REQUIRE_EQ(n, 3);
+ fclose(f);
+
+ if (n == 3) {
+ printf("READ: %d %d %d \n", buf[0], buf[1], buf[2]);
+ REQUIRE_EQ(memcmp(buf, "bar", 3), 0);
+ }
+
+ file_remove(SZ("foo"));
+ }
+}
#undef KIT_TEST_FILE
diff --git a/source/tests/test_interprocess.c b/source/tests/test_interprocess.c
index a69dd02..cf33086 100644
--- a/source/tests/test_interprocess.c
+++ b/source/tests/test_interprocess.c
@@ -10,6 +10,8 @@ enum { DATA_SIZE = 64 };
enum { STATE_INIT, STATE_READY, STATE_DONE };
int run_writer() {
+ kit_shared_memory_clean(SZ(NAME));
+
kit_shared_memory_t mem = kit_shared_memory_open(
SZ(NAME), DATA_SIZE, KIT_SHARED_MEMORY_CREATE);