diskfs / go-diskfs

MIT License
494 stars 112 forks source link

squashfs: set Mode bits correctly in FileInfo #199

Closed ncw closed 8 months ago

deitch commented 8 months ago

I have gone through some very not fun times dealing with when this should have the dir, etc. mode bits set and when not. Are you sure that this is consistently handled this way in go? i.e. when I use the usual built-in os commands to get FileInfo, does it always return with these bits set? If so, I am fine with it, but I want to be sure.

ncw commented 8 months ago

I have gone through some very not fun times dealing with when this should have the dir, etc. mode bits set and when not.

Yes I've been there too :-)

Are you sure that this is consistently handled this way in go? i.e. when I use the usual built-in os commands to get FileInfo, does it always return with these bits set? If so, I am fine with it, but I want to be sure.

The os.FileMode has had a chequered history in Go. At first it was just whatever was read from the OS but then Go got Windows support which is like putting a round peg in a square hole so it had to be changed. It is still rather unix centric, but it is platform independent now.

If you look at the help for fs.FileMode (os.FileMode is just an alias now-a-days) you'll see

type FileMode uint32
    A FileMode represents a file's mode and permission bits. The bits have the
    same definition on all systems, so that information about files can be moved
    from one system to another portably. Not all bits apply to all systems.
    The only required bit is ModeDir for directories.

And if you look at the actual definition of the bits you'll see that they are defined like this for all OSes.

// The defined file mode bits are the most significant bits of the FileMode.
// The nine least-significant bits are the standard Unix rwxrwxrwx permissions.
// The values of these bits should be considered part of the public API and
// may be used in wire protocols or disk representations: they must not be
// changed, although new bits might be added.
const (
    // The single letters are the abbreviations
    // used by the String method's formatting.
    ModeDir        FileMode = 1 << (32 - 1 - iota) // d: is a directory
    ModeAppend                                     // a: append-only
    ModeExclusive                                  // l: exclusive use
    ModeTemporary                                  // T: temporary file; Plan 9 only
    ModeSymlink                                    // L: symbolic link
    ModeDevice                                     // D: device file
    ModeNamedPipe                                  // p: named pipe (FIFO)
    ModeSocket                                     // S: Unix domain socket
    ModeSetuid                                     // u: setuid
    ModeSetgid                                     // g: setgid
    ModeCharDevice                                 // c: Unix character device, when ModeDevice is set
    ModeSticky                                     // t: sticky
    ModeIrregular                                  // ?: non-regular file; nothing else is known about this file

    // Mask for the type bits. For regular files, none will be set.
    ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular

    ModePerm FileMode = 0777 // Unix permission bits
)

So I feel confident in saying that yes, it will always use exactly these bits whatever OS you are running on.

Perhaps the code I wrote to implement this should zero out everything except the 9 unix permissions bits so there aren't any Linux bits left in the mode so we've entirely Go-ified the mode. Currently it only zeroes out the fs.ModeType which means it should work for all Go programs but there is a possibility of reading any other bits from the mode.

deitch commented 8 months ago

Perhaps the code I wrote to implement this should zero out everything except the 9 unix permissions bits so there aren't any Linux bits left in the mode so we've entirely Go-ified the mode.

Any downside to doing this? It sounds right to me, but 🤷‍♂️

If you look at the help for fs.FileMode (os.FileMode is just an alias now-a-days) you'll see

Yeah, I implemented a read-write fs.FS interface and implementation for another project. Hard but good.

ncw commented 8 months ago

Perhaps the code I wrote to implement this should zero out everything except the 9 unix permissions bits so there aren't any Linux bits left in the mode so we've entirely Go-ified the mode.

Any downside to doing this? It sounds right to me, but 🤷‍♂️

I think making the FileMode 100% Go friendly is the right thing to do. If there are other bits in there we can extract to Go standard bits then that can be future work.

I've updated the PR

Yeah, I implemented a read-write fs.FS interface and implementation for another project. Hard but good.

:-)