Commit 4b1a27fa0 for llama.cpp
commit 4b1a27fa0eb875bbca4f6cfe936e3d65adc685c0
Author: Adrien Gallouët <angt@huggingface.co>
Date: Fri Sep 25 20:33:37 2026 +0200
common,rpc : simplify fs_create_directory_with_parents() (#29432)
The original function was broken on Windows for some unicode paths
Paths without a trailing separator now create the last directory too,
matching the function name. All current callers already include a
trailing separator, so this change does not affect them.
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
diff --git a/common/common.cpp b/common/common.cpp
index 364688ef4..ae44f054a 100644
--- a/common/common.cpp
+++ b/common/common.cpp
@@ -46,7 +46,6 @@
#include <io.h>
#else
#include <sys/ioctl.h>
-#include <sys/stat.h>
#include <unistd.h>
#endif
@@ -943,78 +942,9 @@ std::string fs_path_to_utf8(const std::filesystem::path & path) {
// returns true if successful, false otherwise
bool fs_create_directory_with_parents(const std::string & path) {
-#ifdef _WIN32
- std::wstring wpath = utf8_to_wstring(path);
-
- // if the path already exists, check whether it's a directory
- const DWORD attributes = GetFileAttributesW(wpath.c_str());
- if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
- return true;
- }
-
- size_t pos_slash = 0;
-
- // process path from front to back, procedurally creating directories
- while ((pos_slash = path.find('\\', pos_slash)) != std::string::npos) {
- const std::wstring subpath = wpath.substr(0, pos_slash);
-
- pos_slash += 1;
-
- // skip the drive letter, in some systems it can return an access denied error
- if (subpath.length() == 2 && subpath[1] == ':') {
- continue;
- }
-
- const bool success = CreateDirectoryW(subpath.c_str(), NULL);
-
- if (!success) {
- const DWORD error = GetLastError();
-
- // if the path already exists, ensure that it's a directory
- if (error == ERROR_ALREADY_EXISTS) {
- const DWORD attributes = GetFileAttributesW(subpath.c_str());
- if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
- return false;
- }
- } else {
- return false;
- }
- }
- }
-
- return true;
-#else
- // if the path already exists, check whether it's a directory
- struct stat info;
- if (stat(path.c_str(), &info) == 0) {
- return S_ISDIR(info.st_mode);
- }
-
- size_t pos_slash = 1; // skip leading slashes for directory creation
-
- // process path from front to back, procedurally creating directories
- while ((pos_slash = path.find('/', pos_slash)) != std::string::npos) {
- const std::string subpath = path.substr(0, pos_slash);
- struct stat info;
-
- // if the path already exists, ensure that it's a directory
- if (stat(subpath.c_str(), &info) == 0) {
- if (!S_ISDIR(info.st_mode)) {
- return false;
- }
- } else {
- // create parent directories
- const int ret = mkdir(subpath.c_str(), 0755);
- if (ret != 0) {
- return false;
- }
- }
-
- pos_slash += 1;
- }
-
- return true;
-#endif // _WIN32
+ std::error_code ec;
+ std::filesystem::create_directories(std::filesystem::u8path(path), ec);
+ return !ec;
}
bool fs_is_directory(const std::string & path) {
diff --git a/tools/rpc/rpc-server.cpp b/tools/rpc/rpc-server.cpp
index 2db5e52ab..100df3c40 100644
--- a/tools/rpc/rpc-server.cpp
+++ b/tools/rpc/rpc-server.cpp
@@ -9,7 +9,6 @@
#else
# define DIRECTORY_SEPARATOR '/'
# include <unistd.h>
-# include <sys/stat.h>
#endif
#include <algorithm>
#include <clocale>
@@ -26,101 +25,12 @@
#include <pwd.h>
#endif
-// NOTE: this is copied from common.cpp to avoid linking with libcommon
-#ifdef _WIN32
-static std::wstring utf8_to_wstring(const std::string & str) {
- if (str.empty()) {
- return std::wstring();
- }
-
- int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), NULL, 0);
-
- if (size <= 0) {
- return std::wstring();
- }
-
- std::wstring wstr(size, 0);
- MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstr[0], size);
-
- return wstr;
-}
-#endif
-
// NOTE: this is copied from common.cpp to avoid linking with libcommon
// returns true if successful, false otherwise
static bool fs_create_directory_with_parents(const std::string & path) {
-#ifdef _WIN32
- std::wstring wpath = utf8_to_wstring(path);
-
- // if the path already exists, check whether it's a directory
- const DWORD attributes = GetFileAttributesW(wpath.c_str());
- if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
- return true;
- }
-
- size_t pos_slash = 0;
-
- // process path from front to back, procedurally creating directories
- while ((pos_slash = path.find('\\', pos_slash)) != std::string::npos) {
- const std::wstring subpath = wpath.substr(0, pos_slash);
-
- pos_slash += 1;
-
- // skip the drive letter, in some systems it can return an access denied error
- if (subpath.length() == 2 && subpath[1] == ':') {
- continue;
- }
-
- const bool success = CreateDirectoryW(subpath.c_str(), NULL);
-
- if (!success) {
- const DWORD error = GetLastError();
-
- // if the path already exists, ensure that it's a directory
- if (error == ERROR_ALREADY_EXISTS) {
- const DWORD attributes = GetFileAttributesW(subpath.c_str());
- if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
- return false;
- }
- } else {
- return false;
- }
- }
- }
-
- return true;
-#else
- // if the path already exists, check whether it's a directory
- struct stat info;
- if (stat(path.c_str(), &info) == 0) {
- return S_ISDIR(info.st_mode);
- }
-
- size_t pos_slash = 1; // skip leading slashes for directory creation
-
- // process path from front to back, procedurally creating directories
- while ((pos_slash = path.find('/', pos_slash)) != std::string::npos) {
- const std::string subpath = path.substr(0, pos_slash);
- struct stat info;
-
- // if the path already exists, ensure that it's a directory
- if (stat(subpath.c_str(), &info) == 0) {
- if (!S_ISDIR(info.st_mode)) {
- return false;
- }
- } else {
- // create parent directories
- const int ret = mkdir(subpath.c_str(), 0755);
- if (ret != 0) {
- return false;
- }
- }
-
- pos_slash += 1;
- }
-
- return true;
-#endif // _WIN32
+ std::error_code ec;
+ std::filesystem::create_directories(std::filesystem::u8path(path), ec);
+ return !ec;
}
// NOTE: this is copied from common.cpp to avoid linking with libcommon