// vim:fileencoding=utf-8:foldmethod=marker #include "file_posix.h" #include "../../../common/platform/platform.h" #ifdef WP_PLATFORM_POSIX #include "../file.h" #include "../../cpath/cpath.h" #include "../../../common/aliases/aliases.h" #include "../../../base/array/array.h" #include "../../../base/strings/str8/str8.h" #ifdef WP_PLATFORM_APPLE #define _FILE_OFFSET_BITS 64 #define lseek64 lseek #endif // !WP_PLATFORM_APPLE #define __USE_LARGEFILE64 #include #include #include wp_intern i32 file_flags[COUNT_FILE_ACCESS_MODE] = { [WP_ACCESS_READ] = O_RDONLY, [WP_ACCESS_WRITE] = O_WRONLY | O_CREAT, [WP_ACCESS_APPEND] = O_WRONLY | O_APPEND | O_CREAT, [WP_ACCESS_READ_EX] = O_RDWR, [WP_ACCESS_WRITE_EX] = O_RDWR | O_CREAT, [WP_ACCESS_APPEND_EX] = O_RDWR | O_APPEND | O_CREAT, [WP_ACCESS_WRITE_FAIL_ON_EXIST] = O_WRONLY | O_CREAT | O_EXCL, [WP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = O_RDWR | O_CREAT | O_EXCL, }; wp_intern mode_t file_modes[COUNT_FILE_ACCESS_MODE] = { [WP_ACCESS_READ] = 0, [WP_ACCESS_WRITE] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, [WP_ACCESS_APPEND] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, [WP_ACCESS_READ_EX] = 0, [WP_ACCESS_WRITE_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, [WP_ACCESS_APPEND_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, [WP_ACCESS_WRITE_FAIL_ON_EXIST] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, [WP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, }; wp_intern i32 file_seek_origins[COUNT_FILE_SEEK_ORIGIN] = { [WP_SEEK_START] = SEEK_SET, [WP_SEEK_CURRENT] = SEEK_CUR, [WP_SEEK_END] = SEEK_END, }; WpFile *wpFileStdin(void) { wp_persist WpFile _stdin = { .fd = STDIN_FILENO }; return &_stdin; } WpFile *wpFileStdout(void) { wp_persist WpFile _stdout = { .fd = STDOUT_FILENO }; return &_stdout; } WpFile *wpFileStderr(void) { wp_persist WpFile _stderr = { .fd = STDERR_FILENO }; return &_stderr; } WpFile *_fileOpen(const WpAllocator *allocator, WpStr8RO *filepath, WpFileAccessMode mode) { wp_persist c8 tmp[WP_PATH_MAX] = {0}; memset(tmp, 0, WP_PATH_MAX); memcpy(tmp, filepath->buf, filepath->size); i32 fd = open((const char *)tmp, file_flags[mode], file_modes[mode]); if (fd < 0) { return NULL; } WpFile *output = wpMemAllocatorAlloc(allocator, sizeof(WpFile)); if (output) { output->fd = fd; } return output; } i64 _fileSeek(WpFile *file, i64 offset, WpFileSeekOrigin origin) { return lseek64(file->fd, offset, file_seek_origins[origin]); } u64 _fileRead(void *dst_buf, u64 byte_count, WpFile *file, u64 file_length) { u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count; i64 count = read(file->fd, dst_buf, copy_byte_count); if (count < 0) { return 0; } return count; } i64 _fileWrite(const void *src_buf, WpFile *file, u64 byte_count) { return write(file->fd, src_buf, byte_count); } i32 _fileFlush(WpFile *file) { return fsync(file->fd); } i32 _fileClose(WpFile *file) { return close(file->fd); } i32 _fileRename(WpStr8RO *old_filepath, WpStr8RO *new_filepath) { wp_persist c8 old_tmp[WP_PATH_MAX] = {0}; wp_persist c8 new_tmp[WP_PATH_MAX] = {0}; memset(old_tmp, 0, WP_PATH_MAX); memcpy(old_tmp, old_filepath->buf, old_filepath->size); memset(new_tmp, 0, WP_PATH_MAX); memcpy(new_tmp, new_filepath->buf, new_filepath->size); i32 link_result = link((const char *)old_tmp, (const char *)new_tmp); if (link_result == 0) { _fileRemove(old_filepath); } return link_result; } i32 _fileRemove(WpStr8RO *filepath) { wp_persist c8 tmp[WP_PATH_MAX] = {0}; memset(tmp, 0, WP_PATH_MAX); memcpy(tmp, filepath->buf, filepath->size); return unlink((const char *)tmp); } #endif // !WP_PLATFORM_POSIX