Reputation: 7007
I'm trying to re-create the UNIX ls
in C as part of an exercise for school. It has to support the -l
option entirely and behave just like the original.
By the way, I'm on OSX 10.8, if that makes any difference.
I'm having trouble understanding this part of the MAN
, from the Long Format section. Specifically, I'm wondering if the two if
s on the same lines are IF ... OR IF ...
or 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.
As I understand it from the man 2 stat
page, I can check for set-user-id mode like:
st_mode & 4000
And set-group-id mode like this:
st_mode & 2000
So how can I check if both are set? If st_mode & 2000
is true, st_mode & 4000
has to be false right?
Upvotes: 0
Views: 295
Reputation: 10271
I'm having trouble understanding this part of the MAN, from the Long Format section. Specifically, I'm wondering if the two ifs on the same lines are IF ... OR IF ... or IF ... AND IF ...
The IFs are independent. A file can have the setuid bit on or off, and it can also have the setgid bit on or off. The description in the ls
man page can be a bit confusing because the wording is so concise. Here's a description that will hopefully be clearer. Refer to the stat.h man page for the bit definitions.
First, consider the owner bits and the setuid bit.
r
, else output -
.w
, else output -
.S
, else if the owner executable bit is on and the setuid bit is on, output s
, else if the owner executable bit is on, output x
, else output -
.Next, consider the group bits and the setgid bit.
r
, else output -
.w
, else output -
.S
, else if the group executable bit is on and the setgid bit is on, output s
, else if the group executable bit is on, output x
, else output -
.Next, consider the other bits and the S_ISVTX bit.
r
, else output -
.w
, else output -
.T
, else if the file is a directory and the other executable bit is on and the S_ISVTX bit is on, output t
, else if the other executable bit is on, output x
, else output -
.T
or t
can be output for ordinary files if the other requirements are met.HISTORICAL PERSPECTIVE
Originally, the setuid, setgid, and save-text bits were only meaningful for executable files, so the long format ls
could get away with replacing the x
tags with s
or t
, and it was understood that the x
tag was implied. Later revisions of UNIX allowed the setuid, setgid, and save-text bits to have different semantics for non-executable files and for directories (generally, file locking, inheritance of a directory's group by new files, and restricted deletion), so the S
and T
tags were added to ls
's output.
Upvotes: 2
Reputation: 409356
You can check if two (or more) bits are set by comparing the result of the masking with the mask:
(st_mode & 0x6000) == 0x6000
Upvotes: 1