From 751373e0e442a93f3de6c8bda71f6d9c9c6a4579 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Thu, 16 Dec 2021 13:47:46 +0800 Subject: [PATCH] add open to utils --- cfileop.cpp | 10 ++++++++++ cfileop.h | 10 ++++++++++ fileop.cpp | 27 +++++++++++++++++++++++++++ fileop.h | 10 ++++++++++ 4 files changed, 57 insertions(+) diff --git a/cfileop.cpp b/cfileop.cpp index 795e354..8aeb2e6 100644 --- a/cfileop.cpp +++ b/cfileop.cpp @@ -1,6 +1,7 @@ #include "cfileop.h" #include "fileop.h" #include "cpp2c.h" +#include int fileop_exists(const char* fn) { if (!fn) return 0; @@ -39,3 +40,12 @@ int fileop_parse_size(const char* size, size_t* fs, int is_byte) { if (re) *fs = tmp; return re ? 1 : 0; } + +int fileop_open(const char* fn, int* fd, int oflag, int shflag, int pmode) { + if (!fn || !fd) return EINVAL; + int tfd; + if (!shflag) shflag = 0x10; + int re = fileop::open(fn, tfd, oflag, shflag, pmode); + *fd = tfd; + return re; +} diff --git a/cfileop.h b/cfileop.h index 7b6d259..3fd8b04 100644 --- a/cfileop.h +++ b/cfileop.h @@ -43,6 +43,16 @@ char* fileop_basename(const char* fn); * @return 1 if successed otherwise 0 */ int fileop_parse_size(const char* size, size_t* fs, int is_byte); +/** + * @brief Opens a file. + * @param fn File name. + * @param fd file descriptor. -1 if error occured. + * @param oflag The kind of operations allowed. + * @param shflag The kind of sharing allowed. (Windows Only) 0 will be replace with 0x10. + * @param pmode Permission mode. (Windows Only) + * @return errno +*/ +int fileop_open(const char* fn, int* fd, int oflag, int shflag, int pmode); #ifdef __cplusplus } #endif diff --git a/fileop.cpp b/fileop.cpp index fa76242..da95347 100644 --- a/fileop.cpp +++ b/fileop.cpp @@ -9,7 +9,9 @@ #include #else #include +#include #endif +#include #include "err.h" #include "wchar_util.h" #include @@ -46,6 +48,10 @@ bool remove_internal(wchar_t* fn, bool print_error) { return !ret; } +int open_internal(wchar_t* fn, int* fd, int oflag, int shflag, int pmode) { + return _wsopen_s(fd, fn, oflag, shflag, pmode); +} + template T fileop_internal(const char* fname, UINT codePage, T(*callback)(wchar_t* fn, Args... args), T failed, Args... args) { int wlen; @@ -176,3 +182,24 @@ bool fileop::parse_size(std::string size, size_t& fs, bool is_byte) { } return true; } + +int fileop::open(std::string fn, int& fd, int oflag, int shflag, int pmode) { +#if _WIN32 + UINT cp[] = { CP_UTF8, CP_OEMCP, CP_ACP }; + int i; + int tmfd; + int err; + for (i = 0; i < 3; i++) { + if (!fileop_internal(fn.c_str(), cp[i], &open_internal, EINVAL, &tmfd, oflag, shflag, pmode)) { + fd = tmfd; + return 0; + } + } + err = ::_sopen_s(&tmfd, fn.c_str(), oflag, shflag, pmode); + fd = tmfd; + return fd == -1 ? err : 0; +#else + fd = ::open(fn.c_str(), oflag); + return fd == -1 ? errno : 0; +#endif +} diff --git a/fileop.h b/fileop.h index 6b165a9..d984431 100644 --- a/fileop.h +++ b/fileop.h @@ -42,5 +42,15 @@ namespace fileop { * @return true if successed. */ bool parse_size(std::string size, size_t& fs, bool is_byte = true); + /** + * @brief Opens a file. + * @param fn File name. + * @param fd file descriptor. -1 if error occured. + * @param oflag The kind of operations allowed. + * @param shflag The kind of sharing allowed. (Windows Only) + * @param pmode Permission mode. (Windows Only) + * @return errno + */ + int open(std::string fn, int& fd, int oflag, int shflag = 0x10, int pmode = 0); } #endif