Skip to content

Commit 1684939

Browse files
committed
os: Import UNC and drive letter handlings
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent 6ee11e0 commit 1684939

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

src/cio_os.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,62 @@ 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;
5658

5759
if (_fullpath(dir, path, MAX_PATH) == NULL) {
5860
return 1;
5961
}
6062

63+
/* Normalize to backslashes */
6164
for (p = dir; *p; p++) {
62-
/* Skip the drive letter (e.g., "C:") */
63-
if (p > dir && *p == ':' && *(p - 1) != '\0') {
64-
continue;
65+
if (*p == '/') { *p = '\\'; }
66+
}
67+
68+
len = strlen(dir);
69+
70+
/* Determine root length: "C:\" (3) or UNC root "\\server\share\" */
71+
if (len >= 2 &&
72+
((dir[0] >= 'A' && dir[0] <= 'Z') || (dir[0] >= 'a' && dir[0] <= 'z')) &&
73+
dir[1] == ':') {
74+
root_len = (len >= 3 && dir[2] == '\\') ? 3 : 2;
75+
}
76+
else if (len >= 5 && dir[0] == '\\' && dir[1] == '\\') {
77+
/* Skip server and share components: \\server\share\ */
78+
size_t i = 2, seps = 0;
79+
while (i < len && seps < 2) {
80+
if (dir[i] == '\\') { seps++; }
81+
i++;
6582
}
83+
root_len = i; /* points just past "\\server\share\" */
84+
}
6685

67-
if (*p == '\\' || *p == '/') {
68-
char original_char = *p;
86+
/* Create each intermediate component after the root */
87+
for (p = dir + root_len; *p; p++) {
88+
if (*p == '\\') {
89+
char saved = *p;
6990
*p = '\0';
70-
7191
if (!CreateDirectoryA(dir, NULL)) {
72-
if (GetLastError() != ERROR_ALREADY_EXISTS) {
73-
*p = original_char;
92+
DWORD err = GetLastError();
93+
if (err != ERROR_ALREADY_EXISTS) {
94+
*p = saved;
7495
return 1;
7596
}
7697
}
77-
*p = original_char;
98+
*p = saved;
7899
}
79100
}
80101

102+
/* Create the final directory */
81103
if (!CreateDirectoryA(dir, NULL)) {
82-
if (GetLastError() != ERROR_ALREADY_EXISTS) {
104+
DWORD err = GetLastError();
105+
if (err != ERROR_ALREADY_EXISTS) {
83106
return 1;
84107
}
85108
}
86-
87109
return 0;
88110
}
89111
#endif

0 commit comments

Comments
 (0)