feature: implement linux directory handling functions
This commit is contained in:
parent
d56466526b
commit
05f5933111
2 changed files with 167 additions and 1 deletions
160
Source/DrangPlatform/Source/linux/fs/dir.c
Normal file
160
Source/DrangPlatform/Source/linux/fs/dir.c
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#include "drang/alloc.h"
|
||||
#include "errno_convert.h"
|
||||
#include "internal.h"
|
||||
#include <drang/error.h>
|
||||
#include <drang/fs.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int drang_fs_mkdir(const char *path, drang_fs_permissions_t permissions)
|
||||
{
|
||||
DRANG_BEGIN_TRY()
|
||||
DRANG_FAIL_IF_NULL(path, DRANG_EINVAL);
|
||||
|
||||
int mode = 0;
|
||||
if (permissions & DRANG_FS_PERM_USER_READ)
|
||||
mode |= S_IRUSR;
|
||||
if (permissions & DRANG_FS_PERM_USER_WRITE)
|
||||
mode |= S_IWUSR;
|
||||
if (permissions & DRANG_FS_PERM_USER_EXEC)
|
||||
mode |= S_IXUSR;
|
||||
if (permissions & DRANG_FS_PERM_GROUP_READ)
|
||||
mode |= S_IRGRP;
|
||||
if (permissions & DRANG_FS_PERM_GROUP_WRITE)
|
||||
mode |= S_IWGRP;
|
||||
if (permissions & DRANG_FS_PERM_GROUP_EXEC)
|
||||
mode |= S_IXGRP;
|
||||
if (permissions & DRANG_FS_PERM_OTHER_READ)
|
||||
mode |= S_IROTH;
|
||||
if (permissions & DRANG_FS_PERM_OTHER_WRITE)
|
||||
mode |= S_IWOTH;
|
||||
if (permissions & DRANG_FS_PERM_OTHER_EXEC)
|
||||
mode |= S_IXOTH;
|
||||
|
||||
if (mkdir(path, mode) != 0) {
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
}
|
||||
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
||||
int drang_fs_rmdir(const char *path)
|
||||
{
|
||||
DRANG_BEGIN_TRY()
|
||||
DRANG_FAIL_IF_NULL(path, DRANG_EINVAL);
|
||||
if (rmdir(path) != 0) {
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
}
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
||||
int drang_fs_opendir(const char *path, drang_fs_directory_t **out_directory)
|
||||
{
|
||||
struct drang_fs_directory *fs_dir = NULL;
|
||||
DIR *dir = NULL;
|
||||
DRANG_BEGIN_TRY()
|
||||
DRANG_FAIL_IF_NULL(path, DRANG_EINVAL);
|
||||
DRANG_FAIL_IF_NULL(out_directory, DRANG_EINVAL);
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
}
|
||||
|
||||
fs_dir = DRANG_TRY_ALLOC_T(struct drang_fs_directory);
|
||||
|
||||
fs_dir->dir = dir;
|
||||
|
||||
DRANG_RETURN_IN(out_directory, fs_dir);
|
||||
|
||||
DRANG_CATCH(_)
|
||||
{
|
||||
if (dir) {
|
||||
closedir(dir);
|
||||
}
|
||||
drang_free(fs_dir);
|
||||
}
|
||||
DRANG_END_TRY()
|
||||
}
|
||||
|
||||
int drang_fs_readdir(drang_fs_directory_t *directory, drang_fs_dir_entry_t *out_entry)
|
||||
{
|
||||
struct dirent *entry = NULL;
|
||||
DRANG_BEGIN_TRY()
|
||||
|
||||
entry = readdir(directory->dir);
|
||||
|
||||
DRANG_CHECK(entry != NULL, DRANG_ENOENT);
|
||||
|
||||
while (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
|
||||
entry = readdir(directory->dir);
|
||||
DRANG_CHECK(entry != NULL, DRANG_ENOENT);
|
||||
}
|
||||
|
||||
strncpy(out_entry->name, entry->d_name, DRANG_FS_MAX_REL_PATH_SIZE);
|
||||
out_entry->name[DRANG_FS_MAX_REL_PATH_SIZE - 1] = '\0';
|
||||
switch (entry->d_type) {
|
||||
case DT_REG:
|
||||
out_entry->type = drang_fs_type_file;
|
||||
break;
|
||||
case DT_DIR:
|
||||
out_entry->type = drang_fs_type_directory;
|
||||
break;
|
||||
case DT_LNK:
|
||||
out_entry->type = drang_fs_type_symlink;
|
||||
break;
|
||||
default:
|
||||
out_entry->type = drang_fs_type_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
||||
int drang_fs_closedir(drang_fs_directory_t *directory)
|
||||
{
|
||||
DRANG_BEGIN_TRY()
|
||||
DRANG_FAIL_IF_NULL(directory, DRANG_EINVAL);
|
||||
if (closedir(directory->dir) != 0) {
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
}
|
||||
|
||||
drang_free(directory);
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
||||
int drang_fs_get_cwd(char *buffer, size_t size, size_t *out_size)
|
||||
{
|
||||
DRANG_BEGIN_TRY()
|
||||
DRANG_FAIL_IF_NULL(buffer, DRANG_EINVAL);
|
||||
if (getcwd(buffer, size) != NULL) {
|
||||
DRANG_RETURN_IN(out_size, strlen(buffer));
|
||||
}
|
||||
|
||||
if (errno == ERANGE) {
|
||||
if (out_size) {
|
||||
long required_size = pathconf(".", _PC_PATH_MAX);
|
||||
*out_size = required_size;
|
||||
}
|
||||
DRANG_FAIL(DRANG_ENOMEM);
|
||||
}
|
||||
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
|
||||
|
||||
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
||||
int drang_fs_set_cwd(const char *path)
|
||||
{
|
||||
DRANG_BEGIN_TRY()
|
||||
|
||||
if (chdir(path) != 0) {
|
||||
DRANG_FAIL(drang_errno_to_error(errno));
|
||||
}
|
||||
|
||||
DRANG_END_TRY_IGNORE()
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include "linux/sync/internal.h"
|
||||
#include <drang/fs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#define DRANG_LINUX_FS_BUFFER_SIZE (4096)
|
||||
|
||||
struct drang_fs_file
|
||||
|
|
@ -11,3 +11,9 @@ struct drang_fs_file
|
|||
drang_fs_mode_t mode;
|
||||
struct drang_rwlock lock;
|
||||
};
|
||||
|
||||
|
||||
struct drang_fs_directory
|
||||
{
|
||||
DIR* dir;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue