The Erlang docs for file:read_file_info/1
state "file permissions [are] the sum" and "other bits...may be set", not instilling confidence. And, Google has not been my friend here.
I'm looking to take the mode returned by file:read_file_info/1
, eg 33188
, on a Linux machine and convert it into something more human readable and/or recognizable, like rw-r--r--
or 644
.
Any tips, links, or directions greatly appreciated.
The short way:
io_lib:format("~.8B", [Mode]).
... or:
io_lib:format("~.8B", [Mode band 8#777]).
For Mode = 33204
these two will give you respectively: ["100664"]
and ["664"]
.
The long way:
print(Mode) ->
print(Mode band 8#777, []).
print(0, Acc) when length(Acc) =:= 9 ->
Acc;
print(N, Acc) ->
Char = perm(N band 1, length(Acc) rem 3),
print(N bsr 1, [Char | Acc]).
perm(0, _) ->
$-;
perm(1, 0) ->
$x;
perm(1, 1) ->
$w;
perm(1, 2) ->
$r.
This one (function print/1
) for Mode = 33204
will give you this as result: "rw-rw-r--"
.
If something was unclear for one, I'll try to expound basic things behind the snippets which I have provided.
As @macintux mentioned already, the 33204
in fact is a decimal representation of the octal number 100664. These three lowest octal digits ( 664
) there is probably what you need, and so we get them with bitwise and ( band
) operation with the highest number which fits in three octal digits ( 8#777
). That's why short way is so short - you just tell erlang to convert Mode
to string as if it was the octal number.
The second representation you've mentioned (like rw-rw-r--
, something that ls
spits out) is easily reproducible from binary representation of the Mode
number. Note that three octal digits will give you exactly nine binary digits ( 8#644 = 2#110110100
). In fact this is the string rwxrwxrwx
where each element replaced by -
if corresponding digit equals 0
. If digit is 1
the element remains untouched.
So there is slightly cleaner approach to achieve this:
print(Mode) ->
print(Mode band 8#777, lists:reverse("rwxrwxrwx"), []).
print(0, [], Acc) ->
Acc;
print(N, [Char0 | Rest], Acc) ->
Char = char(N band 1, Char0),
print(N bsr 1, Rest, [Char | Acc]).
char(0, _) ->
$-;
char(1, C) ->
C.
I hope you got the point. Anyway feel free to ask any questions in comments if you doubt.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.