How to use Erlang file:read_file_info permissions/mode info?

岁酱吖の 提交于 2019-12-11 02:55:38

问题


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, e.g. 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.


回答1:


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.



来源:https://stackoverflow.com/questions/13183838/how-to-use-erlang-fileread-file-info-permissions-mode-info

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!