|  |  | @ -49,6 +49,7 @@ static int fsync_dir(const char* path){ | 
			
		
	
		
		
			
				
					
					|  |  |  |   return result; |  |  |  |   return result; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // TODO: replace by std::filesystem::create_directories
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int mkdir_p(std::string path) { |  |  |  | static int mkdir_p(std::string path) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   char * _path = (char *)path.c_str(); |  |  |  |   char * _path = (char *)path.c_str(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -70,18 +71,51 @@ static int mkdir_p(std::string path) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return 0; |  |  |  |   return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static int ensure_dir_exists(std::string path) { |  |  |  | static bool ensure_params_path(const std::string ¶m_path, const std::string &key_path) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   // TODO: replace by std::filesystem::create_directories
 |  |  |  |   // Make sure params path exists
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   return mkdir_p(path.c_str()); |  |  |  |   if (!util::file_exists(param_path) && mkdir_p(param_path) != 0) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |     return false; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   // See if the symlink exists, otherwise create it
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (!util::file_exists(key_path)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // 1) Create temp folder
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // 2) Set permissions
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // 3) Symlink it to temp link
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // 4) Move symlink to <params>/d
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     std::string tmp_path = param_path + "/.tmp_XXXXXX"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // this should be OK since mkdtemp just replaces characters in place
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     char *tmp_dir = mkdtemp((char *)tmp_path.c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (tmp_dir == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (chmod(tmp_dir, 0777) != 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     std::string link_path = std::string(tmp_dir) + ".link"; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (symlink(tmp_dir, link_path.c_str()) != 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // don't return false if it has been created by other
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (rename(link_path.c_str(), key_path.c_str()) != 0 && errno != EEXIST) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | Params::Params(bool persistent_param){ |  |  |  |   // Ensure permissions are correct in case we didn't create the symlink
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   params_path = persistent_param ? persistent_params_path : default_params_path; |  |  |  |   return chmod(key_path.c_str(), 0777) == 0; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | Params::Params(const std::string &path) { |  |  |  | Params::Params(bool persistent_param) : Params(persistent_param ? persistent_params_path : default_params_path) {} | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   params_path = path; |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Params::Params(const std::string &path) : params_path(path) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (!ensure_params_path(params_path, params_path + "/d")) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     throw std::runtime_error(util::string_format("Failed to ensure params path, errno=%d", errno)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | int Params::put(const char* key, const char* value, size_t value_size) { |  |  |  | int Params::put(const char* key, const char* value, size_t value_size) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -99,52 +133,6 @@ int Params::put(const char* key, const char* value, size_t value_size) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   std::string tmp_path; |  |  |  |   std::string tmp_path; | 
			
		
	
		
		
			
				
					
					|  |  |  |   ssize_t bytes_written; |  |  |  |   ssize_t bytes_written; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Make sure params path exists
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   result = ensure_dir_exists(params_path); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (result < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // See if the symlink exists, otherwise create it
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   path = params_path + "/d"; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   struct stat st; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (stat(path.c_str(), &st) == -1) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create temp folder
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     path = params_path + "/.tmp_XXXXXX"; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     char *t = mkdtemp((char*)path.c_str()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (t == NULL){ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     std::string tmp_dir(t); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Set permissions
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     result = chmod(tmp_dir.c_str(), 0777); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (result < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Symlink it to temp link
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     tmp_path = tmp_dir + ".link"; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     result = symlink(tmp_dir.c_str(), tmp_path.c_str()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (result < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Move symlink to <params>/d
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     path = params_path + "/d"; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     result = rename(tmp_path.c_str(), path.c_str()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (result < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Ensure permissions are correct in case we didn't create the symlink
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     result = chmod(path.c_str(), 0777); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (result < 0) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       goto cleanup; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Write value to temp.
 |  |  |  |   // Write value to temp.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   tmp_path = params_path + "/.tmp_value_XXXXXX"; |  |  |  |   tmp_path = params_path + "/.tmp_value_XXXXXX"; | 
			
		
	
		
		
			
				
					
					|  |  |  |   tmp_fd = mkstemp((char*)tmp_path.c_str()); |  |  |  |   tmp_fd = mkstemp((char*)tmp_path.c_str()); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |