Documentation
¶
Index ¶
Examples ¶
- FileModePerm (RawCharacter)
- FileModePerm (SUDO)
- FileModePermString
- FileModeString
- FileModeString (Character)
- FileModeString (Socket)
- FileModeTypeLetter
- Mode.FileMode
- Mode.IsDir
- Mode.IsRegular
- Mode.Perm
- Mode.Perm (Parse)
- Mode.PermString
- Mode.PermString (Directory)
- Mode.PermString (SetUidBits)
- Mode.String
- New
- Parse
- Parse (DirectoryMixedRaw)
- Parse (Invalid)
- Parse (Mixed)
- ParseFileMode
Constants ¶
This section is empty.
Variables ¶
var ( ErrorModeLength = errors.New("Invalid Mode Length") ErrorMode = errors.New("Invalid Mode") )
Functions ¶
func Chmod ¶
Functional call to os.Chmod with the ability to set permissions based on the Mode value.
func FileModePermString ¶
Return the lower 12 bits in a UNIX permission string format
Example ¶
stat, _ := os.Lstat("/tmp") m := stat.Mode() fmt.Printf("mode: %q\n", unixmode.FileModePermString(m))
Output: mode: "rwxrwxrwt"
func FileModeString ¶
Return the Mode with the TypeLetter + PermString + " " The extra space is for compatibility with 4.4BSD strmode
Example ¶
stat, _ := os.Lstat("/tmp") m := stat.Mode() fmt.Printf("mode: %q\n", unixmode.FileModeString(m))
Output: mode: "drwxrwxrwt "
Example (Character) ¶
if stat, err := os.Lstat("/dev/lp0"); err != nil { log.Fatal("Could not stat character device", err) } else { m := stat.Mode() fmt.Printf("mode: %q\n", unixmode.FileModeString(m)) }
Output: mode: "crw-rw---- "
Example (Socket) ¶
if stat, err := os.Lstat("/dev/log"); err != nil { log.Fatal("Could not stat socket", err) } else { m := stat.Mode() fmt.Printf("mode: %q\n", unixmode.FileModeString(m)) }
Output: mode: "srw-rw-rw- "
func FileModeTypeLetter ¶
Return the TypeLetter defined in the FileMode bits.
Example ¶
if stat, err := os.Lstat("/dev/null"); err != nil { log.Fatal("Could not stat character device", err) } else { m := stat.Mode() fmt.Printf("mode: %c\n", unixmode.FileModeTypeLetter(m)) }
Output: mode: c
func ParseFileMode ¶
A function to parse a fs.FileMode string into the standard fs.FileMode
Example ¶
val := "augrwxr--r--" fm, _ := unixmode.ParseFileMode(val) fmt.Printf("File Mode: %o %s == %s\n", fm, val, fm)
Output: File Mode: 10060000744 augrwxr--r-- == augrwxr--r--
Types ¶
type Mode ¶
type Mode uint16
A Mode represents a file's mode and permission bits. The bits are used in the POSIX definition.
const ( // Types (upper 4 bits) ModeTypeMask Mode = 0170000 /* type of file mask */ ModeNamedPipe Mode = 0010000 /* named pipe (fifo) */ ModeCharDevice Mode = 0020000 /* character special */ ModeDir Mode = 0040000 /* directory */ ModeDevice Mode = 0060000 /* block special */ ModeRegular Mode = 0100000 /* regular */ ModeSymlink Mode = 0120000 /* symbolic link */ ModeSocket Mode = 0140000 /* socket */ // Set ID / Sticky (middle 3 bits) ModeSetuid Mode = 0004000 /* set-user-ID on execution */ ModeSetgid Mode = 0002000 /* set-group-ID on execution */ ModeSticky Mode = 0001000 /* save swapped text even after use */ // Permissions (lower 9 bits) ModeUserMask Mode = 0000700 /* RWX mask for owner */ ModeReadUser Mode = 0000400 /* R for owner */ ModeWriteUser Mode = 0000200 /* W for owner */ ModeExecUser Mode = 0000100 /* X for owner */ ModeGroupMask Mode = 0000070 /* RWX mask for group */ ModeReadGroup Mode = 0000040 /* R for group */ ModeWriteGroup Mode = 0000020 /* W for group */ ModeExecGroup Mode = 0000010 /* X for group */ ModeOtherMask Mode = 0000007 /* RWX mask for other */ ModeReadOther Mode = 0000004 /* R for other */ ModeWriteOther Mode = 0000002 /* W for other */ ModeExecOther Mode = 0000001 /* X for other */ )
The defined file mode bits are the most significant bits of the Mode. The values of these bits are defined by the Unix filemode standard and may be used in wire protocols or disk representations: they must not be changed, although new bits might be added.
func FileModePerm ¶
Perm returns the Unix permission bits in FileMode m. That is, it takes the GoLang fs.FileMode and changes the bit flags into the Mode permission format without maintaining the type.
This is useful for setting permissions on a linux system, like this:
Similarly, one can achieve the same result by doing:
m, err := os.Stat("/tmp") myPerm := unixmode.FileModePerm(m.FileMode()) os.Chmod(name, myPerm)
Note: GoLang reserves bits 10-12 along with 3 additional random bit locations for sticky bit values. By keeping 10-12 clear and parsing down the higher order bits on top of these three bits, it has effectively disabled the lower 3 bits from being used. This methodology is to create "Go's portable mode bits"
This seems like a duplication of efforts for an extra 3 higher order bits to be assigned when the lower 3 bits are used when calling os.Chmod and conversely the syscallMode. This duplication of bit usage makes life easier for developers only interested in the lower 12, however creating an additional higher order bits just seems odd when the lower bits are still used. One may ask "why not re-use bits which already have a pretty stable definition?" With 32 bits in fs.FileMode and twice the declaration of what defines a sticky bit, they would have a valid point. This leaves one to wonder: when bits are duplicated, one can be left playing the game: "guess the bit which was used" when calling Chmod? Besides, what can go wrong when bits at two locations in a register could trigger SUID on a root owned executable?
Ref: https://cs.opensource.google/go/go/+/master:src/os/file_posix.go;l=62-75
Example (RawCharacter) ¶
if stat, err := os.Lstat("/dev/lp0"); err != nil { log.Fatal("Could not stat character device", err) } else { m := stat.Mode() fmt.Printf("mode: %c %04o\n", unixmode.FileModeTypeLetter(m), unixmode.FileModePerm(m)) }
Output: mode: c 0660
Example (SUDO) ¶
if stat, err := os.Lstat("/usr/bin/sudo"); err != nil { log.Fatal("Could not stat character device", err) } else { m := stat.Mode() fmt.Printf("mode: %c %04o\n", unixmode.FileModeTypeLetter(m), unixmode.FileModePerm(m)) }
Output: mode: - 4111
func New ¶
Create a unixmode.Mode(uint16) from a FileMode(uint32) by cross referencing bits.
Example ¶
fm := fs.FileMode(0777 | fs.ModeSetuid) fmt.Printf("Full unix mode: %07o\n", unixmode.New(fm)) fmt.Printf("Unix perms: %05o\n", unixmode.New(fm).Perm())
Output: Full unix mode: 0104777 Unix perms: 04777
func Parse ¶
Parse will take three formats and convert them into a Mode with the bits set:
"rwsrwxrwx" - 9 bytes, Returns the lower 12 bits set
"-rwsrwxrwx" - 10 bytes, Lower 12 bits and includes setting the file ModeType
"-rwsrwxrwx " - 11 bytes, Compatibility with newer os's with ACLs and SELinux contexts
Example ¶
if m, err := unixmode.Parse("rwxrwx---"); err != nil { log.Fatal(err) } else { fmt.Printf("mode: %04o\n", m) }
Output: mode: 0770
Example (DirectoryMixedRaw) ¶
if m, err := unixmode.Parse("d-w-r-S-wT"); err != nil { log.Fatal(err) } else { fmt.Printf("mode: %04o\n", m) }
Output: mode: 43242
Example (Invalid) ¶
if m, err := unixmode.Parse("drwSrwSrwS "); err != nil { fmt.Println("Err:", err) } else { fmt.Printf("mode: %04o\n", m) }
Output: Err: Invalid 'S' at position 9
Example (Mixed) ¶
if m, err := unixmode.Parse("-w-r-S-wT"); err != nil { log.Fatal(err) } else { fmt.Printf("mode: %04o\n", m.Perm()) }
Output: mode: 3242
func (Mode) FileMode ¶
Create a FileMode(uint32) from a unixmode.Mode(uint16) by cross referencing bits.
Example ¶
fm, _ := unixmode.Parse("dr-sr-srwx") // This is the standard go FileMode output, basically only "rwx" fmt.Printf("Unix mode: %q\n", fm.PermString()) // Note that Go FileMode does not show suid bits fmt.Printf("Go FileMode: %q\n", fm.FileMode().Perm())
Output: Unix mode: "r-sr-srwx" Go FileMode: "-r-xr-xrwx"
func (Mode) IsDir ¶
IsDir reports whether m describes a directory. That is, it tests for the ModeDir bit being set in m.
Example ¶
m, _ := unixmode.Parse("dr-s-wSr-T") fmt.Printf("is dir: %v\n", m.IsDir())
Output: is dir: true
func (Mode) IsRegular ¶
IsRegular reports whether m describes a regular file. That is, it tests that the ModeRegular bit is the only type set.
Example ¶
m, _ := unixmode.Parse("-r-s-wSr-T") fmt.Printf("is regular: %v\n", m.IsRegular())
Output: is regular: true
func (Mode) Perm ¶
Perm returns the Unix permission bits in m. That is, it returns the Mode & 07777, as the lower 12 bits describe the full permissions.
Example ¶
m := unixmode.Mode(041755) fmt.Printf("mode: %04o\n", m.Perm())
Output: mode: 1755
Example (Parse) ¶
m, _ := unixmode.Parse("r-s-wSr-T") fmt.Printf("mode: %04o\n", m.Perm())
Output: mode: 7524
func (Mode) PermString ¶
Return the lower 12 bits in a UNIX permission string format
Example ¶
m := unixmode.Mode(0755) fmt.Printf("mode: %q\n", m.PermString())
Output: mode: "rwxr-xr-x"
Example (Directory) ¶
m := unixmode.Mode(040755) fmt.Printf("mode: %q\n", m.PermString())
Output: mode: "rwxr-xr-x"
Example (SetUidBits) ¶
m := unixmode.Mode(06755) fmt.Printf("mode: %q\n", m.PermString())
Output: mode: "rwsr-sr-x"
func (Mode) String ¶
Return the Mode with the TypeLetter + PermString + " " The extra space is for compatibility with 4.4BSD strmode
Example ¶
m := unixmode.Mode(041755) fmt.Printf("mode: %q\n", m.String())
Output: mode: "drwxr-xr-t "
func (Mode) TypeLetter ¶
Return the TypeLetter defined in the Mode bits.