Skip to content

Commit

Permalink
review changes
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Apr 19, 2021
1 parent 775bc11 commit 065d46e
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 100 deletions.
4 changes: 1 addition & 3 deletions base/filesystem.jl
Expand Up @@ -11,14 +11,12 @@ const S_IFREG = 0o100000 # regular file
const S_IFIFO = 0o010000 # fifo (named pipe)
const S_IFLNK = 0o120000 # symbolic link
const S_IFSOCK = 0o140000 # socket file
const S_IFMT = 0o170000

const S_ISUID = 0o4000 # set UID bit
const S_ISGID = 0o2000 # set GID bit
const S_ENFMT = S_ISGID # file locking enforcement
const S_ISVTX = 0o1000 # sticky bit
const S_IREAD = 0o0400 # Unix V7 synonym for S_IRUSR
const S_IWRITE = 0o0200 # Unix V7 synonym for S_IWUSR
const S_IEXEC = 0o0100 # Unix V7 synonym for S_IXUSR
const S_IRWXU = 0o0700 # mask for owner permissions
const S_IRUSR = 0o0400 # read by owner

Expand Down
203 changes: 142 additions & 61 deletions base/stat.jl
Expand Up @@ -62,63 +62,56 @@ StatStruct(desc::Union{AbstractString, OS_HANDLE}, buf::Union{Vector{UInt8},Ptr{
function show(io::IO, st::StatStruct)
compact = get(io, :compact, true)
function iso_datetime_with_relative(t, tnow)
sprint() do iob2
print(iob2, Libc.strftime("%FT%T%z", t))
secdiff = t - tnow
for (d, name) in ((24*60*60,"day"),(60*60,"hour"),(60,"minute"),(1,"second"))
tdiff = round(Int, div(abs(secdiff), d))
(tdiff == 0 && name != "second") && continue # find first unit difference
if tdiff == 0 && name == "second"
print(iob2, " (just now)")
break
end
plural = tdiff == 1 ? "" : "s"
when = secdiff < 0 ? "ago" : "in the future"
print(iob2, " ($(tdiff) $(name)$(plural) $(when))")
str = Libc.strftime("%FT%T%z", t)
secdiff = t - tnow
for (d, name) in ((24*60*60,"day"),(60*60,"hour"),(60,"minute"),(1,"second"))
tdiff = round(Int, div(abs(secdiff), d))
(tdiff == 0 && name != "second") && continue # find first unit difference
if tdiff == 0 && name == "second"
str *= " (just now)"
break
end
plural = tdiff == 1 ? "" : "s"
when = secdiff < 0 ? "ago" : "in the future"
str *= " ($(tdiff) $(name)$(plural) $(when))"
break
end
end
str = if compact
sprint() do iob
print(iob, "$(st.desc)")
print(iob, " size: $(st.size) bytes")
print(iob, " device: $(st.device)")
print(iob, " inode: $(st.inode)")
print(iob, " mode: 0o$(string(filemode(st), base = 8, pad = 6)) ($(filemode_string(st)))")
print(iob, " nlink: $(st.nlink)")
username = Base.getusername(st.uid)
isnothing(username) ? print(iob, " uid: $(st.uid)") : print(iob, " uid: $(st.uid) ($username)")
groupname = Base.getgroupname(st.gid)
isnothing(groupname) ? print(iob, " gid: $(st.gid)") : print(iob, " gid: $(st.gid) ($groupname)")
print(iob, " rdev: $(st.rdev)")
print(iob, " blksize: $(st.blksize)")
print(iob, " blocks: $(st.blocks)")
tnow = Libc.TimeVal().sec
print(iob, " mtime: $(iso_datetime_with_relative(st.mtime, tnow))")
println(iob, " ctime: $(iso_datetime_with_relative(st.ctime, tnow))")
end
if compact
print(io, "$(st.desc)")
print(io, " size: $(st.size) bytes")
print(io, " device: $(st.device)")
print(io, " inode: $(st.inode)")
print(io, " mode: 0o$(string(filemode(st), base = 8, pad = 6)) ($(filemode_string(st)))")
print(io, " nlink: $(st.nlink)")
username = Base.getusername(st.uid)
isnothing(username) ? print(io, " uid: $(st.uid)") : print(io, " uid: $(st.uid) ($username)")
groupname = Base.getgroupname(st.gid)
isnothing(groupname) ? print(io, " gid: $(st.gid)") : print(io, " gid: $(st.gid) ($groupname)")
print(io, " rdev: $(st.rdev)")
print(io, " blksize: $(st.blksize)")
print(io, " blocks: $(st.blocks)")
tnow = Libc.TimeVal().sec
print(io, " mtime: $(iso_datetime_with_relative(st.mtime, tnow))")
println(io, " ctime: $(iso_datetime_with_relative(st.ctime, tnow))")
else
sprint() do iob
println(iob, "StatStruct for $(st.desc)")
println(iob, " size: $(st.size) bytes")
println(iob, " device: $(st.device)")
println(iob, " inode: $(st.inode)")
println(iob, " mode: 0o$(string(filemode(st), base = 8, pad = 6)) ($(filemode_string(st)))")
println(iob, " nlink: $(st.nlink)")
username = Base.getusername(st.uid)
isnothing(username) ? println(iob, " uid: $(st.uid)") : println(iob, " uid: $(st.uid) ($username)")
groupname = Base.getgroupname(st.gid)
isnothing(groupname) ? println(iob, " gid: $(st.gid)") : println(iob, " gid: $(st.gid) ($groupname)")
println(iob, " rdev: $(st.rdev)")
println(iob, "blksize: $(st.blksize)")
println(iob, " blocks: $(st.blocks)")
tnow = Libc.TimeVal().sec
println(iob, " mtime: $(iso_datetime_with_relative(st.mtime, tnow))")
println(iob, " ctime: $(iso_datetime_with_relative(st.ctime, tnow))")
end
println(io, "StatStruct for $(st.desc)")
println(io, " size: $(st.size) bytes")
println(io, " device: $(st.device)")
println(io, " inode: $(st.inode)")
println(io, " mode: 0o$(string(filemode(st), base = 8, pad = 6)) ($(filemode_string(st)))")
println(io, " nlink: $(st.nlink)")
username = Base.getusername(st.uid)
isnothing(username) ? println(io, " uid: $(st.uid)") : println(io, " uid: $(st.uid) ($username)")
groupname = Base.getgroupname(st.gid)
isnothing(groupname) ? println(io, " gid: $(st.gid)") : println(io, " gid: $(st.gid) ($groupname)")
println(io, " rdev: $(st.rdev)")
println(io, "blksize: $(st.blksize)")
println(io, " blocks: $(st.blocks)")
tnow = Libc.TimeVal().sec
println(io, " mtime: $(iso_datetime_with_relative(st.mtime, tnow))")
println(io, " ctime: $(iso_datetime_with_relative(st.ctime, tnow))")
end
print(io, str)
end

# stat & lstat functions
Expand Down Expand Up @@ -218,18 +211,17 @@ function filemode_string(mode)
(S_ISVTX, "T"),
(S_IXOTH, "x"))
)
str = sprint() do iob
for table in filemode_table
complete = true
for (bit, char) in table
if mode & bit == bit
print(iob, char)
complete = false
break
end
str = ""
for table in filemode_table
complete = true
for (bit, char) in table
if mode & bit == bit
str *= char
complete = false
break
end
complete && print(iob, "-")
end
complete && (str *= "-")
end
return str
end
Expand Down Expand Up @@ -451,3 +443,92 @@ function ismount(path...)
(s1.inode == s2.inode) && return true
false
end

mutable struct Cpasswd
pw_name::Ptr{Cchar} # username
pw_passwd::Ptr{Cchar} # user password
pw_uid::Cuint # user ID
pw_gid::Cuint # group ID
pw_gecos::Ptr{Cchar} # user information
pw_dir::Ptr{Cchar} # home directory
pw_shell::Ptr{Cchar} # shell program
Cpasswd() = new()
end
struct Passwd
name::String
passwd::String
uid::Int
gid::Int
gecos::String
dir::String
shell::String
end
function getpwuid(uid)
pd = Cpasswd()
pwdptr = pointer_from_objref(pd)
tempPwdPtr = pointer_from_objref(Cpasswd())
buf = Array{Cchar}(undef, 200)
bufsize = sizeof(buf)
ret = ccall(:getpwuid_r, Cint, (Cuint, Ptr{Cpasswd}, Ptr{UInt8}, Csize_t, Ptr{Cpasswd}), uid, pwdptr, buf, bufsize, tempPwdPtr)
ret != 0 && error("getpwuid_r error")
out = Passwd(
pd.pw_name == C_NULL ? "" : unsafe_string(pd.pw_name),
pd.pw_passwd == C_NULL ? "" : unsafe_string(pd.pw_passwd),
pd.pw_uid,
pd.pw_gid,
pd.pw_gecos == C_NULL ? "" : unsafe_string(pd.pw_gecos),
pd.pw_dir == C_NULL ? "" : unsafe_string(pd.pw_dir),
pd.pw_shell == C_NULL ? "" : unsafe_string(pd.pw_shell)
)
return out
end

function getusername(uid::Union{UInt32, UInt64})
if Sys.iswindows()
return nothing
else
pwd = getpwuid(uid)
isempty(pwd.name) && return
return pwd.name
end
end

mutable struct Cgroup
gr_name::Ptr{Cchar} # group name
gr_passwd::Ptr{Cchar} # group password
gr_gid::Cuint # group ID
gr_mem::Ptr{Ptr{Cchar}} # group members
Cgroup() = new()
end
struct Group
name::String
passwd::String
gid::Int
mem::Vector{String}
end
function getpwuid(gid)
gp = Cgroup()
gpptr = pointer_from_objref(gp)
tempGpPtr = pointer_from_objref(Cgroup())
buf = Array{Cchar}(undef, 200)
bufsize = sizeof(buf)
ret = ccall(:getgrgid_r, Cint, (Cuint, Ptr{Cgroup}, Ptr{UInt8}, Csize_t, Ptr{Cgroup}), gid, gpptr, buf, bufsize, tempGpPtr)
ret != 0 && error("getpwuid_r error")
out = Group(
gp.gr_name == C_NULL ? "" : unsafe_string(gp.gr_name),
gp.gr_passwd == C_NULL ? "" : unsafe_string(gp.gr_passwd),
gp.gr_gid,
gp.gr_mem == C_NULL ? "" : [""] # TODO: Actually populate
)
return out
end

function getgroupname(gid::Union{UInt32, UInt64})
if Sys.iswindows()
return nothing
else
gp = getpwuid(gid)
isempty(gp.name) && return
return gp.name
end
end
36 changes: 0 additions & 36 deletions base/util.jl
Expand Up @@ -622,39 +622,3 @@ function runtests(tests = ["all"]; ncores::Int = ceil(Int, Sys.CPU_THREADS::Int
"including error messages above and the output of versioninfo():\n$(read(buf, String))")
end
end

# stat.jl helpers which require methods that are loaded later

function getusername(uid::Union{UInt32, UInt64})
if Sys.islinux()
name = strip(read(pipeline(`getent passwd "$(Int(uid))"`,`cut -d: -f1`), String))
isempty(name) && return
return name
elseif Sys.isapple()
lines = read(`dscl . -list /Users UniqueID`, String)
isempty(lines) && return
lines = split(lines, "\n")
for line in lines
parts = split(line, " ", keepempty=false)
tryparse(Int, last(parts)) == Int(uid) && return first(parts)
end
end
nothing
end

function getgroupname(gid::Union{UInt32, UInt64})
if Sys.islinux()
name = strip(read(pipeline(`getent group "$(Int(gid))"`,`cut -d: -f1`), String))
isempty(name) && return
return name
elseif Sys.isapple()
lines = read(`dscl . -list /groups PrimaryGroupID`, String)
isempty(lines) && return
lines = split(lines, "\n")
for line in lines
parts = split(line, " ", keepempty=false)
tryparse(Int, last(parts)) == gid && return first(parts)
end
end
nothing
end

0 comments on commit 065d46e

Please sign in to comment.