Skip to content

Commit d309635

Browse files
musmstevengj
authored andcommitted
Update homedir and pwd to use StringVector and buffer resizing (#32295)
* Use StringVector and fix logic in pwd and homedir * remove extra whitespace * Address feedback
1 parent 5fa469b commit d309635

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

base/file.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ export
2727
unlink,
2828
walkdir
2929

30-
import .Base.RefValue
31-
3230
# get and set current directory
3331

3432
"""
@@ -48,12 +46,22 @@ julia> pwd()
4846
```
4947
"""
5048
function pwd()
51-
b = Vector{UInt8}(undef, 1024)
52-
len = RefValue{Csize_t}(length(b))
53-
uv_error(:getcwd, ccall(:uv_cwd, Cint, (Ptr{UInt8}, Ptr{Csize_t}), b, len))
54-
String(b[1:len[]])
49+
buf = Base.StringVector(AVG_PATH - 1) # space for null-terminator implied by StringVector
50+
sz = RefValue{Csize_t}(length(buf) + 1) # total buffer size including null
51+
while true
52+
rc = ccall(:uv_cwd, Cint, (Ptr{UInt8}, Ptr{Csize_t}), buf, sz)
53+
if rc == 0
54+
resize!(buf, sz[])
55+
return String(buf)
56+
elseif rc == Base.UV_ENOBUFS
57+
resize!(buf, sz[] - 1) # space for null-terminator implied by StringVector
58+
else
59+
uv_error(:cwd, rc)
60+
end
61+
end
5562
end
5663

64+
5765
"""
5866
cd(dir::AbstractString=homedir())
5967

base/filesystem.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,16 @@ import .Base:
4444
skip, stat, unsafe_read, unsafe_write, write, transcode, uv_error,
4545
rawhandle, OS_HANDLE, INVALID_OS_HANDLE, windowserror
4646

47+
import .Base.RefValue
48+
4749
if Sys.iswindows()
4850
import .Base: cwstring
4951
end
5052

53+
# Average buffer size including null terminator for several filesystem operations.
54+
# On Windows we use the MAX_PATH = 260 value on Win32.
55+
const AVG_PATH = Sys.iswindows() ? 260 : 512
56+
5157
include("path.jl")
5258
include("stat.jl")
5359
include("file.jl")

base/path.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,17 @@ Return the current user's home directory.
6262
[`uv_os_homedir` documentation](http://docs.libuv.org/en/v1.x/misc.html#c.uv_os_homedir).
6363
"""
6464
function homedir()
65-
path_max = 1024
66-
buf = Vector{UInt8}(undef, path_max)
67-
sz = RefValue{Csize_t}(path_max + 1)
65+
buf = Base.StringVector(AVG_PATH - 1) # space for null-terminator implied by StringVector
66+
sz = RefValue{Csize_t}(length(buf) + 1) # total buffer size including null
6867
while true
6968
rc = ccall(:uv_os_homedir, Cint, (Ptr{UInt8}, Ptr{Csize_t}), buf, sz)
7069
if rc == 0
7170
resize!(buf, sz[])
7271
return String(buf)
7372
elseif rc == Base.UV_ENOBUFS
74-
resize!(buf, sz[] - 1)
73+
resize!(buf, sz[] - 1) # space for null-terminator implied by StringVector
7574
else
76-
error("unable to retrieve home directory")
75+
uv_error(:homedir, rc)
7776
end
7877
end
7978
end

test/path.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ end
258258
end
259259
@testset "homedir" begin
260260
var = Sys.iswindows() ? "USERPROFILE" : "HOME"
261-
MAX_PATH = Sys.iswindows() ? 240 : 1020
261+
AVG_PATH = Base.Filesystem.AVG_PATH - 1 # null-termination character
262262
for i = 0:9
263-
local home = " "^MAX_PATH * "123456789"[1:i]
263+
local home = " "^AVG_PATH * "123456789"[1:i]
264264
@test withenv(var => home) do
265265
homedir()
266266
end == home

0 commit comments

Comments
 (0)