From 3a8174ece3894c990b6b16414b45930c2504e292 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Sat, 16 Mar 2024 22:51:28 +0800 Subject: [PATCH 01/22] Add conditional compiling with ACL_DBUF_HOOK_NEW. --- .../include/acl_cpp/stdlib/dbuf_pool.hpp | 26 ++++++++++-------- lib_acl_cpp/samples/dbuf/dbuf3/main.cpp | 4 +++ lib_acl_cpp/src/redis/redis_command.cpp | 5 ++++ lib_acl_cpp/src/stdlib/dbuf_pool.cpp | 27 ++++++++++++++++--- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp b/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp index 692295039..ba079545e 100644 --- a/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp +++ b/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp @@ -5,8 +5,7 @@ struct ACL_DBUF_POOL; -namespace acl -{ +namespace acl { /** * 会话类的内存链管理类,该类仅提供内存分配函数,在整个类对象被析构时该内存链 @@ -14,13 +13,18 @@ namespace acl * 该类实际上是封装了 lib_acl 中的 ACL_DBUF_POOL 结构及方法 */ -class ACL_CPP_API dbuf_pool // : public noncopyable -{ +#if 0 +#ifndef ACL_DBUF_HOOK_NEW +# define ACL_DBUF_HOOK_NEW +#endif +#endif + +class ACL_CPP_API dbuf_pool { // : public noncopyable public: /** * 该类对象必须动态创建 */ - dbuf_pool(); + dbuf_pool(size_t nblock = 2); /** * 该类对象必须要动态创建,所以隐藏了析构函数,使用者需要调用 destroy @@ -28,6 +32,7 @@ public: */ void destroy(); +#ifdef ACL_DBUF_HOOK_NEW /** * 重载 new/delete 操作符,使 dbuf_pool 对象本身也创建在内存池上, * 从而减少了 malloc/free 的次数 @@ -36,10 +41,11 @@ public: */ static void *operator new(size_t size, size_t nblock = 2); -#if defined(_WIN32) || defined(_WIN64) +# if defined(_WIN32) || defined(_WIN64) static void operator delete(void* ptr, size_t); -#endif +# endif static void operator delete(void* ptr); +#endif // ACL_DBUF_HOOK_NEW /** * 重置内存池的状态以便于重复使用该内存池对象 @@ -158,8 +164,7 @@ class dbuf_guard; /** * 在会话内存池对象上分配的对象基础类 */ -class ACL_CPP_API dbuf_obj //: public noncopyable -{ +class ACL_CPP_API dbuf_obj { //: public noncopyable public: /** * 构造函数 @@ -207,8 +212,7 @@ private: * 会话内存池管理器,由该类对象管理 dbuf_pool 对象及在其上分配的对象,当该类 * 对象销毁时,dbuf_pool 对象及在上面均被释放。 */ -class ACL_CPP_API dbuf_guard // : public noncopyable -{ +class ACL_CPP_API dbuf_guard { // : public noncopyable public: /** * 构造函数 diff --git a/lib_acl_cpp/samples/dbuf/dbuf3/main.cpp b/lib_acl_cpp/samples/dbuf/dbuf3/main.cpp index 2149d952b..804e57b01 100644 --- a/lib_acl_cpp/samples/dbuf/dbuf3/main.cpp +++ b/lib_acl_cpp/samples/dbuf/dbuf3/main.cpp @@ -40,7 +40,11 @@ int main(int argc, char* argv[]) acl::log::stdout_open(true); +#ifdef ACL_DBUF_HOOK_NEW acl::dbuf_pool* dbuf = new (100) acl::dbuf_pool; +#else + acl::dbuf_pool* dbuf = new acl::dbuf_pool(100); +#endif for (int i = 0; i < 102400; i++) dbuf->dbuf_alloc(10); diff --git a/lib_acl_cpp/src/redis/redis_command.cpp b/lib_acl_cpp/src/redis/redis_command.cpp index b76e590bc..8bf76bf4b 100644 --- a/lib_acl_cpp/src/redis/redis_command.cpp +++ b/lib_acl_cpp/src/redis/redis_command.cpp @@ -41,7 +41,12 @@ void redis_command::init(void) addr_[0] = 0; #define REDIS_DBUF_NBLOCK 1 + +#ifdef ACL_DBUF_HOOK_NEW dbuf_ = new (REDIS_DBUF_NBLOCK) dbuf_pool(); +#else + dbuf_ = new dbuf_pool(REDIS_DBUF_NBLOCK); +#endif } redis_command::redis_command(void) diff --git a/lib_acl_cpp/src/stdlib/dbuf_pool.cpp b/lib_acl_cpp/src/stdlib/dbuf_pool.cpp index 511a8b514..dd925fcd2 100644 --- a/lib_acl_cpp/src/stdlib/dbuf_pool.cpp +++ b/lib_acl_cpp/src/stdlib/dbuf_pool.cpp @@ -7,12 +7,21 @@ namespace acl { -dbuf_pool::dbuf_pool(void) +dbuf_pool::dbuf_pool(size_t nblock /* = 2 */) { +#ifdef ACL_DBUF_HOOK_NEW + (void) nblock; +#else + pool_ = acl_dbuf_pool_create(4096 * nblock); + mysize_ = sizeof(dbuf_pool); +#endif } dbuf_pool::~dbuf_pool(void) { +#ifndef ACL_DBUF_HOOK_NEW + acl_dbuf_pool_destroy(pool_); +#endif } void dbuf_pool::destroy(void) @@ -20,6 +29,8 @@ void dbuf_pool::destroy(void) delete this; } +#ifdef ACL_DBUF_HOOK_NEW + void *dbuf_pool::operator new(size_t size, size_t nblock /* = 2 */) { if (nblock == 0) { @@ -38,13 +49,13 @@ void *dbuf_pool::operator new(size_t size, size_t nblock /* = 2 */) return dbuf; } -#if defined(_WIN32) || defined(_WIN64) +# if defined(_WIN32) || defined(_WIN64) void dbuf_pool::operator delete(void* ptr, size_t) { dbuf_pool* dbuf = (dbuf_pool*) ptr; acl_dbuf_pool_destroy(dbuf->pool_); } -#endif +# endif void dbuf_pool::operator delete(void* ptr) { @@ -52,6 +63,8 @@ void dbuf_pool::operator delete(void* ptr) acl_dbuf_pool_destroy(dbuf->pool_); } +#endif // ACL_DBUF_HOOK_NEW + bool dbuf_pool::dbuf_reset(size_t reserve /* = 0 */) { return acl_dbuf_pool_reset(pool_, mysize_ + reserve) == 0; @@ -129,7 +142,11 @@ dbuf_guard::dbuf_guard(acl::dbuf_pool* dbuf, size_t capacity /* = 500 */) , size_(0) { if (dbuf == NULL) { +#ifdef DBUF_HOOK_NEW dbuf_ = dbuf_internal_ = new (nblock_) acl::dbuf_pool; +#else + dbuf_ = dbuf_internal_ = new acl::dbuf_pool(nblock_); +#endif } else { dbuf_ = dbuf; dbuf_internal_ = NULL; @@ -143,7 +160,11 @@ dbuf_guard::dbuf_guard(size_t nblock /* = 2 */, size_t capacity /* = 500 */) , incr_(500) , size_(0) { +#ifdef DBUF_HOOK_NEW dbuf_ = dbuf_internal_ = new (nblock_) acl::dbuf_pool; +#else + dbuf_ = dbuf_internal_ = new acl::dbuf_pool(nblock_); +#endif init(capacity); } From cbcbb4085a051f9b078d65c720d82b3f3219e34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Mon, 18 Mar 2024 15:47:59 +0800 Subject: [PATCH 02/22] Adding supporting for harmonyOS. --- lib_acl/CMakeLists.txt | 16 ++++++++++++++++ lib_acl/src/stdlib/filedir/acl_fhandle.c | 2 +- lib_acl/src/stdlib/iostuff/acl_write_wait.c | 2 +- lib_acl_cpp/CMakeLists.txt | 15 +++++++++++++++ lib_protocol/CMakeLists.txt | 13 +++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib_acl/CMakeLists.txt b/lib_acl/CMakeLists.txt index badc8a383..4e5550117 100644 --- a/lib_acl/CMakeLists.txt +++ b/lib_acl/CMakeLists.txt @@ -28,6 +28,17 @@ if (CMAKE_SYSTEM_NAME MATCHES "Android") add_definitions("-Wno-unused-command-line-argument") string(APPEND CMAKE_C_FLAGS "-Qunused-arguments") set(UNIX_OS true) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_definitions("-DANDROID") + add_definitions("-DACL_OHOS") + add_definitions("-O3 -flto") + add_definitions("-DHAS_ATOMIC") + add_definitions("-DACL_CLIENT_ONLY") + add_definitions("-fdata-sections -ffunction-sections") + add_definitions("-Wno-unused-command-line-argument") + add_definitions("-Wno-c99-extensions") + string(APPEND CMAKE_C_FLAGS "-Qunused-arguments") + set(UNIX_OS true) elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") add_definitions("-O2") set(UNIX_OS true) @@ -161,6 +172,8 @@ endif() if (CMAKE_SYSTEM_NAME MATCHES "Android") set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../android/lib/${ANDROID_ABI}) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../harmony/lib/${OHOS_ARCH}) else() set(lib_output_path ${PROJECT_BINARY_DIR}/../lib) endif() @@ -186,6 +199,9 @@ if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND ACL_BUILD_SHARED set(sys_ldflags "-shared -flto") endif() target_compile_options(acl_static PRIVATE -fvisibility=hidden) + elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(sys_ldflags "-shared -flto") + target_compile_options(acl_static PRIVATE -fvisibility=hidden) elseif (${UNIX_OS}) set(sys_ldflags "-shared -lpthread -ldl") target_compile_options(acl_static PRIVATE -fvisibility=hidden) diff --git a/lib_acl/src/stdlib/filedir/acl_fhandle.c b/lib_acl/src/stdlib/filedir/acl_fhandle.c index a28f02ece..e32fba925 100644 --- a/lib_acl/src/stdlib/filedir/acl_fhandle.c +++ b/lib_acl/src/stdlib/filedir/acl_fhandle.c @@ -317,7 +317,7 @@ void acl_fhandle_close(ACL_FHANDLE *fs, int delay_timeout) if (fs->nrefer == 0) { acl_debug(__debug_section, 2) ("%s: fpath: %s, when_free: %ld, now: %ld", - myname, PATH(fs->fp), fs->when_free, now); + myname, PATH(fs->fp), (long) fs->when_free, (long) now); __fhandle_close(fs); } iter = iter_next; diff --git a/lib_acl/src/stdlib/iostuff/acl_write_wait.c b/lib_acl/src/stdlib/iostuff/acl_write_wait.c index cab026ed1..a226fc302 100644 --- a/lib_acl/src/stdlib/iostuff/acl_write_wait.c +++ b/lib_acl/src/stdlib/iostuff/acl_write_wait.c @@ -74,7 +74,7 @@ int acl_write_wait_ms(ACL_SOCKET fd, int timeout) end = time(NULL); acl_msg_error("%s(%d), %s: poll return 0, delay=%d, " "fd=%d, cost=%ld", __FILE__, __LINE__, - myname, delay, fd, end - begin); + myname, delay, fd, (long) ( end - begin)); return -1; default: if (fds.revents & POLLNVAL) { diff --git a/lib_acl_cpp/CMakeLists.txt b/lib_acl_cpp/CMakeLists.txt index 3f439f43a..7faa9ad2f 100644 --- a/lib_acl_cpp/CMakeLists.txt +++ b/lib_acl_cpp/CMakeLists.txt @@ -25,6 +25,15 @@ if(CMAKE_SYSTEM_NAME MATCHES "Android") add_definitions("-fdata-sections -ffunction-sections") string(APPEND CMAKE_CXX_FLAGS "-Qunused-arguments") set(UNIX_OS true) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_definitions("-O3 -flto") + add_definitions("-DANDROID") + add_definitions("-DACL_CPP_LOG_SKIP_FILE") + add_definitions("-fdata-sections -ffunction-sections") + add_definitions("-Wno-unused-command-line-argument") + add_definitions("-Wno-c99-extensions") + string(APPEND CMAKE_CXX_FLAGS "-Qunused-arguments") + set(UNIX_OS true) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") # add_definitions("-Wno-invalid-source-encoding") add_definitions("-O2") @@ -225,6 +234,8 @@ endif() if (CMAKE_SYSTEM_NAME MATCHES "Android") set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../android/lib/${ANDROID_ABI}) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../harmony/lib/${OHOS_ARCH}) else() set(lib_output_path ${PROJECT_BINARY_DIR}/../lib) endif() @@ -251,6 +262,10 @@ if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND ACL_BUILD_SHARED endif() target_compile_options(acl_cpp_static PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden) + elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(sys_ldflags "-shared -flto -lz") + target_compile_options(acl_cpp_static PRIVATE + -fvisibility=hidden -fvisibility-inlines-hidden) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") set(sys_ldflags "-shared -lz -liconv -lpthread -ldl") target_compile_options(acl_cpp_static PRIVATE diff --git a/lib_protocol/CMakeLists.txt b/lib_protocol/CMakeLists.txt index e6f6e9c3e..8ef7edfc9 100644 --- a/lib_protocol/CMakeLists.txt +++ b/lib_protocol/CMakeLists.txt @@ -23,6 +23,14 @@ if (CMAKE_SYSTEM_NAME MATCHES "Android") add_definitions("-fdata-sections -ffunction-sections") string(APPEND CMAKE_C_FLAGS "-Qunused-arguments") set(UNIX_OS true) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_definitions("-DANDROID") + add_definitions("-O3 -flto") + add_definitions("-Wno-unused-command-line-argument") + add_definitions("-fdata-sections -ffunction-sections") + add_definitions("-Wno-c99-extensions") + string(APPEND CMAKE_C_FLAGS "-Qunused-arguments") + set(UNIX_OS true) elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") add_definitions("-O2") set(UNIX_OS true) @@ -112,6 +120,8 @@ endif() if (CMAKE_SYSTEM_NAME MATCHES "Android") set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../android/lib/${ANDROID_ABI}) +elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(lib_output_path ${CMAKE_CURRENT_SOURCE_DIR}/../harmony/lib/${OHOS_ARCH}) else() set(lib_output_path ${PROJECT_BINARY_DIR}/../lib) endif() @@ -137,6 +147,9 @@ if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND ACL_BUILD_SHARED set(sys_ldflags "-shared -flto -lz") endif() target_compile_options(protocol_static PRIVATE -fvisibility=hidden) + elseif (CMAKE_SYSTEM_NAME MATCHES "OHOS") + set(sys_ldflags "-shared -flto -lz") + target_compile_options(protocol_static PRIVATE -fvisibility=hidden) elseif (${UNIX_OS}) set(sys_ldflags "-shared -lz -lpthread -ldl") target_compile_options(protocol_static PRIVATE -fvisibility=hidden) From 35b5c737930f0bb364ab5921541da06612d5e28d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Tue, 19 Mar 2024 15:14:27 +0800 Subject: [PATCH 03/22] Support harmonyOS --- lib_acl/src/net/connect/acl_inet_connect.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib_acl/src/net/connect/acl_inet_connect.c b/lib_acl/src/net/connect/acl_inet_connect.c index 219e21147..842b58af3 100644 --- a/lib_acl/src/net/connect/acl_inet_connect.c +++ b/lib_acl/src/net/connect/acl_inet_connect.c @@ -217,6 +217,7 @@ static ACL_SOCKET connect_one(const struct addrinfo *peer, #endif return ACL_SOCKET_INVALID; } + return sock; } @@ -284,6 +285,8 @@ static struct addrinfo *resolve_addr(const char *name, const char *service) hints.ai_flags = 0; #elif defined(ACL_MACOSX) hints.ai_flags = AI_DEFAULT; +#elif defined(ACL_OHOS) + hints.ai_flags = 0; #elif defined(ACL_ANDROID) hints.ai_flags = AI_ADDRCONFIG; #elif defined(ACL_WINDOWS) @@ -298,8 +301,8 @@ static struct addrinfo *resolve_addr(const char *name, const char *service) return res0; } - acl_msg_error("%s(%d), %s: getaddrinfo error %s, peer=%s", - __FILE__, __LINE__, __FUNCTION__, gai_strerror(err), name); + acl_msg_error("%s(%d), %s: getaddrinfo error(%d) %s, peer=%s", + __FILE__, __LINE__, __FUNCTION__, err, gai_strerror(err), name); return NULL; } @@ -363,9 +366,13 @@ static int parse_addr(const char *addr, struct addr_res *res) res->peer_res0 = try_numeric_addr(res->peer_family, peer, res->peer_port, &res->peer_buf, &res->peer_in); - if (res->peer_res0 == NULL && (res->peer_res0 = - resolve_addr(peer, res->peer_port)) == NULL) { - return -1; + if (res->peer_res0 == NULL) { + res->peer_res0 = resolve_addr(peer, res->peer_port); + if (res->peer_res0 == NULL) { + acl_msg_error("%s(%d): resolve %s|%s error", + __FUNCTION__, __LINE__, peer, res->peer_port); + return -1; + } } if (local != NULL) { From 2a1b89bac68a91f2b62f7273b3cfe03a67d846ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Tue, 19 Mar 2024 15:25:51 +0800 Subject: [PATCH 04/22] Add project for harmonyOS. --- harmony/api9/.gitignore | 11 ++ harmony/api9/AppScope/app.json5 | 10 ++ .../resources/base/element/string.json | 8 + .../resources/base/media/app_icon.png | Bin 0 -> 6790 bytes harmony/api9/build-profile.json5 | 27 +++ harmony/api9/entry/.gitignore | 6 + harmony/api9/entry/build-profile.json5 | 19 +++ harmony/api9/entry/hvigorfile.ts | 2 + harmony/api9/entry/oh-package.json5 | 12 ++ .../api9/entry/src/main/cpp/CMakeLists.txt | 59 +++++++ harmony/api9/entry/src/main/cpp/hello.cpp | 159 ++++++++++++++++++ harmony/api9/entry/src/main/cpp/logger.cpp | 126 ++++++++++++++ harmony/api9/entry/src/main/cpp/logger.h | 16 ++ harmony/api9/entry/src/main/cpp/mystdafx.h | 4 + .../src/main/cpp/types/libentry/index.d.ts | 2 + .../main/cpp/types/libentry/oh-package.json5 | 6 + .../ets/common/constant/StyleConstant.ets | 36 ++++ .../src/main/ets/entryability/EntryAbility.ts | 41 +++++ .../api9/entry/src/main/ets/pages/Index.ets | 62 +++++++ harmony/api9/entry/src/main/module.json5 | 48 ++++++ .../main/resources/base/element/color.json | 8 + .../main/resources/base/element/float.json | 48 ++++++ .../main/resources/base/element/string.json | 16 ++ .../src/main/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/main_pages.json | 5 + .../main/resources/en_US/element/string.json | 16 ++ .../main/resources/zh_CN/element/string.json | 16 ++ .../src/ohosTest/ets/test/Ability.test.ets | 35 ++++ .../entry/src/ohosTest/ets/test/List.test.ets | 7 + .../ohosTest/ets/testability/TestAbility.ets | 48 ++++++ .../ohosTest/ets/testability/pages/Index.ets | 34 ++++ .../ets/testrunner/OpenHarmonyTestRunner.ts | 49 ++++++ harmony/api9/entry/src/ohosTest/module.json5 | 37 ++++ .../resources/base/element/color.json | 8 + .../resources/base/element/string.json | 16 ++ .../ohosTest/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../resources/base/profile/test_pages.json | 5 + harmony/api9/hvigor/hvigor-config.json5 | 6 + harmony/api9/hvigor/hvigor-wrapper.js | 2 + harmony/api9/hvigorfile.ts | 2 + harmony/api9/hvigorw | 48 ++++++ harmony/api9/hvigorw.bat | 64 +++++++ harmony/api9/oh-package-lock.json5 | 13 ++ harmony/api9/oh-package.json5 | 13 ++ 44 files changed, 1150 insertions(+) create mode 100644 harmony/api9/.gitignore create mode 100644 harmony/api9/AppScope/app.json5 create mode 100644 harmony/api9/AppScope/resources/base/element/string.json create mode 100644 harmony/api9/AppScope/resources/base/media/app_icon.png create mode 100644 harmony/api9/build-profile.json5 create mode 100644 harmony/api9/entry/.gitignore create mode 100644 harmony/api9/entry/build-profile.json5 create mode 100644 harmony/api9/entry/hvigorfile.ts create mode 100644 harmony/api9/entry/oh-package.json5 create mode 100644 harmony/api9/entry/src/main/cpp/CMakeLists.txt create mode 100644 harmony/api9/entry/src/main/cpp/hello.cpp create mode 100644 harmony/api9/entry/src/main/cpp/logger.cpp create mode 100644 harmony/api9/entry/src/main/cpp/logger.h create mode 100644 harmony/api9/entry/src/main/cpp/mystdafx.h create mode 100644 harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts create mode 100644 harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 create mode 100644 harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets create mode 100644 harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts create mode 100644 harmony/api9/entry/src/main/ets/pages/Index.ets create mode 100644 harmony/api9/entry/src/main/module.json5 create mode 100644 harmony/api9/entry/src/main/resources/base/element/color.json create mode 100644 harmony/api9/entry/src/main/resources/base/element/float.json create mode 100644 harmony/api9/entry/src/main/resources/base/element/string.json create mode 100644 harmony/api9/entry/src/main/resources/base/media/icon.png create mode 100644 harmony/api9/entry/src/main/resources/base/profile/main_pages.json create mode 100644 harmony/api9/entry/src/main/resources/en_US/element/string.json create mode 100644 harmony/api9/entry/src/main/resources/zh_CN/element/string.json create mode 100644 harmony/api9/entry/src/ohosTest/ets/test/Ability.test.ets create mode 100644 harmony/api9/entry/src/ohosTest/ets/test/List.test.ets create mode 100644 harmony/api9/entry/src/ohosTest/ets/testability/TestAbility.ets create mode 100644 harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets create mode 100644 harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts create mode 100644 harmony/api9/entry/src/ohosTest/module.json5 create mode 100644 harmony/api9/entry/src/ohosTest/resources/base/element/color.json create mode 100644 harmony/api9/entry/src/ohosTest/resources/base/element/string.json create mode 100644 harmony/api9/entry/src/ohosTest/resources/base/media/icon.png create mode 100644 harmony/api9/entry/src/ohosTest/resources/base/profile/test_pages.json create mode 100644 harmony/api9/hvigor/hvigor-config.json5 create mode 100644 harmony/api9/hvigor/hvigor-wrapper.js create mode 100644 harmony/api9/hvigorfile.ts create mode 100644 harmony/api9/hvigorw create mode 100644 harmony/api9/hvigorw.bat create mode 100644 harmony/api9/oh-package-lock.json5 create mode 100644 harmony/api9/oh-package.json5 diff --git a/harmony/api9/.gitignore b/harmony/api9/.gitignore new file mode 100644 index 000000000..fbabf7710 --- /dev/null +++ b/harmony/api9/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/harmony/api9/AppScope/app.json5 b/harmony/api9/AppScope/app.json5 new file mode 100644 index 000000000..60e0ad398 --- /dev/null +++ b/harmony/api9/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.api9", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/harmony/api9/AppScope/resources/base/element/string.json b/harmony/api9/AppScope/resources/base/element/string.json new file mode 100644 index 000000000..3851e6fbf --- /dev/null +++ b/harmony/api9/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "api9" + } + ] +} diff --git a/harmony/api9/AppScope/resources/base/media/app_icon.png b/harmony/api9/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 +#include +#include "mystdafx.h" +#include "logger.h" + +class http_thread : public acl::thread { +public: + http_thread(const char* url) : url_(url) {} + ~http_thread() = default; + + const acl::string& result() const { + return body_; + } + + protected: + std::string url_; + acl::string body_; + + // @override + void *run() override { + url_get(); + return nullptr; + } + + bool url_get() { + const char* addr = "110.242.68.4|80"; + addr = "www.baidu.com:80"; + // addr = "110.242.68.3"; + acl::http_request req(addr, 5); + req.request_header().set_url("/") + .set_host("www.baidu.com"); + + if (!req.request(nullptr, 0)) { + log_info("%s: http request error, addr=%s", __func__, addr); + return false; + } + + int http_status = req.http_status(); + acl::string buf; + buf.format("http status=%d", http_status); + log_info( "%s: url_get", __func__, buf.c_str()); + + if (!req.get_body(body_)) { + log_error("%s: get http body error!", __func__); + return false; + } + + int f = AI_ADDRCONFIG; + struct sockaddr sa; + log_info("%s: http response body: %s", __func__, body_.c_str()); + return true; + } +}; + +static napi_value HttpGet(napi_env env, napi_callback_info info) +{ + log_info("%s: Started!", __func__); + + size_t argc = 1; + napi_value args[1] = { nullptr }; + + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + char url[256]; + size_t len; + napi_status res = napi_get_value_string_utf8(env, args[0], url, sizeof(url), &len); + if (res != napi_ok) { + log_info("%s: napi_get_value_string_utf8 error=%d", __func__, res); + return nullptr; + } + + log_info( "%s: url=%s", __func__, url); + +#if 0 + napi_value result; + if (napi_create_string_utf8(env, url, strlen(url), &result) != napi_ok) { + return nullptr; + } + return result; +#else + http_thread http(url); + http.set_detachable(false); + http.start(); + http.wait(); + + const acl::string& body = http.result(); + if (body.empty()) { + log_info("%s: http resply body empty!", __func__); + return nullptr; + } + napi_value result; + res = napi_create_string_utf8(env, body.c_str(), body.size(), &result); + if (res != napi_ok) { + log_info("%s: napi_create_string_utf8 error=%d", __func__, res); + return nullptr; + } + + log_info("%s: At last, http body length=%zd", __func__, body.size()); + return result; +#endif +} + +static napi_value Add(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value args[2] = {nullptr}; + + napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); + + napi_valuetype valuetype0; + napi_typeof(env, args[0], &valuetype0); + + napi_valuetype valuetype1; + napi_typeof(env, args[1], &valuetype1); + + double value0; + napi_get_value_double(env, args[0], &value0); + + double value1; + napi_get_value_double(env, args[1], &value1); + + napi_value sum; + napi_create_double(env, value0 + value1, &sum); + + return sum; +} + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + acl::acl_cpp_init(); + log_open(); + + const char* version = acl_version(); + log_info("%s: Acl version=%s", __func__, version); + + napi_property_descriptor desc[] = { + { "HttpGet", nullptr, HttpGet, nullptr, nullptr, nullptr, napi_default, nullptr }, + { "Add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }, + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version =1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) +{ + napi_module_register(&demoModule); +} diff --git a/harmony/api9/entry/src/main/cpp/logger.cpp b/harmony/api9/entry/src/main/cpp/logger.cpp new file mode 100644 index 000000000..bf9c7700f --- /dev/null +++ b/harmony/api9/entry/src/main/cpp/logger.cpp @@ -0,0 +1,126 @@ +// +// Created by zhengshuxin on 2019/8/22. +// + +#include "mystdafx.h" +#include +#include +#include "logger.h" + +#define LOG_ON + +void log_info(const char* fmt, ...) +{ + const char* ver = acl_version(); + char tag[256]; + snprintf(tag, sizeof(tag), "acl-%s", ver); + acl::string buf; + + va_list ap; + va_start(ap, fmt); + buf.vformat(fmt, ap); + va_end(ap); + + OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "tag", "%{public}s", buf.c_str()); +} + +void log_error(const char* fmt, ...) +{ + const char* ver = acl_version(); + char tag[256]; + snprintf(tag, sizeof(tag), "acl-%s", ver); + acl::string buf; + + va_list ap; + va_start(ap, fmt); + buf.vformat(fmt, ap); + va_end(ap); + + OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, tag, "%{public}s", buf.c_str()); +} + +void log_warn(const char* fmt, ...) +{ + const char* ver = acl_version(); + char tag[256]; + snprintf(tag, sizeof(tag), "acl-%s", ver); + acl::string buf; + + va_list ap; + va_start(ap, fmt); + buf.vformat(fmt, ap); + va_end(ap); + + OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, tag, "%{public}s", buf.c_str()); +} + +void log_fatal(const char* fmt, ...) +{ + const char* ver = acl_version(); + char tag[256]; + snprintf(tag, sizeof(tag), "acl-%s", ver); + acl::string buf; + + va_list ap; + va_start(ap, fmt); + buf.vformat(fmt, ap); + va_end(ap); + + OH_LOG_Print(LOG_APP, LOG_FATAL, LOG_DOMAIN, tag, "%{public}s", buf.c_str()); +} + +void log_debug(const char* fmt, ...) +{ + const char* ver = acl_version(); + char tag[256]; + snprintf(tag, sizeof(tag), "acl-%s", ver); + acl::string buf; + + va_list ap; + va_start(ap, fmt); + buf.vformat(fmt, ap); + va_end(ap); + + OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, tag, "%{public}s", buf.c_str()); +} + +static int open_callback(const char*, void*) { + return 0; +} + +static write_fn s_write_callback; + +static void write_callback(void*, const char* str) +{ + log_info("%s", str); +} + +static void log_callback(void* ctx, const char* fmt, va_list ap) { + static acl::string* buf = nullptr; + if (buf == nullptr) { + buf = new acl::string(512); + } + buf->vformat(fmt, ap); + s_write_callback(ctx, buf->c_str()); +} + +static void init_once() { + s_write_callback = write_callback; + acl_msg_register(open_callback, nullptr, log_callback, nullptr); + acl_msg_open("dummy.txt", "dummy"); +} + +static acl_pthread_once_t s_init_once = ACL_PTHREAD_ONCE_INIT; + +void log_open() +{ + if (acl_pthread_once(&s_init_once, init_once) != 0) { + return; + } + + //log_info("call logger_hook ok"); +} + +void log_close() +{ +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/cpp/logger.h b/harmony/api9/entry/src/main/cpp/logger.h new file mode 100644 index 000000000..a95e6c70b --- /dev/null +++ b/harmony/api9/entry/src/main/cpp/logger.h @@ -0,0 +1,16 @@ +// +// Created by zhengshuxin on 2019/8/26. +// + +#pragma once + +typedef void (*write_fn)(void *, const char *); + +void log_info(const char *fmt, ...); +void log_error(const char *fmt, ...); +void log_warn(const char *fmt, ...); +void log_fatal(const char *fmt, ...); +void log_debug(const char *fmt, ...); + +void log_open(); +void log_close(); \ No newline at end of file diff --git a/harmony/api9/entry/src/main/cpp/mystdafx.h b/harmony/api9/entry/src/main/cpp/mystdafx.h new file mode 100644 index 000000000..ee0355fe6 --- /dev/null +++ b/harmony/api9/entry/src/main/cpp/mystdafx.h @@ -0,0 +1,4 @@ +#pragma once + +#include "lib_acl.h" +#include "acl_cpp/lib_acl.hpp" diff --git a/harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts b/harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts new file mode 100644 index 000000000..dd88e2ee2 --- /dev/null +++ b/harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts @@ -0,0 +1,2 @@ +export const Add: (a: number, b: number) => number; +export const HttpGet: (url: string) => string; \ No newline at end of file diff --git a/harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 b/harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 000000000..8c49cae22 --- /dev/null +++ b/harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libentry.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets b/harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets new file mode 100644 index 000000000..74eade926 --- /dev/null +++ b/harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default class StyleConstants { + /** + * Full the width. + */ + static readonly FULL_WIDTH: string = '100%'; + + /** + * Full the height. + */ + static readonly FULL_HEIGHT: string = '100%'; + + /** + * Web height. + */ + static readonly WEB_HEIGHT: string = '83%'; + + /** + * Button width. + */ + static readonly BUTTON_WIDTH: string = '90%'; +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts b/harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts new file mode 100644 index 000000000..1d53c8339 --- /dev/null +++ b/harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts @@ -0,0 +1,41 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import hilog from '@ohos.hilog'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +}; diff --git a/harmony/api9/entry/src/main/ets/pages/Index.ets b/harmony/api9/entry/src/main/ets/pages/Index.ets new file mode 100644 index 000000000..708d36719 --- /dev/null +++ b/harmony/api9/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,62 @@ +import hilog from '@ohos.hilog'; +import testNapi from 'libentry.so' +import worker from '@ohos.worker'; +import StyleConstant from '../common/constant/StyleConstant'; +import taskpool from '@ohos.taskpool'; + +@Concurrent +function httpGet(url: string) : string { + const body: string = testNapi.HttpGet(url); + return body; +} + +@Concurrent +function Add(num1, num2) : number { + return testNapi.Add(num1, num2); +} + +async function asyncTask() : Promise { + try { + let task = new taskpool.Task(Add, 10, 100); + let num = await taskpool.execute(task); + console.info('------------------------------>Add Result: ', num); + } catch (e) { + console.error("----------------------------->Taskpool execute Add error: " + e); + } + + try { + let url: string = "http://www.baidu.com/"; + let task = new taskpool.Task(httpGet, url); + let body = await taskpool.execute(task); + if (body != null) { + //console.info('----------------------------->body:' + String(body)); + console.info('----------------------------->body ok!'); + } else { + console.info("------------------------------>body null"); + } + } catch (e) { + console.error("----------------------------->Taskpool execute HttpGet error: " + e); + } +} + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + asyncTask(); + //hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.Add(20, 30)); + }) + } + .width('100%') + } + .height('100%') + } +} diff --git a/harmony/api9/entry/src/main/module.json5 b/harmony/api9/entry/src/main/module.json5 new file mode 100644 index 000000000..74c298de1 --- /dev/null +++ b/harmony/api9/entry/src/main/module.json5 @@ -0,0 +1,48 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet" + ], + "requestPermissions":[ + { + "name": "ohos.permission.INTERNET", + "usedScene": { + "abilities": [ + "EntryAbility" + ], + "when": "inuse" + } + } + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ts", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/resources/base/element/color.json b/harmony/api9/entry/src/main/resources/base/element/color.json new file mode 100644 index 000000000..3c712962d --- /dev/null +++ b/harmony/api9/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/resources/base/element/float.json b/harmony/api9/entry/src/main/resources/base/element/float.json new file mode 100644 index 000000000..8e30f46ca --- /dev/null +++ b/harmony/api9/entry/src/main/resources/base/element/float.json @@ -0,0 +1,48 @@ +{ + "float": [ + { + "name": "text_input_width", + "value": "300" + }, + { + "name": "button_font_size", + "value": "16" + }, + { + "name": "button_height", + "value": "40" + }, + { + "name": "text_input_height", + "value": "40" + }, + { + "name": "default_fontSize", + "value": "30" + }, + { + "name": "image_height", + "value": "30" + }, + { + "name": "image_width", + "value": "30" + }, + { + "name": "border_radius", + "value": "28" + }, + { + "name": "default_row_height", + "value": "56" + }, + { + "name": "default_margin", + "value": "12" + }, + { + "name": "default_padding", + "value": "12" + } + ] +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/resources/base/element/string.json b/harmony/api9/entry/src/main/resources/base/element/string.json new file mode 100644 index 000000000..f94595515 --- /dev/null +++ b/harmony/api9/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/harmony/api9/entry/src/main/resources/base/media/icon.png b/harmony/api9/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets b/harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 000000000..166366593 --- /dev/null +++ b/harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,34 @@ +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 000000000..92a16d84e --- /dev/null +++ b/harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,49 @@ +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/harmony/api9/entry/src/ohosTest/module.json5 b/harmony/api9/entry/src/ohosTest/module.json5 new file mode 100644 index 000000000..c031340ae --- /dev/null +++ b/harmony/api9/entry/src/ohosTest/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/harmony/api9/entry/src/ohosTest/resources/base/element/color.json b/harmony/api9/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 000000000..3c712962d --- /dev/null +++ b/harmony/api9/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/harmony/api9/entry/src/ohosTest/resources/base/element/string.json b/harmony/api9/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 000000000..65d8fa5a7 --- /dev/null +++ b/harmony/api9/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/harmony/api9/entry/src/ohosTest/resources/base/media/icon.png b/harmony/api9/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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"a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"鈥"===e||"鈥"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"鈥":case"鈥":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"鈥":case"鈥":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/harmony/api9/hvigorfile.ts b/harmony/api9/hvigorfile.ts new file mode 100644 index 000000000..647818690 --- /dev/null +++ b/harmony/api9/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/harmony/api9/hvigorw b/harmony/api9/hvigorw new file mode 100644 index 000000000..54aadd226 --- /dev/null +++ b/harmony/api9/hvigorw @@ -0,0 +1,48 @@ +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/harmony/api9/hvigorw.bat b/harmony/api9/hvigorw.bat new file mode 100644 index 000000000..6861293e4 --- /dev/null +++ b/harmony/api9/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/harmony/api9/oh-package-lock.json5 b/harmony/api9/oh-package-lock.json5 new file mode 100644 index 000000000..bc40219d5 --- /dev/null +++ b/harmony/api9/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/harmony/api9/oh-package.json5 b/harmony/api9/oh-package.json5 new file mode 100644 index 000000000..e27cf522a --- /dev/null +++ b/harmony/api9/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "name": "api9", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.6" + } +} From 38ac362981fa98331ad9131d7a4c2580f9642c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Wed, 20 Mar 2024 10:22:14 +0800 Subject: [PATCH 05/22] Rename acl project's name to acl_one for harmonyOS. --- harmony/api9/{ => acl_one}/.gitignore | 0 harmony/api9/{ => acl_one}/AppScope/app.json5 | 2 +- .../AppScope/resources/base/element/string.json | 2 +- .../AppScope/resources/base/media/app_icon.png | Bin harmony/api9/{ => acl_one}/build-profile.json5 | 0 harmony/api9/{ => acl_one}/entry/.gitignore | 0 .../api9/{ => acl_one}/entry/build-profile.json5 | 0 harmony/api9/{ => acl_one}/entry/hvigorfile.ts | 0 harmony/api9/{ => acl_one}/entry/oh-package.json5 | 0 .../entry/src/main/cpp/CMakeLists.txt | 14 ++++++++------ .../{ => acl_one}/entry/src/main/cpp/hello.cpp | 0 .../{ => acl_one}/entry/src/main/cpp/logger.cpp | 0 .../{ => acl_one}/entry/src/main/cpp/logger.h | 0 .../{ => acl_one}/entry/src/main/cpp/mystdafx.h | 0 .../entry/src/main/cpp/types/libentry/index.d.ts | 0 .../src/main/cpp/types/libentry/oh-package.json5 | 0 .../main/ets/common/constant/StyleConstant.ets | 0 .../src/main/ets/entryability/EntryAbility.ts | 0 .../entry/src/main/ets/pages/Index.ets | 0 .../{ => acl_one}/entry/src/main/module.json5 | 0 .../src/main/resources/base/element/color.json | 0 .../src/main/resources/base/element/float.json | 0 .../src/main/resources/base/element/string.json | 0 .../entry/src/main/resources/base/media/icon.png | Bin .../main/resources/base/profile/main_pages.json | 0 .../src/main/resources/en_US/element/string.json | 0 .../src/main/resources/zh_CN/element/string.json | 0 .../entry/src/ohosTest/ets/test/Ability.test.ets | 0 .../entry/src/ohosTest/ets/test/List.test.ets | 0 .../src/ohosTest/ets/testability/TestAbility.ets | 0 .../src/ohosTest/ets/testability/pages/Index.ets | 0 .../ets/testrunner/OpenHarmonyTestRunner.ts | 0 .../{ => acl_one}/entry/src/ohosTest/module.json5 | 0 .../ohosTest/resources/base/element/color.json | 0 .../ohosTest/resources/base/element/string.json | 0 .../src/ohosTest/resources/base/media/icon.png | Bin .../resources/base/profile/test_pages.json | 0 .../api9/{ => acl_one}/hvigor/hvigor-config.json5 | 0 .../api9/{ => acl_one}/hvigor/hvigor-wrapper.js | 0 harmony/api9/{ => acl_one}/hvigorfile.ts | 0 harmony/api9/{ => acl_one}/hvigorw | 0 harmony/api9/{ => acl_one}/hvigorw.bat | 0 harmony/api9/{ => acl_one}/oh-package-lock.json5 | 0 harmony/api9/{ => acl_one}/oh-package.json5 | 2 +- 44 files changed, 11 insertions(+), 9 deletions(-) rename harmony/api9/{ => acl_one}/.gitignore (100%) rename harmony/api9/{ => acl_one}/AppScope/app.json5 (79%) rename harmony/api9/{ => acl_one}/AppScope/resources/base/element/string.json (70%) rename harmony/api9/{ => acl_one}/AppScope/resources/base/media/app_icon.png (100%) rename harmony/api9/{ => acl_one}/build-profile.json5 (100%) rename harmony/api9/{ => acl_one}/entry/.gitignore (100%) rename harmony/api9/{ => acl_one}/entry/build-profile.json5 (100%) rename harmony/api9/{ => acl_one}/entry/hvigorfile.ts (100%) rename harmony/api9/{ => acl_one}/entry/oh-package.json5 (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/CMakeLists.txt (83%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/hello.cpp (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/logger.cpp (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/logger.h (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/mystdafx.h (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/types/libentry/index.d.ts (100%) rename harmony/api9/{ => acl_one}/entry/src/main/cpp/types/libentry/oh-package.json5 (100%) rename harmony/api9/{ => acl_one}/entry/src/main/ets/common/constant/StyleConstant.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/main/ets/entryability/EntryAbility.ts (100%) rename harmony/api9/{ => acl_one}/entry/src/main/ets/pages/Index.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/main/module.json5 (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/base/element/color.json (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/base/element/float.json (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/base/element/string.json (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/base/media/icon.png (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/base/profile/main_pages.json (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/en_US/element/string.json (100%) rename harmony/api9/{ => acl_one}/entry/src/main/resources/zh_CN/element/string.json (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/ets/test/Ability.test.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/ets/test/List.test.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/ets/testability/TestAbility.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/ets/testability/pages/Index.ets (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/module.json5 (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/resources/base/element/color.json (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/resources/base/element/string.json (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/resources/base/media/icon.png (100%) rename harmony/api9/{ => acl_one}/entry/src/ohosTest/resources/base/profile/test_pages.json (100%) rename harmony/api9/{ => acl_one}/hvigor/hvigor-config.json5 (100%) rename harmony/api9/{ => acl_one}/hvigor/hvigor-wrapper.js (100%) rename harmony/api9/{ => acl_one}/hvigorfile.ts (100%) rename harmony/api9/{ => acl_one}/hvigorw (100%) rename harmony/api9/{ => acl_one}/hvigorw.bat (100%) rename harmony/api9/{ => acl_one}/oh-package-lock.json5 (100%) rename harmony/api9/{ => acl_one}/oh-package.json5 (90%) diff --git a/harmony/api9/.gitignore b/harmony/api9/acl_one/.gitignore similarity index 100% rename from harmony/api9/.gitignore rename to harmony/api9/acl_one/.gitignore diff --git a/harmony/api9/AppScope/app.json5 b/harmony/api9/acl_one/AppScope/app.json5 similarity index 79% rename from harmony/api9/AppScope/app.json5 rename to harmony/api9/acl_one/AppScope/app.json5 index 60e0ad398..b93be02c2 100644 --- a/harmony/api9/AppScope/app.json5 +++ b/harmony/api9/acl_one/AppScope/app.json5 @@ -1,6 +1,6 @@ { "app": { - "bundleName": "com.example.api9", + "bundleName": "com.example.acl_one", "vendor": "example", "versionCode": 1000000, "versionName": "1.0.0", diff --git a/harmony/api9/AppScope/resources/base/element/string.json b/harmony/api9/acl_one/AppScope/resources/base/element/string.json similarity index 70% rename from harmony/api9/AppScope/resources/base/element/string.json rename to harmony/api9/acl_one/AppScope/resources/base/element/string.json index 3851e6fbf..4c3f776e5 100644 --- a/harmony/api9/AppScope/resources/base/element/string.json +++ b/harmony/api9/acl_one/AppScope/resources/base/element/string.json @@ -2,7 +2,7 @@ "string": [ { "name": "app_name", - "value": "api9" + "value": "acl_one" } ] } diff --git a/harmony/api9/AppScope/resources/base/media/app_icon.png b/harmony/api9/acl_one/AppScope/resources/base/media/app_icon.png similarity index 100% rename from harmony/api9/AppScope/resources/base/media/app_icon.png rename to harmony/api9/acl_one/AppScope/resources/base/media/app_icon.png diff --git a/harmony/api9/build-profile.json5 b/harmony/api9/acl_one/build-profile.json5 similarity index 100% rename from harmony/api9/build-profile.json5 rename to harmony/api9/acl_one/build-profile.json5 diff --git a/harmony/api9/entry/.gitignore b/harmony/api9/acl_one/entry/.gitignore similarity index 100% rename from harmony/api9/entry/.gitignore rename to harmony/api9/acl_one/entry/.gitignore diff --git a/harmony/api9/entry/build-profile.json5 b/harmony/api9/acl_one/entry/build-profile.json5 similarity index 100% rename from harmony/api9/entry/build-profile.json5 rename to harmony/api9/acl_one/entry/build-profile.json5 diff --git a/harmony/api9/entry/hvigorfile.ts b/harmony/api9/acl_one/entry/hvigorfile.ts similarity index 100% rename from harmony/api9/entry/hvigorfile.ts rename to harmony/api9/acl_one/entry/hvigorfile.ts diff --git a/harmony/api9/entry/oh-package.json5 b/harmony/api9/acl_one/entry/oh-package.json5 similarity index 100% rename from harmony/api9/entry/oh-package.json5 rename to harmony/api9/acl_one/entry/oh-package.json5 diff --git a/harmony/api9/entry/src/main/cpp/CMakeLists.txt b/harmony/api9/acl_one/entry/src/main/cpp/CMakeLists.txt similarity index 83% rename from harmony/api9/entry/src/main/cpp/CMakeLists.txt rename to harmony/api9/acl_one/entry/src/main/cpp/CMakeLists.txt index 741565ff7..88dc9c986 100644 --- a/harmony/api9/entry/src/main/cpp/CMakeLists.txt +++ b/harmony/api9/acl_one/entry/src/main/cpp/CMakeLists.txt @@ -1,20 +1,23 @@ # the minimum version of CMake. cmake_minimum_required(VERSION 3.4.1) -project(api9) +project(acl_one) set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${NATIVERENDER_ROOT_PATH} ${NATIVERENDER_ROOT_PATH}/include) -set(acl_home ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../..) +set(acl_home ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../..) set(acl_c_path ${acl_home}/lib_acl) set(acl_c_include ${acl_c_path}/include) +set(pro_c_path ${acl_home}/lib_protocol) +set(pro_c_include ${acl_home}/lib_protocol/include) set(acl_cpp_path ${acl_home}/lib_acl_cpp) set(acl_cpp_include ${acl_cpp_path}/include) include_directories( ${acl_c_include} + ${pro_c_include} ${acl_cpp_include} ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -38,9 +41,9 @@ endforeach() add_library(entry SHARED ${mylib_src}) #add_library(entry SHARED hello.cpp) -add_subdirectory(../../../../../../lib_acl acl) -add_subdirectory(../../../../../../lib_protocol protocol) -add_subdirectory(../../../../../../lib_acl_cpp acl_cpp) +add_subdirectory(${acl_c_path} acl) +add_subdirectory(${pro_c_path} protocol) +add_subdirectory(${acl_cpp_path} acl_cpp) set(lib_acl_path ${acl_home}/harmony/lib/${OHOS_ARCH}) set(libacl ${lib_acl_path}/libacl.a) @@ -56,4 +59,3 @@ find_library( ) target_link_libraries(entry PUBLIC libace_napi.z.so ${lib_all} ${hilog-lib} libace_napi.z.so libc++.a) #target_link_libraries(entry PUBLIC libace_napi.z.so ${lib_all} ${hilog-lib} libc++.a) - diff --git a/harmony/api9/entry/src/main/cpp/hello.cpp b/harmony/api9/acl_one/entry/src/main/cpp/hello.cpp similarity index 100% rename from harmony/api9/entry/src/main/cpp/hello.cpp rename to harmony/api9/acl_one/entry/src/main/cpp/hello.cpp diff --git a/harmony/api9/entry/src/main/cpp/logger.cpp b/harmony/api9/acl_one/entry/src/main/cpp/logger.cpp similarity index 100% rename from harmony/api9/entry/src/main/cpp/logger.cpp rename to harmony/api9/acl_one/entry/src/main/cpp/logger.cpp diff --git a/harmony/api9/entry/src/main/cpp/logger.h b/harmony/api9/acl_one/entry/src/main/cpp/logger.h similarity index 100% rename from harmony/api9/entry/src/main/cpp/logger.h rename to harmony/api9/acl_one/entry/src/main/cpp/logger.h diff --git a/harmony/api9/entry/src/main/cpp/mystdafx.h b/harmony/api9/acl_one/entry/src/main/cpp/mystdafx.h similarity index 100% rename from harmony/api9/entry/src/main/cpp/mystdafx.h rename to harmony/api9/acl_one/entry/src/main/cpp/mystdafx.h diff --git a/harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts b/harmony/api9/acl_one/entry/src/main/cpp/types/libentry/index.d.ts similarity index 100% rename from harmony/api9/entry/src/main/cpp/types/libentry/index.d.ts rename to harmony/api9/acl_one/entry/src/main/cpp/types/libentry/index.d.ts diff --git a/harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 b/harmony/api9/acl_one/entry/src/main/cpp/types/libentry/oh-package.json5 similarity index 100% rename from harmony/api9/entry/src/main/cpp/types/libentry/oh-package.json5 rename to harmony/api9/acl_one/entry/src/main/cpp/types/libentry/oh-package.json5 diff --git a/harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets b/harmony/api9/acl_one/entry/src/main/ets/common/constant/StyleConstant.ets similarity index 100% rename from harmony/api9/entry/src/main/ets/common/constant/StyleConstant.ets rename to harmony/api9/acl_one/entry/src/main/ets/common/constant/StyleConstant.ets diff --git a/harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts b/harmony/api9/acl_one/entry/src/main/ets/entryability/EntryAbility.ts similarity index 100% rename from harmony/api9/entry/src/main/ets/entryability/EntryAbility.ts rename to harmony/api9/acl_one/entry/src/main/ets/entryability/EntryAbility.ts diff --git a/harmony/api9/entry/src/main/ets/pages/Index.ets b/harmony/api9/acl_one/entry/src/main/ets/pages/Index.ets similarity index 100% rename from harmony/api9/entry/src/main/ets/pages/Index.ets rename to harmony/api9/acl_one/entry/src/main/ets/pages/Index.ets diff --git a/harmony/api9/entry/src/main/module.json5 b/harmony/api9/acl_one/entry/src/main/module.json5 similarity index 100% rename from harmony/api9/entry/src/main/module.json5 rename to harmony/api9/acl_one/entry/src/main/module.json5 diff --git a/harmony/api9/entry/src/main/resources/base/element/color.json b/harmony/api9/acl_one/entry/src/main/resources/base/element/color.json similarity index 100% rename from harmony/api9/entry/src/main/resources/base/element/color.json rename to harmony/api9/acl_one/entry/src/main/resources/base/element/color.json diff --git a/harmony/api9/entry/src/main/resources/base/element/float.json b/harmony/api9/acl_one/entry/src/main/resources/base/element/float.json similarity index 100% rename from harmony/api9/entry/src/main/resources/base/element/float.json rename to harmony/api9/acl_one/entry/src/main/resources/base/element/float.json diff --git a/harmony/api9/entry/src/main/resources/base/element/string.json b/harmony/api9/acl_one/entry/src/main/resources/base/element/string.json similarity index 100% rename from harmony/api9/entry/src/main/resources/base/element/string.json rename to harmony/api9/acl_one/entry/src/main/resources/base/element/string.json diff --git a/harmony/api9/entry/src/main/resources/base/media/icon.png b/harmony/api9/acl_one/entry/src/main/resources/base/media/icon.png similarity index 100% rename from harmony/api9/entry/src/main/resources/base/media/icon.png rename to harmony/api9/acl_one/entry/src/main/resources/base/media/icon.png diff --git a/harmony/api9/entry/src/main/resources/base/profile/main_pages.json b/harmony/api9/acl_one/entry/src/main/resources/base/profile/main_pages.json similarity index 100% rename from harmony/api9/entry/src/main/resources/base/profile/main_pages.json rename to harmony/api9/acl_one/entry/src/main/resources/base/profile/main_pages.json diff --git a/harmony/api9/entry/src/main/resources/en_US/element/string.json b/harmony/api9/acl_one/entry/src/main/resources/en_US/element/string.json similarity index 100% rename from harmony/api9/entry/src/main/resources/en_US/element/string.json rename to harmony/api9/acl_one/entry/src/main/resources/en_US/element/string.json diff --git a/harmony/api9/entry/src/main/resources/zh_CN/element/string.json b/harmony/api9/acl_one/entry/src/main/resources/zh_CN/element/string.json similarity index 100% rename from harmony/api9/entry/src/main/resources/zh_CN/element/string.json rename to harmony/api9/acl_one/entry/src/main/resources/zh_CN/element/string.json diff --git a/harmony/api9/entry/src/ohosTest/ets/test/Ability.test.ets b/harmony/api9/acl_one/entry/src/ohosTest/ets/test/Ability.test.ets similarity index 100% rename from harmony/api9/entry/src/ohosTest/ets/test/Ability.test.ets rename to harmony/api9/acl_one/entry/src/ohosTest/ets/test/Ability.test.ets diff --git a/harmony/api9/entry/src/ohosTest/ets/test/List.test.ets b/harmony/api9/acl_one/entry/src/ohosTest/ets/test/List.test.ets similarity index 100% rename from harmony/api9/entry/src/ohosTest/ets/test/List.test.ets rename to harmony/api9/acl_one/entry/src/ohosTest/ets/test/List.test.ets diff --git a/harmony/api9/entry/src/ohosTest/ets/testability/TestAbility.ets b/harmony/api9/acl_one/entry/src/ohosTest/ets/testability/TestAbility.ets similarity index 100% rename from harmony/api9/entry/src/ohosTest/ets/testability/TestAbility.ets rename to harmony/api9/acl_one/entry/src/ohosTest/ets/testability/TestAbility.ets diff --git a/harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets b/harmony/api9/acl_one/entry/src/ohosTest/ets/testability/pages/Index.ets similarity index 100% rename from harmony/api9/entry/src/ohosTest/ets/testability/pages/Index.ets rename to harmony/api9/acl_one/entry/src/ohosTest/ets/testability/pages/Index.ets diff --git a/harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/harmony/api9/acl_one/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts similarity index 100% rename from harmony/api9/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts rename to harmony/api9/acl_one/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts diff --git a/harmony/api9/entry/src/ohosTest/module.json5 b/harmony/api9/acl_one/entry/src/ohosTest/module.json5 similarity index 100% rename from harmony/api9/entry/src/ohosTest/module.json5 rename to harmony/api9/acl_one/entry/src/ohosTest/module.json5 diff --git a/harmony/api9/entry/src/ohosTest/resources/base/element/color.json b/harmony/api9/acl_one/entry/src/ohosTest/resources/base/element/color.json similarity index 100% rename from harmony/api9/entry/src/ohosTest/resources/base/element/color.json rename to harmony/api9/acl_one/entry/src/ohosTest/resources/base/element/color.json diff --git a/harmony/api9/entry/src/ohosTest/resources/base/element/string.json b/harmony/api9/acl_one/entry/src/ohosTest/resources/base/element/string.json similarity index 100% rename from harmony/api9/entry/src/ohosTest/resources/base/element/string.json rename to harmony/api9/acl_one/entry/src/ohosTest/resources/base/element/string.json diff --git a/harmony/api9/entry/src/ohosTest/resources/base/media/icon.png b/harmony/api9/acl_one/entry/src/ohosTest/resources/base/media/icon.png similarity index 100% rename from harmony/api9/entry/src/ohosTest/resources/base/media/icon.png rename to harmony/api9/acl_one/entry/src/ohosTest/resources/base/media/icon.png diff --git a/harmony/api9/entry/src/ohosTest/resources/base/profile/test_pages.json b/harmony/api9/acl_one/entry/src/ohosTest/resources/base/profile/test_pages.json similarity index 100% rename from harmony/api9/entry/src/ohosTest/resources/base/profile/test_pages.json rename to harmony/api9/acl_one/entry/src/ohosTest/resources/base/profile/test_pages.json diff --git a/harmony/api9/hvigor/hvigor-config.json5 b/harmony/api9/acl_one/hvigor/hvigor-config.json5 similarity index 100% rename from harmony/api9/hvigor/hvigor-config.json5 rename to harmony/api9/acl_one/hvigor/hvigor-config.json5 diff --git a/harmony/api9/hvigor/hvigor-wrapper.js b/harmony/api9/acl_one/hvigor/hvigor-wrapper.js similarity index 100% rename from harmony/api9/hvigor/hvigor-wrapper.js rename to harmony/api9/acl_one/hvigor/hvigor-wrapper.js diff --git a/harmony/api9/hvigorfile.ts b/harmony/api9/acl_one/hvigorfile.ts similarity index 100% rename from harmony/api9/hvigorfile.ts rename to harmony/api9/acl_one/hvigorfile.ts diff --git a/harmony/api9/hvigorw b/harmony/api9/acl_one/hvigorw similarity index 100% rename from harmony/api9/hvigorw rename to harmony/api9/acl_one/hvigorw diff --git a/harmony/api9/hvigorw.bat b/harmony/api9/acl_one/hvigorw.bat similarity index 100% rename from harmony/api9/hvigorw.bat rename to harmony/api9/acl_one/hvigorw.bat diff --git a/harmony/api9/oh-package-lock.json5 b/harmony/api9/acl_one/oh-package-lock.json5 similarity index 100% rename from harmony/api9/oh-package-lock.json5 rename to harmony/api9/acl_one/oh-package-lock.json5 diff --git a/harmony/api9/oh-package.json5 b/harmony/api9/acl_one/oh-package.json5 similarity index 90% rename from harmony/api9/oh-package.json5 rename to harmony/api9/acl_one/oh-package.json5 index e27cf522a..5e28606b4 100644 --- a/harmony/api9/oh-package.json5 +++ b/harmony/api9/acl_one/oh-package.json5 @@ -1,5 +1,5 @@ { - "name": "api9", + "name": "acl_one", "version": "1.0.0", "description": "Please describe the basic information.", "main": "", From f17c5ed0940d8a887218129e51e92436b262886a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Wed, 20 Mar 2024 18:09:28 +0800 Subject: [PATCH 06/22] Support harmonyOS. --- lib_acl/src/net/acl_host_port.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_acl/src/net/acl_host_port.c b/lib_acl/src/net/acl_host_port.c index 367212561..ff779ef78 100644 --- a/lib_acl/src/net/acl_host_port.c +++ b/lib_acl/src/net/acl_host_port.c @@ -155,6 +155,8 @@ struct addrinfo *acl_host_addrinfo2(const char *addr, int type, int family) hints.ai_socktype = type; #ifdef ACL_MACOSX hints.ai_flags = AI_DEFAULT; +#elif defined(ACL_OHOS) + hints.ai_flags = 0; #elif defined(ACL_ANDROID) hints.ai_flags = AI_ADDRCONFIG; #elif defined(ACL_WINDOWS) From 3f2c6829588691e309ae0798ea23f86ca9da77af Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Fri, 22 Mar 2024 18:27:06 +0800 Subject: [PATCH 07/22] Don't show warning for dbuf module. --- lib_acl/src/stdlib/memory/acl_dbuf_pool.c | 15 ++++++++++----- lib_fiber/samples/https_server/Makefile | 1 + lib_fiber/samples/https_server/main.cpp | 21 +++++++++++++++++++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib_acl/src/stdlib/memory/acl_dbuf_pool.c b/lib_acl/src/stdlib/memory/acl_dbuf_pool.c index 9569da1f9..8357a727c 100644 --- a/lib_acl/src/stdlib/memory/acl_dbuf_pool.c +++ b/lib_acl/src/stdlib/memory/acl_dbuf_pool.c @@ -47,15 +47,17 @@ ACL_DBUF_POOL *acl_dbuf_pool_create(size_t block_size) memset(&info, 0, sizeof(SYSTEM_INFO)); GetSystemInfo(&info); page_size = info.dwPageSize; - if (page_size <= 0) + if (page_size <= 0) { page_size = 4096; + } #else page_size = 4096; #endif size = (block_size / (size_t) page_size) * (size_t) page_size; - if (size < (size_t) page_size) + if (size < (size_t) page_size) { size = page_size; + } /* xxx: 为了尽量保证在调用 acl_mymalloc 分配内存时为内存页的整数倍, * 需要减去 sizeof(ACL_DBUF) 和 16 字节,其中 16 字节是 acl_mymalloc @@ -78,7 +80,7 @@ ACL_DBUF_POOL *acl_dbuf_pool_create(size_t block_size) pool->head = (ACL_DBUF*) pool->buf; pool->head->next = NULL; pool->head->keep = 1; - pool->head->used = 0; + pool->head->used = 1; pool->head->size = size; pool->head->addr = pool->head->buf; pool->count = 1; @@ -93,10 +95,13 @@ void acl_dbuf_pool_destroy(ACL_DBUF_POOL *pool) while (iter) { tmp = iter; iter = iter->next; - if ((char*) tmp == pool->buf) + if ((char*) tmp == pool->buf) { break; - if (tmp->size > pool->block_size) + } + if (tmp->size > pool->block_size) { pool->huge--; + } + #ifdef USE_VALLOC free(tmp); #else diff --git a/lib_fiber/samples/https_server/Makefile b/lib_fiber/samples/https_server/Makefile index bbed3c0a8..18ecd463d 100644 --- a/lib_fiber/samples/https_server/Makefile +++ b/lib_fiber/samples/https_server/Makefile @@ -1,3 +1,4 @@ include ../Makefile_cpp.in #EXTLIBS = -L../../../lib/linux64 -lpolarssl +#EXTLIBS = -L../../../test/libmm -lmm -Wl,-rpath,../../../test/libmm PROG = httpd diff --git a/lib_fiber/samples/https_server/main.cpp b/lib_fiber/samples/https_server/main.cpp index b1d82cc0e..dc4514db8 100644 --- a/lib_fiber/samples/https_server/main.cpp +++ b/lib_fiber/samples/https_server/main.cpp @@ -9,6 +9,7 @@ static int __rw_timeout = 10; static acl::string __ssl_crt("./ssl_crt.pem"); static acl::string __ssl_key("./ssl_key.pem"); static acl::sslbase_conf* __ssl_conf; +static bool __shared_stack = false; static void http_server(ACL_FIBER *, void *ctx) { @@ -80,6 +81,14 @@ static void fiber_accept(ACL_FIBER *, void *ctx) { const char* addr = (const char* ) ctx; acl::server_socket server; + ACL_FIBER_ATTR attr; + + acl_fiber_attr_init(&attr); + + if (__shared_stack) { + acl_fiber_attr_setstacksize(&attr, 4096); + acl_fiber_attr_setsharestack(&attr, 1); + } ssl_init(*__ssl_conf, __ssl_crt, __ssl_key); @@ -99,7 +108,11 @@ static void fiber_accept(ACL_FIBER *, void *ctx) client->set_rw_timeout(__rw_timeout); printf("accept one: %d\r\n", client->sock_handle()); - acl_fiber_create(http_server, client, STACK_SIZE); + if (__shared_stack) { + acl_fiber_create2(&attr, http_server, client); + } else { + acl_fiber_create(http_server, client, STACK_SIZE); + } } exit (0); @@ -108,6 +121,7 @@ static void fiber_accept(ACL_FIBER *, void *ctx) static void usage(const char* procname) { printf("usage: %s -h [help]\r\n" + " -S [use shared stack]\r\n" " -l ssl_lib_path\r\n" " -s listen_addr\r\n" " -r rw_timeout\r\n" @@ -128,7 +142,7 @@ int main(int argc, char *argv[]) acl::acl_cpp_init(); acl::log::stdout_open(true); - while ((ch = getopt(argc, argv, "hs:r:c:k:l:")) > 0) { + while ((ch = getopt(argc, argv, "hs:r:c:k:l:S")) > 0) { switch (ch) { case 'h': usage(argv[0]); @@ -148,6 +162,9 @@ int main(int argc, char *argv[]) case 'l': libpath = optarg; break; + case 'S': + __shared_stack =true; + break; default: break; } From 1e886b9270199f7566749be02021a9465e1dc2d6 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Fri, 22 Mar 2024 18:55:55 +0800 Subject: [PATCH 08/22] Add conditional compiling for socket write API to avoid blocked when writing data. --- lib_acl/src/stdlib/sys/acl_sys_socket.c | 88 ++++++++++++------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/lib_acl/src/stdlib/sys/acl_sys_socket.c b/lib_acl/src/stdlib/sys/acl_sys_socket.c index 366d7a2fe..be8dc9822 100644 --- a/lib_acl/src/stdlib/sys/acl_sys_socket.c +++ b/lib_acl/src/stdlib/sys/acl_sys_socket.c @@ -145,23 +145,6 @@ int acl_socket_close(ACL_SOCKET fd) int acl_socket_read(ACL_SOCKET fd, void *buf, size_t size, int timeout, ACL_VSTREAM *fp, void *arg acl_unused) { -#if 0 - WSABUF wsaData; - DWORD dwBytes = 0; - DWORD flags = 0; - int ret; - - wsaData.len = (u_long) size; - wsaData.buf = (char*) buf; - ret = WSARecv(fd, &wsaData, 1, &dwBytes, &flags, NULL, NULL); - if (ret == SOCKET_ERROR) { - return -1; - } - if (dwBytes == 0) { - return -1; - } - return dwBytes; -#else if (fp != NULL && fp->read_ready) { fp->read_ready = 0; } else if (timeout > 0) { @@ -174,25 +157,25 @@ int acl_socket_read(ACL_SOCKET fd, void *buf, size_t size, } } -# if defined(_WIN32) || defined(_WIN64) -# ifdef SYS_WSA_API +#if defined(_WIN32) || defined(_WIN64) +# ifdef SYS_WSA_API WSABUF wsabuf; wsabuf.buf = buf; wsabuf.len = (int) size; DWORD flags = 0; return WSARecv(fd, &wsabuf, (int) size, 0, &flags, 0, 0); -# else - return __sys_recv(fd, buf, (int) size, 0); -# endif # else return __sys_recv(fd, buf, (int) size, 0); # endif +#else + return __sys_recv(fd, buf, (int) size, 0); #endif } int acl_socket_write(ACL_SOCKET fd, const void *buf, size_t size, int timeout, ACL_VSTREAM *fp acl_unused, void *arg acl_unused) { +#ifdef ACL_WRITE_FIRST int ret, error; ret = __sys_send(fd, buf, (int) size, 0); @@ -207,13 +190,14 @@ int acl_socket_write(ACL_SOCKET fd, const void *buf, size_t size, error = acl_last_error(); -#if ACL_EWOULDBLOCK == ACL_EAGAIN +# if ACL_EWOULDBLOCK == ACL_EAGAIN if (error != ACL_EWOULDBLOCK) { -#else +# else if (error != ACL_EWOULDBLOCK && error != ACL_EAGAIN) { -#endif +# endif return ret; } +#endif #ifdef ACL_WRITEABLE_CHECK if (fp != NULL && ACL_VSTREAM_IS_MS(fp)) { @@ -225,8 +209,10 @@ int acl_socket_write(ACL_SOCKET fd, const void *buf, size_t size, } return __sys_send(fd, buf, (int) size, 0); -#else +#elif defined(ACL_WRITE_FIRST) return ret; +#else +# error "One of ACL_WRITE_FIRST or ACL_WRITEABLE_CHECK must be defined at least!" #endif } @@ -459,6 +445,7 @@ int acl_socket_read(ACL_SOCKET fd, void *buf, size_t size, int acl_socket_write(ACL_SOCKET fd, const void *buf, size_t size, int timeout, ACL_VSTREAM *fp acl_unused, void *arg acl_unused) { +#ifdef ACL_WRITE_FIRST int ret, error; ret = (int) __sys_write(fd, buf, size); @@ -472,32 +459,38 @@ int acl_socket_write(ACL_SOCKET fd, const void *buf, size_t size, error = acl_last_error(); -#if ACL_EWOULDBLOCK == ACL_EAGAIN +# if ACL_EWOULDBLOCK == ACL_EAGAIN if (error != ACL_EWOULDBLOCK) { -#else +# else if (error != ACL_EWOULDBLOCK && error != ACL_EAGAIN) { -#endif +# endif return ret; } - -#ifdef ACL_WRITEABLE_CHECK - if (fp != NULL && ACL_VSTREAM_IS_MS(fp)) { - if (acl_write_wait_ms(fd, timeout) < 0) { - return -1; - } - } else if (acl_write_wait(fd, timeout) < 0) { - return -1; - } - - ret = __sys_write(fd, buf, size); #endif +#ifdef ACL_WRITEABLE_CHECK + if (timeout > 0) { + if (fp != NULL && ACL_VSTREAM_IS_MS(fp)) { + if (acl_write_wait_ms(fd, timeout) < 0) { + return -1; + } + } else if (acl_write_wait(fd, timeout) < 0) { + return -1; + } + } + + return __sys_write(fd, buf, size); +#elif defined(ACL_WRITE_FIRST) return ret; +#else +# error "One of ACL_WRITE_FIRST or ACL_WRITEABLE_CHECK must be defined at least!" +#endif } int acl_socket_writev(ACL_SOCKET fd, const struct iovec *vec, int count, int timeout, ACL_VSTREAM *fp acl_unused, void *arg acl_unused) { +#ifdef ACL_WRITE_FIRST int ret, error; ret = (int) __sys_writev(fd, vec, count); @@ -511,23 +504,26 @@ int acl_socket_writev(ACL_SOCKET fd, const struct iovec *vec, int count, error = acl_last_error(); -#if ACL_EWOULDBLOCK == ACL_EAGAIN +# if ACL_EWOULDBLOCK == ACL_EAGAIN if (error != ACL_EWOULDBLOCK) { -#else +# else if (error != ACL_EWOULDBLOCK && error != ACL_EAGAIN) { -#endif +# endif return ret; } +#endif #ifdef ACL_WRITEABLE_CHECK if (acl_write_wait(fd, timeout) < 0) { return -1; } - ret = __sys_writev(fd, vec, count); -#endif - + return __sys_writev(fd, vec, count); +#elif defined(ACL_WRITE_FIRST) return ret; +#else +# error "One of ACL_WRITE_FIRST or ACL_WRITEABLE_CHECK must be defined at least!" +#endif } #else From 65f1027941920a42fa27cad25de54a5fe6979965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Sat, 23 Mar 2024 11:18:14 +0800 Subject: [PATCH 09/22] Change type the timer from unsigned to size_t. --- lib_fiber/c/include/fiber/fiber_base.h | 18 +++++------ lib_fiber/c/src/fiber.h | 2 +- lib_fiber/c/src/fiber_io.c | 14 ++++---- lib_fiber/c/src/hook/socket.c | 45 ++++++++++++++++++++++---- lib_fiber/cpp/include/fiber/fiber.hpp | 6 ++-- lib_fiber/cpp/src/fiber.cpp | 2 +- 6 files changed, 60 insertions(+), 27 deletions(-) diff --git a/lib_fiber/c/include/fiber/fiber_base.h b/lib_fiber/c/include/fiber/fiber_base.h index 0319d8fa6..18cc1303d 100644 --- a/lib_fiber/c/include/fiber/fiber_base.h +++ b/lib_fiber/c/include/fiber/fiber_base.h @@ -274,36 +274,36 @@ FIBER_API void acl_fiber_schedule_stop(void); /** * Let the current fiber sleep for a while - * @param milliseconds {unsigned int} the milliseconds to sleep + * @param milliseconds {size_t} the milliseconds to sleep * @return {unsigned int} the rest milliseconds returned after wakeup */ -FIBER_API unsigned int acl_fiber_delay(unsigned int milliseconds); +FIBER_API size_t acl_fiber_delay(size_t milliseconds); /** * Let the current fiber sleep for a while - * @param seconds {unsigned int} the seconds to sleep - * @return {unsigned int} the rest seconds returned after wakeup + * @param seconds {size_t} the seconds to sleep + * @return {size_t} the rest seconds returned after wakeup */ -FIBER_API unsigned int acl_fiber_sleep(unsigned int seconds); +FIBER_API size_t acl_fiber_sleep(size_t seconds); /** * Create one fiber timer - * @param milliseconds {unsigned int} the timer wakeup milliseconds + * @param milliseconds {size_t} the timer wakeup milliseconds * @param size {size_t} the virtual memory of the created fiber * @param fn {void (*)(ACL_FIBER*, void*)} the callback when fiber wakeup * @param ctx {void*} the second parameter of the callback fn * @return {ACL_FIBER*} the new created fiber returned */ -FIBER_API ACL_FIBER* acl_fiber_create_timer(unsigned int milliseconds, +FIBER_API ACL_FIBER* acl_fiber_create_timer(size_t milliseconds, size_t size, void (*fn)(ACL_FIBER*, void*), void* ctx); /** * Reset the timer milliseconds time before the timer fiber wakeup * @param timer {ACL_FIBER*} the fiber created by acl_fiber_create_timer - * @param milliseconds {unsigned int} the new timer wakeup milliseconds + * @param milliseconds {size_t} the new timer wakeup milliseconds * @return {int} return 0 if rest timer success, else return -1 if failed */ -FIBER_API int acl_fiber_reset_timer(ACL_FIBER* timer, unsigned int milliseconds); +FIBER_API int acl_fiber_reset_timer(ACL_FIBER* timer, size_t milliseconds); /** * Set the DNS service addr diff --git a/lib_fiber/c/src/fiber.h b/lib_fiber/c/src/fiber.h index f5f79b826..a6c65a472 100644 --- a/lib_fiber/c/src/fiber.h +++ b/lib_fiber/c/src/fiber.h @@ -129,7 +129,7 @@ int fiber_wait_read(FILE_EVENT *fe); int fiber_wait_write(FILE_EVENT *fe); EVENT *fiber_io_event(void); -void fiber_timer_add(ACL_FIBER *fiber, unsigned milliseconds); +void fiber_timer_add(ACL_FIBER *fiber, size_t milliseconds); int fiber_timer_del(ACL_FIBER *fiber); FILE_EVENT *fiber_file_open(socket_t fd); diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index edd27e501..eee2f2812 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -172,7 +172,7 @@ static long long fiber_io_stamp(void) return event_get_stamp(ev); } -void fiber_timer_add(ACL_FIBER *fiber, unsigned milliseconds) +void fiber_timer_add(ACL_FIBER *fiber, size_t milliseconds) { EVENT *ev = fiber_io_event(); long long now = event_get_stamp(ev); @@ -318,7 +318,7 @@ void fiber_io_clear(void) } } -unsigned int acl_fiber_delay(unsigned int milliseconds) +size_t acl_fiber_delay(size_t milliseconds) { long long now; ACL_FIBER *fiber; @@ -349,7 +349,7 @@ unsigned int acl_fiber_delay(unsigned int milliseconds) return 0; } - return (unsigned int) (now - fiber->when); + return (size_t) (now - fiber->when); } typedef struct { @@ -370,7 +370,7 @@ static void fiber_timer_callback(ACL_FIBER *fiber, void *ctx) break; } - acl_fiber_delay((unsigned int) left); + acl_fiber_delay((size_t) left); now = fiber_io_stamp(); if (fiber->when <= now) { @@ -383,7 +383,7 @@ static void fiber_timer_callback(ACL_FIBER *fiber, void *ctx) fiber_exit(0); } -ACL_FIBER *acl_fiber_create_timer(unsigned int milliseconds, size_t size, +ACL_FIBER *acl_fiber_create_timer(size_t milliseconds, size_t size, void (*fn)(ACL_FIBER *, void *), void *ctx) { long long when; @@ -403,7 +403,7 @@ ACL_FIBER *acl_fiber_create_timer(unsigned int milliseconds, size_t size, return fiber; } -int acl_fiber_reset_timer(ACL_FIBER *fiber, unsigned int milliseconds) +int acl_fiber_reset_timer(ACL_FIBER *fiber, size_t milliseconds) { // The previous timer with the fiber must be removed first. int ret = fiber_timer_del(fiber); @@ -417,7 +417,7 @@ int acl_fiber_reset_timer(ACL_FIBER *fiber, unsigned int milliseconds) return 0; } -unsigned int acl_fiber_sleep(unsigned int seconds) +size_t acl_fiber_sleep(size_t seconds) { return acl_fiber_delay(seconds * 1000) / 1000; } diff --git a/lib_fiber/c/src/hook/socket.c b/lib_fiber/c/src/hook/socket.c index 5635f853c..2e42b5a19 100644 --- a/lib_fiber/c/src/hook/socket.c +++ b/lib_fiber/c/src/hook/socket.c @@ -490,12 +490,12 @@ typedef struct TIMEOUT_CTX { unsigned id; } TIMEOUT_CTX; -static void fiber_timeout(ACL_FIBER *fiber UNUSED, void *ctx) +static void read_timeout(ACL_FIBER *fiber UNUSED, void *ctx) { TIMEOUT_CTX *tc = (TIMEOUT_CTX*) ctx; FILE_EVENT *fe = fiber_file_get(tc->sockfd); - // we must check the fiber carefully here. + // We must check the fiber carefully here. if (fe == NULL || tc->fiber != fe->fiber_r || tc->fiber->fid != fe->fiber_r->fid) { @@ -503,10 +503,32 @@ static void fiber_timeout(ACL_FIBER *fiber UNUSED, void *ctx) return; } - // we can kill the fiber only if the fiber is waiting + // We can kill the fiber only if the fiber is waiting // for readable ore writable of IO process. - if (fe->fiber_r->wstatus & (FIBER_WAIT_READ | FIBER_WAIT_WRITE)) { + if (fe->fiber_r->wstatus & FIBER_WAIT_READ) { + tc->fiber->errnum = FIBER_EAGAIN; + acl_fiber_signal(tc->fiber, SIGINT); + } + mem_free(ctx); +} + +static void send_timeout(ACL_FIBER *fiber UNUSED, void *ctx) +{ + TIMEOUT_CTX *tc = (TIMEOUT_CTX*) ctx; + FILE_EVENT *fe = fiber_file_get(tc->sockfd); + + // We must check the fiber carefully here. + if (fe == NULL || tc->fiber != fe->fiber_w + || tc->fiber->fid != fe->fiber_w->fid) { + + mem_free(ctx); + return; + } + + // We can kill the fiber only if the fiber is waiting + // for readable ore writable of IO process. + if (fe->fiber_w->wstatus & FIBER_WAIT_READ) { tc->fiber->errnum = FIBER_EAGAIN; acl_fiber_signal(tc->fiber, SIGINT); } @@ -564,8 +586,19 @@ int setsockopt(int sockfd, int level, int optname, ctx = (TIMEOUT_CTX*) mem_malloc(sizeof(TIMEOUT_CTX)); ctx->fiber = acl_fiber_running(); ctx->sockfd = sockfd; - acl_fiber_create_timer((unsigned) val * 1000, 64000, fiber_timeout, ctx); - return 0; + + if (optname == SO_RCVTIMEO) { + val *= 1000; + acl_fiber_create_timer(val, 4096, read_timeout, ctx); + return 0; + } else if (optname == SO_SNDTIMEO) { + val *= 1000; + acl_fiber_create_timer(val, 4096, send_timeout, ctx); + return 0; + } else { + msg_error("Invalid optname=%d", optname); + return -1; + } } #endif diff --git a/lib_fiber/cpp/include/fiber/fiber.hpp b/lib_fiber/cpp/include/fiber/fiber.hpp index 0200a6241..a1bad8c65 100644 --- a/lib_fiber/cpp/include/fiber/fiber.hpp +++ b/lib_fiber/cpp/include/fiber/fiber.hpp @@ -202,10 +202,10 @@ public: /** * 使当前运行的协程休眠指定毫秒数 - * @param milliseconds {unsigned int} 指定要休眠的毫秒数 - * @return {unsigned int} 本协程休眠后再次被唤醒后剩余的毫秒数 + * @param milliseconds {size_t} 指定要休眠的毫秒数 + * @return {size_t} 本协程休眠后再次被唤醒后剩余的毫秒数 */ - static unsigned int delay(unsigned int milliseconds); + static size_t delay(size_t milliseconds); /** * 获得处于存活状态的协程数量 diff --git a/lib_fiber/cpp/src/fiber.cpp b/lib_fiber/cpp/src/fiber.cpp index 830ef2a7b..e2aa6cac3 100644 --- a/lib_fiber/cpp/src/fiber.cpp +++ b/lib_fiber/cpp/src/fiber.cpp @@ -102,7 +102,7 @@ void fiber::ready(fiber& f) } } -unsigned int fiber::delay(unsigned int milliseconds) +size_t fiber::delay(size_t milliseconds) { return acl_fiber_delay(milliseconds); } From 369b7b10389f7b86dca696ad18cb7bf71ee27591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Sat, 23 Mar 2024 15:27:36 +0800 Subject: [PATCH 10/22] Optimize IO cancel process in fiber module. --- lib_fiber/c/src/common/timer_cache.c | 6 ++++ lib_fiber/c/src/fiber_io.c | 18 +++++++++++ lib_fiber/c/src/hook/fiber_read.c | 4 +-- lib_fiber/samples/timer_server/main.c | 45 +++++++++++++++++---------- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/lib_fiber/c/src/common/timer_cache.c b/lib_fiber/c/src/common/timer_cache.c index fb3773c38..9fcd5c184 100644 --- a/lib_fiber/c/src/common/timer_cache.c +++ b/lib_fiber/c/src/common/timer_cache.c @@ -104,12 +104,18 @@ int timer_cache_remove(TIMER_CACHE *cache, long long expire, RING *entry) } if (entry->parent != &node->ring) { + // Maybe the fiber has been append to the other ring. + if (ring_size(&node->ring) == 0) { + timer_cache_free_node(cache, node); + } return 0; } + // Detach the fiber from the current timer node. ring_detach(entry); if (ring_size(&node->ring) == 0) { + // If the timer node is empty, just free it now. timer_cache_free_node(cache, node); } return 1; diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index eee2f2812..192ae9d93 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -223,6 +223,11 @@ static void wakeup_timers(TIMER_CACHE *timers, long long now) // Set the flag that the fiber wakeuped for the // timer's arriving. fb->flag |= FIBER_F_TIMER; + + // The fb->me was be appended in fiber_timer_add, and + // we detatch fb->me from timer node and append it to + // the ready ring in acl_fiber_ready. + ring_detach(&fb->me); acl_fiber_ready(fb); } @@ -343,6 +348,13 @@ size_t acl_fiber_delay(size_t milliseconds) // Clear the flag been set in wakeup_timers. fiber->flag &= ~FIBER_F_TIMER; + if (acl_fiber_killed(fiber)) { + // If been killed, the fiber must has been detatched from the + // timer node in acl_fiber_signal(); We call fiber_timer_del + // here in order to try to free the timer node. + fiber_timer_del(fiber); + } + ev = fiber_io_event(); now = event_get_stamp(ev); if (now <= fiber->when) { @@ -484,8 +496,13 @@ int fiber_wait_read(FILE_EVENT *fe) if (acl_fiber_canceled(curr)) { acl_fiber_set_error(curr->errnum); + // If the IO has been canceled, we should try to remove the + // IO read event, because the wakeup process wasn't from + // read_callback normally. + event_del_read(__thread_fiber->event, fe); return -1; } + // else: the IO read event should has been removed in read_callback. return ret; } @@ -541,6 +558,7 @@ int fiber_wait_write(FILE_EVENT *fe) if (acl_fiber_canceled(curr)) { acl_fiber_set_error(curr->errnum); + event_del_write(__thread_fiber->event, fe); return -1; } diff --git a/lib_fiber/c/src/hook/fiber_read.c b/lib_fiber/c/src/hook/fiber_read.c index bce571fe4..5ebec9c17 100644 --- a/lib_fiber/c/src/hook/fiber_read.c +++ b/lib_fiber/c/src/hook/fiber_read.c @@ -201,8 +201,8 @@ int fiber_iocp_read(FILE_EVENT *fe, char *buf, int len) #define FILE_ALLOC(f, t, fd) do { \ (f) = file_event_alloc(fd); \ - (f)->mask = (t); \ - (f)->type = TYPE_EVENTABLE; \ + (f)->mask = (t); \ + (f)->type = TYPE_EVENTABLE; \ } while (0) #ifdef SYS_UNIX diff --git a/lib_fiber/samples/timer_server/main.c b/lib_fiber/samples/timer_server/main.c index 510d55803..d42379ab9 100644 --- a/lib_fiber/samples/timer_server/main.c +++ b/lib_fiber/samples/timer_server/main.c @@ -5,7 +5,8 @@ #include #include "fiber/libfiber.h" -static int __rw_timeout = 0; +static int __rw_timeout = 5; +static time_t __last = 0; typedef struct { ACL_FIBER *fiber; @@ -16,17 +17,20 @@ typedef struct { static void io_timer(ACL_FIBER *fiber, void *ctx) { FIBER_TIMER *ft = (FIBER_TIMER *) ctx; + time_t now = time(NULL); assert(fiber == ft->timer); acl_fiber_set_errno(ft->fiber, FIBER_ETIME); acl_fiber_keep_errno(ft->fiber, 1); - printf("timer-%d wakeup, set fiber-%d, errno: %d, %d\r\n", - acl_fiber_id(fiber), acl_fiber_id(ft->fiber), - FIBER_ETIME, acl_fiber_errno(ft->fiber)); + printf("timer-%d wakeup: cost %ld seconds, set fiber-%d, errno: %d, %d, %s\r\n", + acl_fiber_id(fiber), now - __last, acl_fiber_id(ft->fiber), + FIBER_ETIME, acl_fiber_errno(ft->fiber), acl_fiber_last_serror()); - acl_fiber_ready(ft->fiber); + __last = now; + //acl_fiber_ready(ft->fiber); + acl_fiber_signal(ft->fiber, SIGINT); } static void echo_client(ACL_FIBER *fiber, void *ctx) @@ -45,8 +49,11 @@ static void echo_client(ACL_FIBER *fiber, void *ctx) #define SOCK ACL_VSTREAM_SOCK while (1) { + __last = time(NULL); + printf("begin read\n"); ret = acl_vstream_gets(cstream, buf, sizeof(buf) - 1); + printf("read return: %d\r\n", ret); if (ret == ACL_VSTREAM_EOF) { printf("fiber-%d, gets error: %s, %d, %d, fd: %d, " @@ -54,30 +61,34 @@ static void echo_client(ACL_FIBER *fiber, void *ctx) acl_last_serror(), errno, acl_fiber_errno(fiber), SOCK(cstream), count); - if (errno != FIBER_ETIME) + if (errno != FIBER_ETIME) { + printf("Some error happened!\r\n"); break; + } - if (++ntimeout > 2) - { + if (++ntimeout > 2) { printf("too many timeout: %d\r\n", ntimeout); break; } - printf("ntimeout: %d\r\n", ntimeout); - ft->timer = acl_fiber_create_timer(__rw_timeout * 1000, - 320000, io_timer, ft); + printf("Timeout count: %d\r\n", ntimeout); } - acl_fiber_reset_timer(ft->timer, __rw_timeout * 1000); - buf[ret] = 0; - //printf("gets line: %s", buf); + if (ret > 0) { + buf[ret] = 0; + //printf("gets line: %s", buf); - if (acl_vstream_writen(cstream, buf, ret) == ACL_VSTREAM_EOF) { - printf("write error, fd: %d\r\n", SOCK(cstream)); - break; + if (acl_vstream_writen(cstream, buf, ret) == ACL_VSTREAM_EOF) { + printf("write error, fd: %d\r\n", SOCK(cstream)); + break; + } } count++; + + acl_fiber_clear(ft->fiber); + acl_fiber_reset_timer(ft->timer, __rw_timeout * 1000); + printf("\r\n"); } acl_myfree(ft); From 904dfc103fc82a5fe60e5d85d7edc8f88ca8ade1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Sat, 23 Mar 2024 16:49:39 +0800 Subject: [PATCH 11/22] make wakeup_waiter more safety when timeout. --- lib_fiber/c/src/sync/sync_timer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_fiber/c/src/sync/sync_timer.c b/lib_fiber/c/src/sync/sync_timer.c index a37cdb681..209f51474 100644 --- a/lib_fiber/c/src/sync/sync_timer.c +++ b/lib_fiber/c/src/sync/sync_timer.c @@ -72,11 +72,13 @@ static void wakeup_waiter(SYNC_TIMER *timer UNUSED, SYNC_OBJ *obj) // The fiber must has been awakened by the other fiber or thread. if (obj->delay < 0) { - // No timer has been set if delay < 0, + // No timer has been set if delay < 0, + ring_detach(&obj->fb->me); // Safety detatch me from others. acl_fiber_ready(obj->fb); } else if (fiber_timer_del(obj->fb) == 1) { // Wakeup the waiting fiber before the timer arrives, // just remove it from the timer. + ring_detach(&obj->fb->me); // Safety detatch me from others. acl_fiber_ready(obj->fb); } // else: The fiber has been awakened by the timer. From 1900bda15257516af0e46fd49798e26d4e9d5a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Sat, 23 Mar 2024 16:50:26 +0800 Subject: [PATCH 12/22] Optimize IO timeout for hook API setsockopt(). --- lib_fiber/c/src/fiber_io.c | 22 ++++++++++++++++++++-- lib_fiber/c/src/hook/socket.c | 12 ++++++++++++ lib_fiber/samples/fiber_stack/main.c | 5 ++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index 192ae9d93..9a8991585 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -495,11 +495,21 @@ int fiber_wait_read(FILE_EVENT *fe) } if (acl_fiber_canceled(curr)) { - acl_fiber_set_error(curr->errnum); // If the IO has been canceled, we should try to remove the // IO read event, because the wakeup process wasn't from // read_callback normally. event_del_read(__thread_fiber->event, fe); + acl_fiber_set_error(curr->errnum); + return -1; + } else if (curr->flag & FIBER_F_TIMER) { + // If the IO reading timeout set in setsockopt. + curr->flag &= ~FIBER_F_TIMER; + event_del_read(__thread_fiber->event, fe); + acl_fiber_set_errno(curr, FIBER_ETIME); + acl_fiber_set_error(FIBER_ETIME); + + acl_fiber_set_errno(curr, FIBER_EAGAIN); + acl_fiber_set_error(FIBER_EAGAIN); return -1; } // else: the IO read event should has been removed in read_callback. @@ -557,8 +567,16 @@ int fiber_wait_write(FILE_EVENT *fe) } if (acl_fiber_canceled(curr)) { - acl_fiber_set_error(curr->errnum); event_del_write(__thread_fiber->event, fe); + acl_fiber_set_error(curr->errnum); + return -1; + } else if (curr->flag & FIBER_F_TIMER) { + curr->flag &= ~FIBER_F_TIMER; + event_del_write(__thread_fiber->event, fe); + //acl_fiber_set_errno(curr, FIBER_EAGAIN); + //acl_fiber_set_error(FIBER_EAGAIN); + acl_fiber_set_errno(curr, FIBER_ETIME); + acl_fiber_set_error(FIBER_ETIME); return -1; } diff --git a/lib_fiber/c/src/hook/socket.c b/lib_fiber/c/src/hook/socket.c index 2e42b5a19..6e3b0932d 100644 --- a/lib_fiber/c/src/hook/socket.c +++ b/lib_fiber/c/src/hook/socket.c @@ -484,6 +484,8 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) return acl_fiber_connect(sockfd, addr, addrlen); } +#ifdef CREAT_TIMER_FIBER + typedef struct TIMEOUT_CTX { ACL_FIBER *fiber; int sockfd; @@ -536,11 +538,15 @@ static void send_timeout(ACL_FIBER *fiber UNUSED, void *ctx) mem_free(ctx); } +#endif // CREAT_TIMER_FIBER + int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { size_t val; +#ifdef CREAT_TIMER_FIBER TIMEOUT_CTX *ctx; +#endif const struct timeval *tm; if (sys_setsockopt == NULL) { @@ -583,6 +589,7 @@ int setsockopt(int sockfd, int level, int optname, return -1; } +#ifdef CREAT_TIMER_FIBER ctx = (TIMEOUT_CTX*) mem_malloc(sizeof(TIMEOUT_CTX)); ctx->fiber = acl_fiber_running(); ctx->sockfd = sockfd; @@ -599,6 +606,11 @@ int setsockopt(int sockfd, int level, int optname, msg_error("Invalid optname=%d", optname); return -1; } +#else + val *= 1000; + fiber_timer_add(acl_fiber_running(), val); + return 0; +#endif } #endif diff --git a/lib_fiber/samples/fiber_stack/main.c b/lib_fiber/samples/fiber_stack/main.c index 3c9ee68e1..fcb9ebef4 100644 --- a/lib_fiber/samples/fiber_stack/main.c +++ b/lib_fiber/samples/fiber_stack/main.c @@ -6,7 +6,7 @@ #include "fiber/libfiber.h" static int __stack_size = 320000; -static int __rw_timeout = 0; +static int __rw_timeout = 5; static int __echo_data = 0; static int __setsockopt_timeout = 0; @@ -78,6 +78,7 @@ static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx) break; } +#if 0 ret = acl_vstream_gets(cstream, buf, sizeof(buf) - 1); if (ret == ACL_VSTREAM_EOF) { printf("get first line error\r\n"); @@ -88,6 +89,7 @@ static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx) acl_vstream_close(cstream); continue; } +#endif //printf("accept one, fd: %d\r\n", ACL_VSTREAM_SOCK(cstream)); acl_fiber_create(echo_client, cstream, __stack_size); @@ -183,6 +185,7 @@ int main(int argc, char *argv[]) __listen_fiber = acl_fiber_create(fiber_accept, sstream, 327680); + if (0) acl_fiber_create(fiber_sleep, NULL, 327680); printf("call fiber_schedule\r\n"); From 581ea2eca01d6b0757848a2223daddafc6fbbe6a Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Sun, 24 Mar 2024 09:18:30 +0800 Subject: [PATCH 13/22] Optimize IO timeout process by setsockopt. --- lib_fiber/c/src/fiber.c | 9 ++++++++- lib_fiber/c/src/fiber_io.c | 9 +++------ lib_fiber/samples/fiber_stack/main.c | 4 +++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib_fiber/c/src/fiber.c b/lib_fiber/c/src/fiber.c index 9fb33b398..646984247 100644 --- a/lib_fiber/c/src/fiber.c +++ b/lib_fiber/c/src/fiber.c @@ -472,7 +472,10 @@ static void fiber_signal(ACL_FIBER *fiber, int signum, int sync) // Just only wakeup the suspended fiber. if (fiber->status == FIBER_STATUS_SUSPEND) { +#if 0 + // The fiber will be detached at first in acl_fiber_ready. ring_detach(&fiber->me); // This is safety! +#endif acl_fiber_ready(fiber); @@ -526,10 +529,14 @@ void fiber_exit(int exit_code) void acl_fiber_ready(ACL_FIBER *fiber) { if (fiber->status != FIBER_STATUS_EXITING) { +#if 0 if (fiber->status == FIBER_STATUS_READY) { ring_detach(&fiber->me); } - +#else + // Detache the other binding before such as timer binding. + ring_detach(&fiber->me); +#endif fiber->status = FIBER_STATUS_READY; assert(__thread_fiber); ring_prepend(&__thread_fiber->ready, &fiber->me); diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index 9a8991585..0f8c32476 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -505,8 +505,6 @@ int fiber_wait_read(FILE_EVENT *fe) // If the IO reading timeout set in setsockopt. curr->flag &= ~FIBER_F_TIMER; event_del_read(__thread_fiber->event, fe); - acl_fiber_set_errno(curr, FIBER_ETIME); - acl_fiber_set_error(FIBER_ETIME); acl_fiber_set_errno(curr, FIBER_EAGAIN); acl_fiber_set_error(FIBER_EAGAIN); @@ -573,10 +571,9 @@ int fiber_wait_write(FILE_EVENT *fe) } else if (curr->flag & FIBER_F_TIMER) { curr->flag &= ~FIBER_F_TIMER; event_del_write(__thread_fiber->event, fe); - //acl_fiber_set_errno(curr, FIBER_EAGAIN); - //acl_fiber_set_error(FIBER_EAGAIN); - acl_fiber_set_errno(curr, FIBER_ETIME); - acl_fiber_set_error(FIBER_ETIME); + + acl_fiber_set_errno(curr, FIBER_EAGAIN); + acl_fiber_set_error(FIBER_EAGAIN); return -1; } diff --git a/lib_fiber/samples/fiber_stack/main.c b/lib_fiber/samples/fiber_stack/main.c index fcb9ebef4..04a98b866 100644 --- a/lib_fiber/samples/fiber_stack/main.c +++ b/lib_fiber/samples/fiber_stack/main.c @@ -32,6 +32,8 @@ static void echo_client(ACL_FIBER *fiber acl_unused, void *ctx) #endif printf("%s: setsockopt error: %s\r\n", __FUNCTION__, acl_last_serror()); + } else { + printf("%s: setsockopt ok for readtimeout\r\n", __FUNCTION__); } } @@ -78,7 +80,7 @@ static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx) break; } -#if 0 +#if 1 ret = acl_vstream_gets(cstream, buf, sizeof(buf) - 1); if (ret == ACL_VSTREAM_EOF) { printf("get first line error\r\n"); From a9f32a8b9174a3c050d6dad51cd820455a41d2e1 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Sun, 24 Mar 2024 09:46:48 +0800 Subject: [PATCH 14/22] Add one demo for testing setsockopt. --- lib_fiber/samples/setsockopt/Makefile | 2 + lib_fiber/samples/setsockopt/echo_client.c | 58 ++++++++++++++ lib_fiber/samples/setsockopt/echo_client.h | 6 ++ lib_fiber/samples/setsockopt/main.c | 88 ++++++++++++++++++++++ lib_fiber/samples/setsockopt/stdafx.h | 11 +++ 5 files changed, 165 insertions(+) create mode 100644 lib_fiber/samples/setsockopt/Makefile create mode 100644 lib_fiber/samples/setsockopt/echo_client.c create mode 100644 lib_fiber/samples/setsockopt/echo_client.h create mode 100644 lib_fiber/samples/setsockopt/main.c create mode 100644 lib_fiber/samples/setsockopt/stdafx.h diff --git a/lib_fiber/samples/setsockopt/Makefile b/lib_fiber/samples/setsockopt/Makefile new file mode 100644 index 000000000..19cf1996e --- /dev/null +++ b/lib_fiber/samples/setsockopt/Makefile @@ -0,0 +1,2 @@ +include ../Makefile.in +PROG = server diff --git a/lib_fiber/samples/setsockopt/echo_client.c b/lib_fiber/samples/setsockopt/echo_client.c new file mode 100644 index 000000000..0187bd58c --- /dev/null +++ b/lib_fiber/samples/setsockopt/echo_client.c @@ -0,0 +1,58 @@ +#include "stdafx.h" +#include "echo_client.h" + +static void set_timeout(ACL_VSTREAM *cstream, int rw_timeout) +{ + struct timeval tm; + tm.tv_sec = rw_timeout; + tm.tv_usec = 0; + +#if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) + if (setsockopt(ACL_VSTREAM_SOCK(cstream), SOL_SOCKET, + SO_RCVTIMEO, &__rw_timeout, sizeof(__rw_timeout)) < 0) { +#else + if (setsockopt(ACL_VSTREAM_SOCK(cstream), SOL_SOCKET, + SO_RCVTIMEO, &tm, sizeof(tm)) < 0) { +#endif + printf("%s: setsockopt error: %s\r\n", + __FUNCTION__, acl_last_serror()); + } +} + +void echo_client(ACL_VSTREAM *cstream, int rw_timeout, int echo_data) +{ + char buf[8192]; + int ret, count = 0; + +#define SOCK ACL_VSTREAM_SOCK + + while (1) { + if (rw_timeout > 0) { + set_timeout(cstream, rw_timeout); + } + + ret = acl_vstream_read(cstream, buf, sizeof(buf) - 1); + if (ret == ACL_VSTREAM_EOF) { + printf("gets error: %s, fd: %d, count: %d\r\n", + acl_last_serror(), SOCK(cstream), count); + break; + } + buf[ret] = 0; + //printf("gets line: %s", buf); + + if (!echo_data) { + count++; + continue; + } + + if (acl_vstream_writen(cstream, buf, ret) == ACL_VSTREAM_EOF) { + printf("write error, fd: %d\r\n", SOCK(cstream)); + break; + } + + count++; + //printf("count=%d\n", count); + } + + acl_vstream_close(cstream); +} diff --git a/lib_fiber/samples/setsockopt/echo_client.h b/lib_fiber/samples/setsockopt/echo_client.h new file mode 100644 index 000000000..b89b48a39 --- /dev/null +++ b/lib_fiber/samples/setsockopt/echo_client.h @@ -0,0 +1,6 @@ +#ifndef __ECHO_CLIENT_INCLUDE_H__ +#define __ECHO_CLIENT_INCLUDE_H__ + +void echo_client(ACL_VSTREAM *cstream, int rw_timeout, int echo_data); + +#endif diff --git a/lib_fiber/samples/setsockopt/main.c b/lib_fiber/samples/setsockopt/main.c new file mode 100644 index 000000000..33b7a578b --- /dev/null +++ b/lib_fiber/samples/setsockopt/main.c @@ -0,0 +1,88 @@ +#include "stdafx.h" +#include "echo_client.h" + +static int __stack_size = 320000; +static int __rw_timeout = 5; +static int __echo_data = 0; + +static void fiber_client(ACL_FIBER *fiber acl_unused, void *ctx) +{ + ACL_VSTREAM *cstream = (ACL_VSTREAM *) ctx; + echo_client(cstream, __rw_timeout, __echo_data); +} + +static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx) +{ + ACL_VSTREAM *sstream = (ACL_VSTREAM *) ctx; + + for (;;) { + ACL_VSTREAM *cstream = acl_vstream_accept(sstream, NULL, 0); + if (cstream == NULL) { + printf("acl_vstream_accept error %s\r\n", + acl_last_serror()); + break; + } + + acl_fiber_create(fiber_client, cstream, __stack_size); + } + + acl_vstream_close(sstream); +} + +static void usage(const char *procname) +{ + printf("usage: %s -h [help]\r\n" + " -s listen_addr\r\n" + " -r rw_timeout [default: 5]\r\n" + " -z stack_size\r\n" + " -w [if echo data, default: no]\r\n", procname); +} + +int main(int argc, char *argv[]) +{ + char addr[64]; + ACL_VSTREAM *sstream; + int ch, qlen = 128; + + acl_msg_stdout_enable(1); + acl_fiber_msg_stdout_enable(1); + + snprintf(addr, sizeof(addr), "%s", "127.0.0.1:9002"); + + while ((ch = getopt(argc, argv, "hs:r:wz:")) > 0) { + switch (ch) { + case 'h': + usage(argv[0]); + return 0; + case 's': + snprintf(addr, sizeof(addr), "%s", optarg); + break; + case 'r': + __rw_timeout = atoi(optarg); + break; + case 'w': + __echo_data = 1; + break; + case 'z': + __stack_size = atoi(optarg); + break; + default: + break; + } + } + + sstream = acl_vstream_listen(addr, qlen); + if (sstream == NULL) { + printf("acl_vstream_listen error %s\r\n", acl_last_serror()); + return 1; + } + + printf("listen %s ok\r\n", addr); + + acl_fiber_create(fiber_accept, sstream, 327680); + + printf("call fiber_schedule\r\n"); + acl_fiber_schedule(); + + return 0; +} diff --git a/lib_fiber/samples/setsockopt/stdafx.h b/lib_fiber/samples/setsockopt/stdafx.h new file mode 100644 index 000000000..a240f568d --- /dev/null +++ b/lib_fiber/samples/setsockopt/stdafx.h @@ -0,0 +1,11 @@ +#ifndef __STDAFX_INCLUDE_H__ +#define __STDAFX_INCLUDE_H__ + +#include "lib_acl.h" +#include +#include +#include +#include +#include "fiber/libfiber.h" + +#endif From db39550fe4d5849ff1561459d7a79fa734bb8091 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 09:46:53 +0800 Subject: [PATCH 15/22] Test OpenSSL --- lib_fiber/samples/ssl_client/main.cpp | 23 ++++++++++++--- lib_fiber/samples/ssl_client/t.sh | 2 +- lib_fiber/samples/ssl_server/main.cpp | 40 +++++++++++++++++++++++---- lib_fiber/samples/ssl_server/t.sh | 2 +- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/lib_fiber/samples/ssl_client/main.cpp b/lib_fiber/samples/ssl_client/main.cpp index 596d15ee1..1c2a162b9 100644 --- a/lib_fiber/samples/ssl_client/main.cpp +++ b/lib_fiber/samples/ssl_client/main.cpp @@ -23,7 +23,7 @@ static bool ssl_init(acl::socket_stream& conn) { assert(__ssl_conf); - acl::sslbase_io* ssl = __ssl_conf->open(false, false); + acl::sslbase_io* ssl = __ssl_conf->create(false); if (conn.setup_hook(ssl) == ssl) { printf("setup_hook error\r\n"); @@ -32,7 +32,7 @@ static bool ssl_init(acl::socket_stream& conn) } if (!__check_ssl) { - printf("ssl handshake_ok\r\n"); + printf("ssl handshake ok, no check ssl\r\n"); return true; } @@ -47,7 +47,7 @@ static bool ssl_init(acl::socket_stream& conn) return false; } - printf("ssl handshake_ok\r\n"); + printf("ssl handshake ok\r\n"); return true; } @@ -202,11 +202,26 @@ int main(int argc, char *argv[]) } } else if (libpath.find("polarssl") != NULL) { acl::polarssl_conf::set_libpath(libpath); - if (!acl::polarssl_conf::load()) { + if (acl::polarssl_conf::load()) { __ssl_conf = new acl::polarssl_conf; } else { printf("load %s error\r\n", libpath.c_str()); } + } else if (libpath.find("crypto") != NULL) { + const std::vector& libs = libpath.split2("; \t"); + if (libs.size() != 2) { + printf("invalid libpath=%s\r\n", libpath.c_str()); + return 1; + } + acl::openssl_conf::set_libpath(libs[0], libs[1]); + if (acl::openssl_conf::load()) { + __ssl_conf = new acl::openssl_conf(false); + } else { + printf("load %s error\r\n", libpath.c_str()); + } + } else { + printf("invalid libpath=%s\r\n", libpath.c_str()); + return 1; } gettimeofday(&__begin, NULL); diff --git a/lib_fiber/samples/ssl_client/t.sh b/lib_fiber/samples/ssl_client/t.sh index 62d0eb432..961afb778 100755 --- a/lib_fiber/samples/ssl_client/t.sh +++ b/lib_fiber/samples/ssl_client/t.sh @@ -4,5 +4,5 @@ os=$(echo `uname -s`) if [ $os == "Darwin" ]; then ./client -l "../libmbedcrypto.dylib;../libmbedx509.dylib;../libmbedtls.dylib" -c 200 -n 10000 else - ./client -l "../libmbedcrypto.so;../libmbedx509.so;../libmbedtls.so" -c 200 -n 10000 + ./client -l "/usr/local/lib64/libcrypto.so; /usr/local/lib64/libssl.so" -c 200 -n 10000 fi diff --git a/lib_fiber/samples/ssl_server/main.cpp b/lib_fiber/samples/ssl_server/main.cpp index 7890bd05d..e0fec8a55 100644 --- a/lib_fiber/samples/ssl_server/main.cpp +++ b/lib_fiber/samples/ssl_server/main.cpp @@ -4,7 +4,7 @@ #define STACK_SIZE 128000 -static int __rw_timeout = 0; +static int __rw_timeout = 5; static acl::string __ssl_crt("./ssl_crt.pem"); static acl::string __ssl_key("./ssl_key.pem"); static acl::sslbase_conf *__ssl_conf = NULL; @@ -63,15 +63,31 @@ static void echo_fiber(ACL_FIBER *, void *ctx) delete conn; } -static acl::sslbase_conf* ssl_init(bool use_mbedtls, const acl::string& crt, +enum ssl_type_t { + ssl_type_openssl, + ssl_type_mbedtls, + ssl_type_polarssl, +}; + +static acl::sslbase_conf* ssl_init(ssl_type_t type, const acl::string& crt, const acl::string& key) { acl::sslbase_conf* conf; - if (use_mbedtls) { + switch (type) { + case ssl_type_openssl: + conf = new acl::openssl_conf(true); + break; + case ssl_type_mbedtls: conf = new acl::mbedtls_conf(true); - } else { + break; + case ssl_type_polarssl: conf = new acl::polarssl_conf; + break; + default: + printf("Unknown ssl type=%d\r\n", (int) type); + return NULL; } + conf->enable_cache(1); if (!conf->add_cert(crt)) { @@ -180,14 +196,26 @@ int main(int argc, char *argv[]) printf("load %s error\r\n", libpath.c_str()); return 1; } - __ssl_conf = ssl_init(true, __ssl_crt, __ssl_key); + __ssl_conf = ssl_init(ssl_type_mbedtls, __ssl_crt, __ssl_key); } else if (libpath.find("polarssl") != NULL) { acl::polarssl_conf::set_libpath(libpath); if (!acl::polarssl_conf::load()) { printf("load %s error\r\n", libpath.c_str()); return 1; } - __ssl_conf = ssl_init(false, __ssl_crt, __ssl_key); + __ssl_conf = ssl_init(ssl_type_polarssl, __ssl_crt, __ssl_key); + } else if (libpath.find("crypto") != NULL) { + const std::vector& libs = libpath.split2("; \t"); + if (libs.size() != 2) { + printf("invalid libpath=%s\r\n", libpath.c_str()); + return 1; + } + acl::openssl_conf::set_libpath(libs[0], libs[1]); + if (!acl::openssl_conf::load()) { + printf("load %s error\r\n", libpath.c_str()); + return 1; + } + __ssl_conf = ssl_init(ssl_type_openssl, __ssl_crt, __ssl_key); } else { printf("invalid libpath=%s\r\n", libpath.c_str()); return 1; diff --git a/lib_fiber/samples/ssl_server/t.sh b/lib_fiber/samples/ssl_server/t.sh index 38e6304b3..dccce4b43 100755 --- a/lib_fiber/samples/ssl_server/t.sh +++ b/lib_fiber/samples/ssl_server/t.sh @@ -4,5 +4,5 @@ os=$(echo `uname -s`) if [ $os == "Darwin" ]; then ./server -l "../libmbedcrypto.dylib;../libmbedx509.dylib;../libmbedtls.dylib" -c ./ssl_crt.pem -k ./ssl_key.pem else - ./server -l "../libmbedcrypto.so;../libmbedx509.so;../libmbedtls.so" -c ./ssl_crt.pem -k ./ssl_key.pem + ./server -l "/usr/local/lib64/libcrypto.so; /usr/local/lib64/libssl.so" -c ./ssl_crt.pem -k ./ssl_key.pem fi From c3d26188fd6354693f233de0bbbabe1da3901847 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 11:37:33 +0800 Subject: [PATCH 16/22] Test OpenSSL. --- .../samples/ssl/https_request/main.cpp | 4 ++-- lib_acl_cpp/samples/ssl/https_request/t.sh | 6 +++--- lib_acl_cpp/src/stream/openssl_io.cpp | 14 +++++++++---- lib_fiber/samples/https_client/main.cpp | 2 +- lib_fiber/samples/ssl_client/main.cpp | 20 +++++++++++++++++-- lib_fiber/samples/ssl_server/main.cpp | 11 ++++++---- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lib_acl_cpp/samples/ssl/https_request/main.cpp b/lib_acl_cpp/samples/ssl/https_request/main.cpp index f0904881a..5e8bdb12d 100644 --- a/lib_acl_cpp/samples/ssl/https_request/main.cpp +++ b/lib_acl_cpp/samples/ssl/https_request/main.cpp @@ -66,15 +66,15 @@ int main(int argc, char* argv[]) acl::sslbase_conf* ssl_conf = NULL; if (libpath.find("mbedtls")) { - ssl_conf = new acl::mbedtls_conf(false); acl::mbedtls_conf::set_libpath(libpath.c_str()); + ssl_conf = new acl::mbedtls_conf(false); if (!acl::mbedtls_conf::load()) { printf("load %s error\r\n", libpath.c_str()); return 1; } } else if (libpath.find("polarssl")) { - ssl_conf = new acl::polarssl_conf; acl::polarssl_conf::set_libpath(libpath); + ssl_conf = new acl::polarssl_conf; if (!acl::polarssl_conf::load()) { printf("load %s error\r\n", libpath.c_str()); return 1; diff --git a/lib_acl_cpp/samples/ssl/https_request/t.sh b/lib_acl_cpp/samples/ssl/https_request/t.sh index fcd2e0570..4f67abdf4 100755 --- a/lib_acl_cpp/samples/ssl/https_request/t.sh +++ b/lib_acl_cpp/samples/ssl/https_request/t.sh @@ -8,11 +8,11 @@ if [ $os == 'Darwin' ]; then echo "" ./https_request -f "../libmbedtls_all.dylib" -s echo.websocket.org:443 -S else - ./https_request -f "../libmbedcrypto.so;../libmbedx509.so;../libmbedtls.so" -s www.sina.com.cn:443 -S + ./https_request -f "../libmbedtls_all.so" -s www.sina.com.cn:443 -S echo "" - ./https_request -f "../libmbedcrypto.so;../libmbedx509.so;../libmbedtls.so" -s www.baidu.com:443 -S + ./https_request -f "../libmbedtls_all.so" -s www.baidu.com:443 -S echo "" - ./https_request -f "../libmbedcrypto.so;../libmbedx509.so;../libmbedtls.so" -s echo.websocket.org:443 -S + ./https_request -f "../libmbedtls_all.so" -s echo.websocket.org:443 -S fi # ./https_request -f "/usr/local/lib64/libcrypto.so;/usr/local/lib64/libssl.so" -s www.baidu.com:443 -H www.baidu.com -U / -n 1 -S diff --git a/lib_acl_cpp/src/stream/openssl_io.cpp b/lib_acl_cpp/src/stream/openssl_io.cpp index d8968838d..e1f529915 100644 --- a/lib_acl_cpp/src/stream/openssl_io.cpp +++ b/lib_acl_cpp/src/stream/openssl_io.cpp @@ -313,12 +313,18 @@ int openssl_io::read(void* buf, size_t len) int timeout = nblock_ ? 0 : this->stream_->rw_timeout; ACL_SOCKET fd = ACL_VSTREAM_SOCK(this->stream_); +//#define DEBUG_READ_TIMEOUT + while (len > 0) { - //time_t begin = time(NULL); +#ifdef DEBUG_READ_TIMEOUT + time_t begin = time(NULL); +#endif if (acl_read_wait(fd, timeout) < 0) { - //time_t end = time(NULL); - //logger_error("acl_read_wait error=%s, fd=%d, cost=%ld", - // last_serror(), (int) fd, (long) (end - begin)); +#ifdef DEBUG_READ_TIMEOUT + time_t end = time(NULL); + logger_error("read_wait error=%s, fd=%d, cost=%ld, ttl=%d", + last_serror(), (int) fd, (long) (end - begin), timeout); +#endif return -1; } diff --git a/lib_fiber/samples/https_client/main.cpp b/lib_fiber/samples/https_client/main.cpp index dd45cb13c..cba93a83b 100644 --- a/lib_fiber/samples/https_client/main.cpp +++ b/lib_fiber/samples/https_client/main.cpp @@ -54,7 +54,7 @@ static void http_client(ACL_FIBER *fiber, const char* addr) } if (i < 1) { - if (body.size() < 100) { + if (body.size() < 1000) { printf(">>>fiber-%d: body: %s\r\n", acl_fiber_id(fiber), body.c_str()); } else { diff --git a/lib_fiber/samples/ssl_client/main.cpp b/lib_fiber/samples/ssl_client/main.cpp index 1c2a162b9..f738f4f65 100644 --- a/lib_fiber/samples/ssl_client/main.cpp +++ b/lib_fiber/samples/ssl_client/main.cpp @@ -5,7 +5,7 @@ #define STACK_SIZE 128000 -static int __rw_timeout = 0; +static int __rw_timeout = -1; static int __conn_timeout = 0; static int __max_fibers = 100; static int __left_fibers = 100; @@ -69,6 +69,16 @@ static void run(const char* addr) printf("fiber-%d: connect %s ok, clients: %d, fd: %d\r\n", acl_fiber_self(), addr, __total_clients, conn.sock_handle()); + if (conn.write("h", 1) == -1) { + printf("write h error\n"); + return; + } +#if 1 + printf("write h\r\n"); sleep(3); + conn.write("e", 1); printf("write e\n"); sleep(3); + conn.write("\r\n", 2); printf("write crlf\n"); sleep(3); +#endif + acl::string buf; const char req[] = "hello world\r\n"; @@ -77,11 +87,17 @@ static void run(const char* addr) printf("write error: %s\r\n", acl::last_serror()); break; } + //sleep(1); if (!conn.gets(buf, false)) { printf("gets error: %s\r\n", acl::last_serror()); break; } + + if (i < 5) { + printf(">>>gets: %s\r\n", buf.c_str()); + } + buf.clear(); __total_count++; } @@ -215,7 +231,7 @@ int main(int argc, char *argv[]) } acl::openssl_conf::set_libpath(libs[0], libs[1]); if (acl::openssl_conf::load()) { - __ssl_conf = new acl::openssl_conf(false); + __ssl_conf = new acl::openssl_conf; } else { printf("load %s error\r\n", libpath.c_str()); } diff --git a/lib_fiber/samples/ssl_server/main.cpp b/lib_fiber/samples/ssl_server/main.cpp index e0fec8a55..25483f10e 100644 --- a/lib_fiber/samples/ssl_server/main.cpp +++ b/lib_fiber/samples/ssl_server/main.cpp @@ -44,15 +44,18 @@ static void echo_fiber(ACL_FIBER *, void *ctx) printf("ssl handshake_ok\r\n"); - acl::string buf; + char buf[2048]; while (true) { - if (!conn->gets(buf, false)) { - printf("gets error: %s\r\n", acl::last_serror()); + int ret = conn->read(buf, sizeof(buf) - 1, false); + if (ret < 0) { + printf("read error: %s\r\n", acl::last_serror()); break; } + buf[ret] = 0; + printf(">>>read: %s, cnt=%d\r\n", buf, ret); - if (conn->write(buf) == -1) { + if (conn->write(buf, ret) == -1) { printf("write error: %s\r\n", acl::last_serror()); break; } From f7563f1bc1bcb6cc478bba9b5fdb1855377e81f3 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 15:11:34 +0800 Subject: [PATCH 17/22] w_timeout should be set when writing data in iouring mode. --- lib_fiber/c/src/event/event_io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_fiber/c/src/event/event_io_uring.c b/lib_fiber/c/src/event/event_io_uring.c index 4ccb2c6fc..7cae0d0bd 100644 --- a/lib_fiber/c/src/event/event_io_uring.c +++ b/lib_fiber/c/src/event/event_io_uring.c @@ -190,7 +190,7 @@ static int event_uring_add_write(EVENT_URING *ep, FILE_EVENT *fe) TRY_SUBMMIT(ep); } else if (fe->mask & EVENT_POLLOUT) { - add_write_wait(ep, fe, fe->r_timeout); + add_write_wait(ep, fe, fe->w_timeout); } else if (fe->mask & EVENT_CONNECT) { non_blocking(fe->fd, 1); struct io_uring_sqe *sqe = io_uring_get_sqe(&ep->ring); From b0082d21bcf0381c67352b468724afbaa36ac75c Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 15:17:58 +0800 Subject: [PATCH 18/22] Reset r_timeout/w_timeout after poll finishing. --- lib_fiber/c/src/hook/poll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib_fiber/c/src/hook/poll.c b/lib_fiber/c/src/hook/poll.c index 0a1afefd6..587b2a738 100644 --- a/lib_fiber/c/src/hook/poll.c +++ b/lib_fiber/c/src/hook/poll.c @@ -207,6 +207,7 @@ static void poll_event_clean(EVENT *ev, POLL_EVENT *pe) CLR_READWAIT(pfd->fe); #ifdef HAS_IO_URING pfd->fe->mask &= ~EVENT_POLLIN; + pfd->fe->r_timeout = -1; #endif event_del_read(ev, pfd->fe); pfd->fe->fiber_r = NULL; @@ -215,6 +216,7 @@ static void poll_event_clean(EVENT *ev, POLL_EVENT *pe) CLR_WRITEWAIT(pfd->fe); #ifdef HAS_IO_URING pfd->fe->mask &= ~EVENT_POLLOUT; + pfd->fe->w_timeout = -1; #endif event_del_write(ev, pfd->fe); pfd->fe->fiber_w = NULL; From 1f7ad7098bf409a7f785bf13da2104d9dea97bfb Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 17:48:01 +0800 Subject: [PATCH 19/22] Optimize setsockopt for setting IO timeout in fiber. --- lib_fiber/c/src/event.h | 23 ++++++++++++++--------- lib_fiber/c/src/fiber_io.c | 12 +++++++++++- lib_fiber/c/src/file_event.c | 2 +- lib_fiber/c/src/hook/socket.c | 31 ++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/lib_fiber/c/src/event.h b/lib_fiber/c/src/event.h index 62825c144..2ffb6e395 100644 --- a/lib_fiber/c/src/event.h +++ b/lib_fiber/c/src/event.h @@ -199,6 +199,9 @@ struct FILE_EVENT { #define EVENT_SENDMSG (unsigned) (1 << 28) #endif // HAS_IO_URING +#define EVENT_SO_RCVTIMEO (unsigned) (1 << 29) +#define EVENT_SO_SNDTIMEO (unsigned) (1 << 30) + event_proc *r_proc; event_proc *w_proc; #ifdef HAS_POLL @@ -230,7 +233,7 @@ struct FILE_EVENT { int flags; } recv_ctx; -#if defined(IO_URING_HAS_RECVFROM) +# if defined(IO_URING_HAS_RECVFROM) struct { char *buf; unsigned len; @@ -238,7 +241,7 @@ struct FILE_EVENT { struct sockaddr *src_addr; socklen_t *addrlen; } recvfrom_ctx; -#endif +# endif struct { struct msghdr *msg; @@ -265,7 +268,7 @@ struct FILE_EVENT { int flags; } send_ctx; -#if defined(IO_URING_HAS_SENDTO) +# if defined(IO_URING_HAS_SENDTO) struct { const void *buf; unsigned len; @@ -273,7 +276,7 @@ struct FILE_EVENT { const struct sockaddr *dest_addr; socklen_t addrlen; } sendto_ctx; -#endif +# endif struct { const struct msghdr *msg; @@ -287,9 +290,9 @@ struct FILE_EVENT { socklen_t len; } peer; -#ifdef HAS_STATX +# ifdef HAS_STATX struct statx *statxbuf; -#endif +# endif char *path; } var; @@ -297,11 +300,12 @@ struct FILE_EVENT { struct IO_URING_CTX writer_ctx; struct __kernel_timespec rts; struct __kernel_timespec wts; + +#endif // HAS_IO_URING + int r_timeout; int w_timeout; -#endif - ACL_FIBER_SEM* mbox_wsem; // Used in sync_waiter_wakeup.c #ifdef HAS_IOCP @@ -322,7 +326,8 @@ struct FILE_EVENT { socklen_t len; } peer; } var; -#endif +#endif // HAS_IOCP + short refer; short busy; #define EVENT_BUSY_NONE (0) diff --git a/lib_fiber/c/src/fiber_io.c b/lib_fiber/c/src/fiber_io.c index 0f8c32476..9cdd7bfa1 100644 --- a/lib_fiber/c/src/fiber_io.c +++ b/lib_fiber/c/src/fiber_io.c @@ -179,7 +179,7 @@ void fiber_timer_add(ACL_FIBER *fiber, size_t milliseconds) TIMER_CACHE_NODE *timer; fiber->when = now + milliseconds; - ring_detach(&fiber->me); + ring_detach(&fiber->me); // Detch the previous binding. timer_cache_add(__thread_fiber->ev_timer, fiber->when, &fiber->me); /* Compute the event waiting interval according the timers' head */ @@ -485,6 +485,10 @@ int fiber_wait_read(FILE_EVENT *fe) WAITER_INC(__thread_fiber->event); } + if (fe->mask & EVENT_SO_RCVTIMEO && fe->r_timeout > 0) { + fiber_timer_add(curr, fe->r_timeout); + } + acl_fiber_switch(); fe->fiber_r->wstatus &= ~FIBER_WAIT_READ; @@ -503,6 +507,7 @@ int fiber_wait_read(FILE_EVENT *fe) return -1; } else if (curr->flag & FIBER_F_TIMER) { // If the IO reading timeout set in setsockopt. + // Clear FIBER_F_TIMER flag been set in wakeup_timers. curr->flag &= ~FIBER_F_TIMER; event_del_read(__thread_fiber->event, fe); @@ -555,6 +560,11 @@ int fiber_wait_write(FILE_EVENT *fe) WAITER_INC(__thread_fiber->event); } + + if (fe->mask & EVENT_SO_SNDTIMEO && fe->w_timeout > 0) { + fiber_timer_add(curr, fe->w_timeout); + } + acl_fiber_switch(); fe->fiber_w->wstatus &= ~FIBER_WAIT_WRITE; diff --git a/lib_fiber/c/src/file_event.c b/lib_fiber/c/src/file_event.c index f9359469e..940a5b7bd 100644 --- a/lib_fiber/c/src/file_event.c +++ b/lib_fiber/c/src/file_event.c @@ -31,9 +31,9 @@ void file_event_init(FILE_EVENT *fe, socket_t fd) memset(&fe->var, 0, sizeof(fe->var)); memset(&fe->reader_ctx, 0, sizeof(fe->reader_ctx)); memset(&fe->writer_ctx, 0, sizeof(fe->writer_ctx)); +#endif fe->r_timeout = -1; fe->w_timeout = -1; -#endif #ifdef HAS_IOCP fe->rbuf = NULL; diff --git a/lib_fiber/c/src/hook/socket.c b/lib_fiber/c/src/hook/socket.c index 6e3b0932d..af8da2f5a 100644 --- a/lib_fiber/c/src/hook/socket.c +++ b/lib_fiber/c/src/hook/socket.c @@ -546,6 +546,9 @@ int setsockopt(int sockfd, int level, int optname, size_t val; #ifdef CREAT_TIMER_FIBER TIMEOUT_CTX *ctx; +#else + FILE_EVENT *fe; + ACL_FIBER *curr; #endif const struct timeval *tm; @@ -607,8 +610,34 @@ int setsockopt(int sockfd, int level, int optname, return -1; } #else + curr = acl_fiber_running(); + fe = fiber_file_open(sockfd); + + if (val <= 0) { + fiber_timer_del(curr); + if (optname == SO_RCVTIMEO) { + fe->mask &= ~EVENT_SO_RCVTIMEO; + fe->r_timeout = -1; + } else if (optname == SO_SNDTIMEO) { + fe->mask &= ~EVENT_SO_SNDTIMEO; + fe->w_timeout = -1; + } + return 0; + } + val *= 1000; - fiber_timer_add(acl_fiber_running(), val); + if (optname == SO_RCVTIMEO) { + fe->mask |= EVENT_SO_RCVTIMEO; + fe->r_timeout = val; + } else if (optname == SO_SNDTIMEO) { + fe->mask |= EVENT_SO_SNDTIMEO; + fe->w_timeout = val; + } else { + msg_fatal("%s: Invalid optname=%d", __FUNCTION__, optname); + } + + // We just set the flags here, and the timer will be add in + // fiber_wait_read or fiber_wait_write. return 0; #endif } From 4c41c86bc0ecfb20c20281dbfeaaa57cd364a2a1 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 17:53:44 +0800 Subject: [PATCH 20/22] Use setsockopt to set the IO timeout for OpenSSL module. --- .../include/acl_cpp/stream/openssl_conf.hpp | 16 +++ lib_acl_cpp/src/stream/openssl_conf.cpp | 7 ++ lib_acl_cpp/src/stream/openssl_io.cpp | 102 +++++++++++++----- 3 files changed, 99 insertions(+), 26 deletions(-) diff --git a/lib_acl_cpp/include/acl_cpp/stream/openssl_conf.hpp b/lib_acl_cpp/include/acl_cpp/stream/openssl_conf.hpp index deccda70b..141dbb345 100644 --- a/lib_acl_cpp/include/acl_cpp/stream/openssl_conf.hpp +++ b/lib_acl_cpp/include/acl_cpp/stream/openssl_conf.hpp @@ -117,12 +117,28 @@ public: */ bool push_ssl_ctx(SSL_CTX* ctx); + /** + * 在设置读写超时时,是否使用 setsockopt() + * @param yes {bool} 如果为 true 则使用 setsockopt 设置读写超时,否则 + * 使用 acl_read_wait/acl_write_wait 检查超时情景. + */ + void use_sockopt_timeout(bool yes); + + /** + * 是否需要使用 setsockopt() 设置网络超时时间. + * @return {bool} + */ + bool is_sockopt_timeout() const { + return sockopt_timeout_; + } + private: bool server_side_; SSL_CTX* ssl_ctx_; // The default SSL_CTX. token_tree* ssl_ctx_table_; // Holding the map of host/SSL_CTX. std::set ssl_ctxes_; // Holding all ctx just for freeing. int timeout_; + bool sockopt_timeout_; string crt_file_; unsigned status_; diff --git a/lib_acl_cpp/src/stream/openssl_conf.cpp b/lib_acl_cpp/src/stream/openssl_conf.cpp index a3082712a..bb0a90416 100644 --- a/lib_acl_cpp/src/stream/openssl_conf.cpp +++ b/lib_acl_cpp/src/stream/openssl_conf.cpp @@ -550,6 +550,7 @@ openssl_conf::openssl_conf(bool server_side /* false */, int timeout /* 30 */) , ssl_ctx_(NULL) , ssl_ctx_table_(NULL) , timeout_(timeout) +, sockopt_timeout_(false) { #ifdef HAS_OPENSSL // Init OpenSSL globally, and the dynamic libs will be loaded @@ -590,6 +591,12 @@ openssl_conf::~openssl_conf(void) #endif } +void openssl_conf::use_sockopt_timeout(bool yes) +{ + sockopt_timeout_ = yes; +} + + SSL_CTX* openssl_conf::create_ssl_ctx(void) { #ifdef HAS_OPENSSL diff --git a/lib_acl_cpp/src/stream/openssl_io.cpp b/lib_acl_cpp/src/stream/openssl_io.cpp index e1f529915..289ae5e96 100644 --- a/lib_acl_cpp/src/stream/openssl_io.cpp +++ b/lib_acl_cpp/src/stream/openssl_io.cpp @@ -305,13 +305,46 @@ bool openssl_io::on_close(bool alive) #endif } +static bool set_sock_timeout(ACL_SOCKET fd, int opt, int timeout) +{ + if (timeout <= 0) { + return true; + } + +#if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) + timeout *= 1000; // From seconds to millisecond. + if (setsockopt(fd, SOL_SOCKET, opt, &timeout, sizeof(timeout)) < 0) { + logger_error("setsockopt error=%s, timeout=%d, opt=%d, fd=%d", + last_serror(), timeout, opt, (int) fd); + return false; + } +#else // Must be Linux. + struct timeval tm; + tm.tv_sec = timeout; + tm.tv_usec = 0; + + if (setsockopt(fd, SOL_SOCKET, opt, &tm, sizeof(tm)) < 0) { + logger_error("setsockopt error=%s, timeout=%d, opt=%d, fd=%d", + last_serror(), timeout, opt, (int) fd); + return false; + } +#endif + return true; +} + int openssl_io::read(void* buf, size_t len) { #ifdef HAS_OPENSSL size_t nbytes = 0; char* ptr = (char*) buf; - int timeout = nblock_ ? 0 : this->stream_->rw_timeout; + int timeo = nblock_ ? 0 : this->stream_->rw_timeout; ACL_SOCKET fd = ACL_VSTREAM_SOCK(this->stream_); + bool opt = conf_.is_sockopt_timeout(); + + if (timeo > 0 && opt && !set_sock_timeout(fd, SO_RCVTIMEO, timeo)) { + logger_error("Can't set read timeout, fd=%d", fd); + return -1; + } //#define DEBUG_READ_TIMEOUT @@ -319,16 +352,19 @@ int openssl_io::read(void* buf, size_t len) #ifdef DEBUG_READ_TIMEOUT time_t begin = time(NULL); #endif - if (acl_read_wait(fd, timeout) < 0) { + if (timeo > 0 && !opt && acl_read_wait(fd, timeo) < 0) { #ifdef DEBUG_READ_TIMEOUT time_t end = time(NULL); logger_error("read_wait error=%s, fd=%d, cost=%ld, ttl=%d", - last_serror(), (int) fd, (long) (end - begin), timeout); + last_serror(), (int) fd, (long) (end - begin), timeo); #endif return -1; } int ret = __ssl_read(ssl_, ptr, (int) len); + + this->stream_->read_ready = 0; + if (ret > 0) { nbytes += ret; ptr += ret; @@ -337,37 +373,36 @@ int openssl_io::read(void* buf, size_t len) break; } + if (nbytes > 0) { break; } - this->stream_->read_ready = 0; int err = __ssl_get_error(ssl_, ret); - switch (err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - if (nblock_) { - return ACL_VSTREAM_EOF; + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { + if (nblock_ || opt) { + break; } - break; - case SSL_ERROR_ZERO_RETURN: - case SSL_ERROR_SYSCALL: - default: + } else { + // SSL_ERROR_ZERO_RETURN, SSL_ERROR_SYSCALL, others. + /* if (ERR_peek_error() == 0) { } */ - return ACL_VSTREAM_EOF; + return -1; } } +#if 0 if (len == 0) { this->stream_->read_ready = 1; } +#endif - return nbytes > 0 ? (int) nbytes : ACL_VSTREAM_EOF; + return nbytes > 0 ? (int) nbytes : -1; #else (void) buf; (void) len; @@ -381,12 +416,18 @@ int openssl_io::send(const void* buf, size_t len) #ifdef HAS_OPENSSL size_t nbytes = 0; char* ptr = (char*) buf; - int timeout = nblock_ ? 0 : this->stream_->rw_timeout; + int timeo = nblock_ ? 0 : this->stream_->rw_timeout; ACL_SOCKET fd = ACL_VSTREAM_SOCK(this->stream_); + bool opt = conf_.is_sockopt_timeout(); + + if (timeo > 0 && opt && !set_sock_timeout(fd, SO_SNDTIMEO, timeo)) { + logger_error("Can't set send timeout, fd=%d", fd); + return -1; + } while (len > 0) { //time_t begin = time(NULL); - if (acl_write_wait(fd, timeout) < 0) { + if (timeo > 0 && !opt && acl_write_wait(fd, timeo) < 0) { //time_t end = time(NULL); //logger_error("acl_write_wait error=%s, fd=%d, cost=%ld", // last_serror(), (int) fd, (long) (end - begin)); @@ -402,19 +443,28 @@ int openssl_io::send(const void* buf, size_t len) break; } - int err = __ssl_get_error(ssl_, ret); - switch (err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - break; - case SSL_ERROR_SYSCALL: - default: + if (nbytes > 0) { break; } - break; + + int err = __ssl_get_error(ssl_, ret); + + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { + if (nblock_ || opt) { + break; + } + } else { + // SSL_ERROR_ZERO_RETURN, SSL_ERROR_SYSCALL, others. + + /* + if (ERR_peek_error() == 0) { + } + */ + return -1; + } } - return nbytes > 0 ? (int) nbytes : ACL_VSTREAM_EOF; + return nbytes > 0 ? (int) nbytes : -1; #else (void) buf; (void) len; From 661229ace255923245a6799b47ff2ec549f62187 Mon Sep 17 00:00:00 2001 From: zhengshuxin Date: Mon, 25 Mar 2024 17:57:10 +0800 Subject: [PATCH 21/22] Test OpenSSL timeout in fiber mode. --- lib_fiber/samples/setsockopt/echo_client.c | 30 +++++++++--- lib_fiber/samples/setsockopt/main.c | 56 ++++++++++++++++++---- lib_fiber/samples/ssl_client/main.cpp | 14 +----- lib_fiber/samples/ssl_server/main.cpp | 18 +++++-- 4 files changed, 88 insertions(+), 30 deletions(-) diff --git a/lib_fiber/samples/setsockopt/echo_client.c b/lib_fiber/samples/setsockopt/echo_client.c index 0187bd58c..636157abb 100644 --- a/lib_fiber/samples/setsockopt/echo_client.c +++ b/lib_fiber/samples/setsockopt/echo_client.c @@ -22,24 +22,40 @@ static void set_timeout(ACL_VSTREAM *cstream, int rw_timeout) void echo_client(ACL_VSTREAM *cstream, int rw_timeout, int echo_data) { char buf[8192]; - int ret, count = 0; + int ret, count = 0, ecnt = 0; #define SOCK ACL_VSTREAM_SOCK - while (1) { - if (rw_timeout > 0) { - set_timeout(cstream, rw_timeout); - } + if (rw_timeout > 0) { + set_timeout(cstream, rw_timeout); + } + while (1) { + time_t begin = time(NULL); ret = acl_vstream_read(cstream, buf, sizeof(buf) - 1); + time_t end = time(NULL); + if (ret == ACL_VSTREAM_EOF) { - printf("gets error: %s, fd: %d, count: %d\r\n", - acl_last_serror(), SOCK(cstream), count); + if (errno == EAGAIN && ++ecnt <= 3) { + printf("EAGAIN, try again, fd: %d, cost=%ld\r\n", + SOCK(cstream), end - begin); + continue; + } + printf("read error: %s, fd: %d, count: %d, timeout count=%d\r\n", + acl_last_serror(), SOCK(cstream), count, ecnt); break; } buf[ret] = 0; //printf("gets line: %s", buf); +#if 1 + if (rw_timeout >= 5) { + rw_timeout = 2; + set_timeout(cstream, rw_timeout); + printf(">>reset read timeout to %d\r\n", rw_timeout); + } +#endif + if (!echo_data) { count++; continue; diff --git a/lib_fiber/samples/setsockopt/main.c b/lib_fiber/samples/setsockopt/main.c index 33b7a578b..98cc00cca 100644 --- a/lib_fiber/samples/setsockopt/main.c +++ b/lib_fiber/samples/setsockopt/main.c @@ -5,6 +5,33 @@ static int __stack_size = 320000; static int __rw_timeout = 5; static int __echo_data = 0; +static void *thread_client(void *ctx) +{ + ACL_VSTREAM *cstream = (ACL_VSTREAM*) ctx; + echo_client(cstream, __rw_timeout, __echo_data); + return NULL; +} + +static void thread_server_run(ACL_VSTREAM *sstream) +{ + acl_pthread_attr_t attr; + + acl_pthread_attr_init(&attr); + acl_pthread_attr_setdetachstate(&attr, 1); + + while (1) { + ACL_VSTREAM *cstream = acl_vstream_accept(sstream, NULL, 0); + if (sstream == NULL) { + printf("acl_vstream_accept error %s\r\n", + acl_last_serror()); + break; + } + + acl_pthread_t tid; + acl_pthread_create(&tid, &attr, thread_client, cstream); + } +} + static void fiber_client(ACL_FIBER *fiber acl_unused, void *ctx) { ACL_VSTREAM *cstream = (ACL_VSTREAM *) ctx; @@ -29,27 +56,36 @@ static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx) acl_vstream_close(sstream); } +static void fiber_server_run(ACL_VSTREAM *sstream) +{ + acl_fiber_create(fiber_accept, sstream, 327680); + + printf("call fiber_schedule\r\n"); + acl_fiber_schedule(); +} + static void usage(const char *procname) { printf("usage: %s -h [help]\r\n" " -s listen_addr\r\n" " -r rw_timeout [default: 5]\r\n" " -z stack_size\r\n" - " -w [if echo data, default: no]\r\n", procname); + " -T [if running in thread mode, default: no]\r\n" + " -W [if echo data, default: no]\r\n", procname); } int main(int argc, char *argv[]) { char addr[64]; ACL_VSTREAM *sstream; - int ch, qlen = 128; + int ch, qlen = 128, thread_mode = 0; acl_msg_stdout_enable(1); acl_fiber_msg_stdout_enable(1); snprintf(addr, sizeof(addr), "%s", "127.0.0.1:9002"); - while ((ch = getopt(argc, argv, "hs:r:wz:")) > 0) { + while ((ch = getopt(argc, argv, "hs:r:Wz:T")) > 0) { switch (ch) { case 'h': usage(argv[0]); @@ -60,12 +96,15 @@ int main(int argc, char *argv[]) case 'r': __rw_timeout = atoi(optarg); break; - case 'w': + case 'W': __echo_data = 1; break; case 'z': __stack_size = atoi(optarg); break; + case 'T': + thread_mode = 1; + break; default: break; } @@ -79,10 +118,11 @@ int main(int argc, char *argv[]) printf("listen %s ok\r\n", addr); - acl_fiber_create(fiber_accept, sstream, 327680); - - printf("call fiber_schedule\r\n"); - acl_fiber_schedule(); + if (thread_mode) { + thread_server_run(sstream); + } else { + fiber_server_run(sstream); + } return 0; } diff --git a/lib_fiber/samples/ssl_client/main.cpp b/lib_fiber/samples/ssl_client/main.cpp index f738f4f65..b91be4ceb 100644 --- a/lib_fiber/samples/ssl_client/main.cpp +++ b/lib_fiber/samples/ssl_client/main.cpp @@ -69,16 +69,6 @@ static void run(const char* addr) printf("fiber-%d: connect %s ok, clients: %d, fd: %d\r\n", acl_fiber_self(), addr, __total_clients, conn.sock_handle()); - if (conn.write("h", 1) == -1) { - printf("write h error\n"); - return; - } -#if 1 - printf("write h\r\n"); sleep(3); - conn.write("e", 1); printf("write e\n"); sleep(3); - conn.write("\r\n", 2); printf("write crlf\n"); sleep(3); -#endif - acl::string buf; const char req[] = "hello world\r\n"; @@ -87,9 +77,8 @@ static void run(const char* addr) printf("write error: %s\r\n", acl::last_serror()); break; } - //sleep(1); - if (!conn.gets(buf, false)) { + if (!conn.gets(buf, true)) { printf("gets error: %s\r\n", acl::last_serror()); break; } @@ -100,6 +89,7 @@ static void run(const char* addr) buf.clear(); __total_count++; + //sleep(8); } printf("close one connection: %d, %s\r\n", diff --git a/lib_fiber/samples/ssl_server/main.cpp b/lib_fiber/samples/ssl_server/main.cpp index 25483f10e..b6055df1d 100644 --- a/lib_fiber/samples/ssl_server/main.cpp +++ b/lib_fiber/samples/ssl_server/main.cpp @@ -45,15 +45,26 @@ static void echo_fiber(ACL_FIBER *, void *ctx) printf("ssl handshake_ok\r\n"); char buf[2048]; + size_t n = 0, eagain = 0; while (true) { int ret = conn->read(buf, sizeof(buf) - 1, false); if (ret < 0) { - printf("read error: %s\r\n", acl::last_serror()); - break; + if (errno != EAGAIN) { + printf(">>>read error: %s\r\n", acl::last_serror()); + break; + } + + printf(">>>read timeout %zd times\r\n", ++eagain); + if (eagain >= 3) { + break; + } } buf[ret] = 0; - printf(">>>read: %s, cnt=%d\r\n", buf, ret); + + if (n++ < 5) { + printf(">>>read cnt=%d, data=%s\r\n", ret, buf); + } if (conn->write(buf, ret) == -1) { printf("write error: %s\r\n", acl::last_serror()); @@ -219,6 +230,7 @@ int main(int argc, char *argv[]) return 1; } __ssl_conf = ssl_init(ssl_type_openssl, __ssl_crt, __ssl_key); + ((acl::openssl_conf*) __ssl_conf)->use_sockopt_timeout(true); } else { printf("invalid libpath=%s\r\n", libpath.c_str()); return 1; From 0be537a92c370a91ed742748caaa13e0b0d3791e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?shuxin=20=E3=80=80=E3=80=80zheng?= Date: Mon, 25 Mar 2024 18:02:07 +0800 Subject: [PATCH 22/22] Test IO timeout by setting setsockopt on MacOS. --- lib_fiber/samples/setsockopt/echo_client.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib_fiber/samples/setsockopt/echo_client.c b/lib_fiber/samples/setsockopt/echo_client.c index 636157abb..65c02a300 100644 --- a/lib_fiber/samples/setsockopt/echo_client.c +++ b/lib_fiber/samples/setsockopt/echo_client.c @@ -3,14 +3,13 @@ static void set_timeout(ACL_VSTREAM *cstream, int rw_timeout) { +#if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) + if (setsockopt(ACL_VSTREAM_SOCK(cstream), SOL_SOCKET, + SO_RCVTIMEO, &rw_timeout, sizeof(rw_timeout)) < 0) { +#else struct timeval tm; tm.tv_sec = rw_timeout; tm.tv_usec = 0; - -#if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) - if (setsockopt(ACL_VSTREAM_SOCK(cstream), SOL_SOCKET, - SO_RCVTIMEO, &__rw_timeout, sizeof(__rw_timeout)) < 0) { -#else if (setsockopt(ACL_VSTREAM_SOCK(cstream), SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)) < 0) { #endif