conradkleinespel
conradkleinespel

Reputation: 7007

Understanding `man ls` long format: set-user-id and set-group-id modes

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 ifs 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

Answers (2)

Mark Plotnick
Mark Plotnick

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.

    • If the owner read bit is on, output r, else output -.
    • If the owner write bit is on, output w, else output -.
    • If the owner executable bit is off and the setuid bit is on, 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.

    • If the group read bit is on, output r, else output -.
    • If the group write bit is on, output w, else output -.
    • If the group executable bit is off and the setgid bit is on, 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.

    • If the other read bit is on, output r, else output -.
    • If the other write bit is on, output w, else output -.
    • If the file is a directory and the other executable bit is off and the S_ISVTX bit is on, 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 -.
    • In some versions of UNIX, the "if the file is a directory" requirement is omitted, and 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

Some programmer dude
Some programmer dude

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

Related Questions