Skip to content

Commit 98988d2

Browse files
cosmo0920edsiper
authored andcommitted
os: Import UNC and drive letter handlings
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent 6ee11e0 commit 98988d2

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

src/cio_os.c

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,68 @@ int cio_os_isdir(const char *dir)
5050
}
5151

5252
#ifdef _WIN32
53-
inline int cio_os_win32_make_recursive_path(const char* path) {
54-
char dir[MAX_PATH];
55-
char* p = NULL;
53+
static int cio_os_win32_make_recursive_path(const char* path) {
54+
char dir[MAX_PATH];
55+
char* p;
56+
size_t len;
57+
size_t root_len = 0;
58+
size_t i = 0, seps = 0;
59+
char saved;
5660

5761
if (_fullpath(dir, path, MAX_PATH) == NULL) {
5862
return 1;
5963
}
6064

65+
/* Normalize to backslashes */
6166
for (p = dir; *p; p++) {
62-
/* Skip the drive letter (e.g., "C:") */
63-
if (p > dir && *p == ':' && *(p - 1) != '\0') {
64-
continue;
67+
if (*p == '/') {
68+
*p = '\\';
6569
}
70+
}
6671

67-
if (*p == '\\' || *p == '/') {
68-
char original_char = *p;
69-
*p = '\0';
72+
len = strlen(dir);
7073

74+
/* Determine root length: "C:\" (3) or UNC root "\\server\share\" */
75+
if (len >= 2 &&
76+
((dir[0] >= 'A' && dir[0] <= 'Z') || (dir[0] >= 'a' && dir[0] <= 'z')) &&
77+
dir[1] == ':') {
78+
root_len = (len >= 3 && dir[2] == '\\') ? 3 : 2;
79+
}
80+
else if (len >= 5 && dir[0] == '\\' && dir[1] == '\\') {
81+
/* Skip server and share components: \\server\share\ */
82+
i = 2;
83+
while (i < len && seps < 2) {
84+
if (dir[i] == '\\') {
85+
seps++;
86+
}
87+
i++;
88+
}
89+
root_len = i; /* points just past "\\server\share\" */
90+
}
91+
92+
/* Create each intermediate component after the root */
93+
for (p = dir + root_len; *p; p++) {
94+
if (*p == '\\') {
95+
saved = *p;
96+
*p = '\0';
7197
if (!CreateDirectoryA(dir, NULL)) {
72-
if (GetLastError() != ERROR_ALREADY_EXISTS) {
73-
*p = original_char;
98+
DWORD err = GetLastError();
99+
if (err != ERROR_ALREADY_EXISTS) {
100+
*p = saved;
74101
return 1;
75102
}
76103
}
77-
*p = original_char;
104+
*p = saved;
78105
}
79106
}
80107

108+
/* Create the final directory */
81109
if (!CreateDirectoryA(dir, NULL)) {
82-
if (GetLastError() != ERROR_ALREADY_EXISTS) {
110+
DWORD err = GetLastError();
111+
if (err != ERROR_ALREADY_EXISTS) {
83112
return 1;
84113
}
85114
}
86-
87115
return 0;
88116
}
89117
#endif

0 commit comments

Comments
 (0)