diff --git a/cartridge/clusterwide-config.c b/cartridge/clusterwide-config.c index 4fd239be0..a5aab6c5a 100644 --- a/cartridge/clusterwide-config.c +++ b/cartridge/clusterwide-config.c @@ -1,8 +1,11 @@ +#include #include #include #include #include #include +#include +#include #include #include @@ -34,11 +37,10 @@ static int file_write(const char* path, const char* data) { return 0; } -static int mktree(char* path) { +static int mktree(const char* path) { char* tmp_path = strdup(path); // FIXME: here possible buffer overflow char current_dir[512] = ""; - char* ctxptr; struct stat st; char* dir = strtok(tmp_path, "/"); while(dir != NULL) { @@ -46,7 +48,6 @@ static int mktree(char* path) { sprintf(current_dir, "%s/%s", tmp_dir, dir); mode_t mode = 0744; int stat_rc = stat(current_dir, &st); - say_info("current_dir: %s", current_dir); if(stat_rc == -1) { if(mkdir(current_dir, mode) == -1) { say_error("mkdir() error: %s, path: %s, mode: %x", strerror(errno), current_dir, mode); @@ -63,34 +64,35 @@ static int mktree(char* path) { return 0; } -static int cw_save(char* path, char* random_path, char** sections_k, char** sections_v, int section_l) { +static int cw_save(char* path, char* random_path, char** sections_k, char** sections_v, int section_l, char* err) { if(mktree(random_path) == -1 ) { say_error("mktree() error"); return -1; } for (int i = 0; i < section_l; i++) { - char tmp_path[512]; - sprintf(tmp_path, "%s/%s", random_path, sections_k[i]); - if(file_write(tmp_path, sections_v[i]) == -1) { - say_error("file_write() error: %s", strerror(errno)); - goto rollback; + char abspath[512]; + sprintf(abspath, "%s/%s", random_path, sections_k[i]); + const char* _dirname = dirname(abspath); + if(mktree(_dirname) == -1) { + say_error("mktree() error: %s: %s", _dirname, strerror(errno)); + sprintf(err, "%s: %s", _dirname, strerror(errno)); + return -1; + } + if(file_write(abspath, sections_v[i]) == -1) { + say_error("file_write() error: %s: %s", abspath, strerror(errno)); + sprintf(err, "%s: %s", abspath, strerror(errno)); + return -1; } } if(rename(random_path, path) == -1) { - say_error("rename() error: %s", strerror(errno)); - goto rollback; + say_error("rename() error: %s: %s", path, strerror(errno)); + sprintf(err, "%s: %s", path, strerror(errno)); + return -1; } say_verbose("%s has renamed to %s", random_path, path); - goto exit; -rollback: - if(remove(path) == -1) { - say_error("remove error: %s, path: %s", strerror(errno), path); - } - return -1; -exit: return 0; } @@ -100,7 +102,8 @@ static ssize_t va_cw_save(va_list argp) { char** keys = va_arg(argp, char**); char** values = va_arg(argp, char**); int l = va_arg(argp, int); - return cw_save(path, random_path, keys, values, l); + char* err = va_arg(argp, char*); + return cw_save(path, random_path, keys, values, l, err); } static int lua_cw_save(lua_State *L) { @@ -117,7 +120,9 @@ static int lua_cw_save(lua_State *L) { if(!lua_isstring(L, -1)) { const char* _type = luaL_typename(L, -1); say_error("wrong format of table field at index %d: expect string, actual is %s", v, _type); - return -1; + lua_pushnil(L); + lua_pushstring(L, "wrong format"); + return 2; } sections_v[v-1] = lua_tostring(L, -1); lua_pop(L, 1); @@ -135,7 +140,9 @@ static int lua_cw_save(lua_State *L) { if(!lua_isstring(L, -1)) { const char* _type = luaL_typename(L, -1); say_error("wrong format of table field at index %d: expect string, actual is %s", k, _type); - return -1; + lua_pushnil(L); + lua_pushstring(L, "wrong format"); + return 2; } sections_k[k-1] = lua_tostring(L, -1); lua_pop(L, 1); @@ -144,18 +151,22 @@ static int lua_cw_save(lua_State *L) { if(k != v) { say_error("count of keys and count of values are different"); - lua_pushnumber(L, -1); - return -1; + lua_pushnil(L); + lua_pushstring(L, "count of keys is wrong"); + return 2; } - if(coio_call(va_cw_save, path, random_path, sections_k, sections_v, k-1) == -1) { + char err[512]; + + if(coio_call(va_cw_save, path, random_path, sections_k, sections_v, k-1, err) == -1) { say_error("coio_call() error"); - lua_pushnumber(L, -1); - return -1; + lua_pushnil(L); + lua_pushstring(L, err); + return 2; } - lua_pushnumber(L, 0); - return 0; + lua_pushboolean(L, 1); + return 1; } static const struct luaL_Reg functions[] = { @@ -169,4 +180,3 @@ LUA_API int luaopen_cartridge_cwinternal(lua_State *L) { luaL_register(L, NULL, functions); return 1; } - diff --git a/cartridge/clusterwide-config.lua b/cartridge/clusterwide-config.lua index acbea4c4a..aeed7a0a3 100644 --- a/cartridge/clusterwide-config.lua +++ b/cartridge/clusterwide-config.lua @@ -492,9 +492,9 @@ local function save(clusterwide_config, path) table.insert(sections_k, k) table.insert(sections_v, v) end - local rc = internal.save(path, random_path, sections_k, sections_v) - if rc == -1 then - return nil, SaveConfigError:new("error in c") + local rc, err = internal.save(path, random_path, sections_k, sections_v) + if not rc and err then + return nil, SaveConfigError:new(err) end return true end