diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 13881ef70..ab5caca0d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2223,6 +2223,10 @@ Helper functions * nil: return all entries, * true: return only subdirectory names, or * false: return only file names. +* `minetest.safe_file_write(path, content)`: returns boolean indicating success + * Replaces contents of file at path with new contents in a safe (atomic) way. + Use this instead of below code when writing e.g. database files: + `local f = io.open(path, "wb"); f:write(content); f:close()` * `minetest.get_version()`: returns a table containing components of the engine version. Components: * `project`: Name of the project, eg, "Minetest" diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 901105fe0..aaccf17ee 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -356,6 +356,23 @@ int ModApiUtil::l_get_dir_list(lua_State *L) return 1; } +// safe_file_write(path, content) +int ModApiUtil::l_safe_file_write(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *path = luaL_checkstring(L, 1); + size_t size; + const char *content = luaL_checklstring(L, 2, &size); + + CHECK_SECURE_PATH(L, path, true); + + bool ret = fs::safeWriteToFile(path, std::string(content, size)); + lua_pushboolean(L, ret); + + return 1; +} + +// request_insecure_environment() int ModApiUtil::l_request_insecure_environment(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -475,6 +492,7 @@ void ModApiUtil::Initialize(lua_State *L, int top) API_FCT(mkdir); API_FCT(get_dir_list); + API_FCT(safe_file_write); API_FCT(request_insecure_environment); diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index 16f4edea8..872e43625 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -81,6 +81,9 @@ private: // get_dir_list(path, is_dir) static int l_get_dir_list(lua_State *L); + // safe_file_write(path, content) + static int l_safe_file_write(lua_State *L); + // request_insecure_environment() static int l_request_insecure_environment(lua_State *L);