diff --git a/base/docs/helpdb/Base.jl b/base/docs/helpdb/Base.jl index 2b6cf41fbcab1..57b0e326e5295 100644 --- a/base/docs/helpdb/Base.jl +++ b/base/docs/helpdb/Base.jl @@ -5358,6 +5358,14 @@ that directory will be recursively changed. """ chmod +""" + chown(path, owner, group=-1) + +Change the owner and/or group of `path` to `owner` and/or `group`. If the value entered for `owner` or `group` +is `-1` the corresponding ID will not change. Only integer `owner`s and `group`s are currently supported. +""" +chown + """ gamma(x) diff --git a/base/exports.jl b/base/exports.jl index fddbf6dc52da9..fd90c58ec353a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -1274,6 +1274,7 @@ export # filesystem operations cd, chmod, + chown, cp, ctime, download, diff --git a/base/file.jl b/base/file.jl index 44a22c5698fcc..5663477661612 100644 --- a/base/file.jl +++ b/base/file.jl @@ -5,6 +5,7 @@ export cd, chmod, + chown, cp, cptree, mkdir, @@ -450,3 +451,9 @@ function chmod(path::AbstractString, mode::Integer; recursive::Bool=false) end nothing end + +function chown(path::AbstractString, owner::Integer, group::Integer=-1) + err = ccall(:jl_fs_chown, Int32, (Cstring, Cint, Cint), path, owner, group) + uv_error("chown",err) + nothing +end diff --git a/doc/stdlib/file.rst b/doc/stdlib/file.rst index af384c5a0b2d2..4b6f2cf9814a1 100644 --- a/doc/stdlib/file.rst +++ b/doc/stdlib/file.rst @@ -81,6 +81,12 @@ Change the permissions mode of ``path`` to ``mode``\ . Only integer ``mode``\ s (e.g. ``0o777``\ ) are currently supported. If ``recursive=true`` and the path is a directory all permissions in that directory will be recursively changed. +.. function:: chown(path, owner, group=-1) + + .. Docstring generated from Julia source + + Change the owner and/or group of ``path`` to ``owner`` and/or ``group``\ . If the value entered for ``owner`` or ``group`` is ``-1`` the corresponding ID will not change. Only integer ``owner``\ s and ``group``\ s are currently supported. + .. function:: stat(file) .. Docstring generated from Julia source diff --git a/src/jl_uv.c b/src/jl_uv.c index c3a489dd58fb9..cc1d8bddc4492 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -306,6 +306,14 @@ JL_DLLEXPORT int jl_fs_chmod(char *path, int mode) return ret; } +JL_DLLEXPORT int jl_fs_chown(char *path, int uid, int gid) +{ + uv_fs_t req; + int ret = uv_fs_chown(jl_io_loop, &req, path, uid, gid, NULL); + uv_fs_req_cleanup(&req); + return ret; +} + JL_DLLEXPORT int jl_fs_write(int handle, const char *data, size_t len, int64_t offset) { diff --git a/test/file.jl b/test/file.jl index beeab44d4bd8e..b4dd503d8f6aa 100644 --- a/test/file.jl +++ b/test/file.jl @@ -156,6 +156,22 @@ rm(c_tmpdir, recursive=true) @test_throws Base.UVError rm(c_tmpdir, recursive=true) @test rm(c_tmpdir, force=true, recursive=true) === nothing +# chown will give an error if the user does not have permissions to change files +@unix_only if ENV["USER"] =="root" + chown(file, -2, -1) # Change the file owner to nobody + @test stat(file).uid !=0 + chown(file, 0, -2) # Change the file group to nogroup (and owner back to root) + @test stat(file).gid !=0 + @test stat(file).uid ==0 + chown(file, -1, 0) + @test stat(file).gid ==0 + @test stat(file).uid ==0 +else + @test_throws Base.UVError chown(file, -2, -1) # Non-root user cannot change ownership to another user + @test_throws Base.UVError chown(file, -1, -2) # Non-root user cannot change group to a group they are not a member of (eg: nogroup) +end + +@windows_only @test chown(file, -2, -2) == nothing # chown shouldn't cause any errors for Windows ####################################################################### # This section tests file watchers. #