Skip to content

Commit 42f4d64

Browse files
committed
Merge pull request #2095 from rabbitmq/disk-monitor-and-long-paths-on-windows
rabbit_disk_monitor: Tell Win32 API to not enforce path limits to dir's argument (cherry picked from commit 96cf615)
1 parent a3c8bc8 commit 42f4d64

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

src/rabbit_disk_monitor.erl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,28 @@ get_disk_free(Dir, {unix, _}) ->
232232
Df = os:find_executable("df"),
233233
parse_free_unix(rabbit_misc:os_cmd(Df ++ " -kP " ++ Dir));
234234
get_disk_free(Dir, {win32, _}) ->
235-
parse_free_win32(rabbit_misc:os_cmd("dir /-C /W \"" ++ Dir ++ "\"")).
235+
%% On Windows, the Win32 API enforces a limit of 260 characters
236+
%% (MAX_PATH). If we call `dir` with a path longer than that, it
237+
%% fails with "File not found". Starting with Windows 10 version
238+
%% 1607, this limit was removed, but the administrator has to
239+
%% configure that.
240+
%%
241+
%% NTFS supports paths up to 32767 characters. Therefore, paths
242+
%% longer than 260 characters exist but they are "inaccessible" to
243+
%% `dir`.
244+
%%
245+
%% A workaround is to tell the Win32 API to not parse a path and
246+
%% just pass it raw to the underlying filesystem. To do this, the
247+
%% path must be prepended with "\\?\". That's what we do here.
248+
%%
249+
%% However, the underlying filesystem may not support forward
250+
%% slashes transparently, as the Win32 API does. Therefore, we
251+
%% convert all forward slashes to backslashes.
252+
%%
253+
%% See the following page to learn more about this:
254+
%% https://ss64.com/nt/syntax-filenames.html
255+
RawDir = "\\\\?\\" ++ string:replace(Dir, "/", "\\", all),
256+
parse_free_win32(rabbit_misc:os_cmd("dir /-C /W \"" ++ RawDir ++ "\"")).
236257

237258
parse_free_unix(Str) ->
238259
case string:tokens(Str, "\n") of

0 commit comments

Comments
 (0)