理解`man ls` long格式:set-user-id和set-group-id模式

时间:2013-11-27 09:40:36

标签: c unix permissions

我正在尝试在C中重新创建UNIX ls,作为学校练习的一部分。它必须完全支持-l选项并且行为与原始选项一样。

顺便说一句,我在OSX 10.8上,如果这有任何区别的话。

我无法理解长格式部分中MAN的这一部分。具体来说,我想知道同一行上的两个ifIF ... OR IF ...还是IF ... AND IF ...

The first of the following that applies:

S     If in the owner permissions, the file is not executable and set-user-ID mode is set.  If in the group permissions, the file is not executable and set-group-ID mode is set.

s     If in the owner permissions, the file is executable and set-user-ID mode is set.  If in the group permissions, the file is executable and setgroup-ID mode is set.

我从man 2 stat页面了解到,我可以检查set-user-id模式,如:

st_mode & 4000

和set-group-id模式一样:

st_mode & 2000

那么如何检查两者是否都已设定?如果st_mode & 2000为真,那么st_mode & 4000必须是假的吗?

2 个答案:

答案 0 :(得分:2)

  

从长格式部分我无法理解MAN的这一部分。   具体来说,我想知道同一行上的两个if是否是IF ...或者如果...或者IF ...并且如果......

IF是独立的。文件可以打开或关闭setuid位,也可以打开或关闭setgid位。 ls手册页中的描述可能有点令人困惑,因为措辞非常简洁。这是一个有希望更清晰的描述。有关位定义,请参阅stat.h手册页。

  • 首先,考虑所有者位和setuid位。

    • 如果所有者读取位已启用,则输出r,否则输出-
    • 如果所有者写入位已启用,则输出w,否则输出-
    • 如果所有者可执行位已关闭且setuid位为on,则输出S,否则如果所有者可执行位为on且setuid位为on,则输出s,否则如果所有者可执行位已打开,输出x,否则输出-
  • 接下来,考虑组位和setgid位。

    • 如果组读取位已打开,则输出r,否则输出-
    • 如果组写位已打开,则输出w,否则输出-
    • 如果组可执行位关闭且setgid位为on,则输出S,否则如果组可执行位为on且setgid位为on,则输出s,否则为组可执行位已打开,输出x,否则输出-
  • 接下来,考虑其他位和S_ISVTX位。

    • 如果其他读取位开启,则输出r,否则输出-
    • 如果另一个写入位开启,则输出w,否则输出-
    • 如果文件是目录而另一个可执行位已关闭并且S_ISVTX位已打开,则输出T,否则,如果该文件是目录而另一个可执行位已打开且S_ISVTX位已打开,输出t,否则如果其他可执行位开启,则输出x,否则输出-
    • 在某些版本的UNIX中,省略了“如果文件是目录”要求,并且如果满足其他要求,则可以为普通文件输出Tt

历史观点

最初,setuid,setgid和save-text位仅对可执行文件有意义,因此长格式ls可以通过x替换s标记或t,据了解,隐含了x标记。 UNIX的后续版本允许setuid,setgid和save-text位对于非可执行文件和目录具有不同的语义(通常,文件锁定,通过新文件继承目录组,以及限制删除),因此{ {1}}和S标记已添加到T的输出中。

答案 1 :(得分:1)

您可以通过比较掩码的结果和掩码来检查是否设置了两个(或更多)位:

(st_mode & 0x6000) == 0x6000