v1.9.0
IMPROVED: * Removed *BROKEN* dep. lrn2fixurshitk
This commit is contained in:
149
fsutils/funcs_linux.go
Normal file
149
fsutils/funcs_linux.go
Normal file
@@ -0,0 +1,149 @@
|
||||
//go:build linux
|
||||
|
||||
package fsutils
|
||||
|
||||
import (
|
||||
`os`
|
||||
`reflect`
|
||||
`unsafe`
|
||||
|
||||
`golang.org/x/sys/unix`
|
||||
`r00t2.io/goutils/bitmask`
|
||||
`r00t2.io/sysutils/paths`
|
||||
)
|
||||
|
||||
func GetAttrs(path string) (attrs *FsAttrs, err error) {
|
||||
|
||||
var f *os.File
|
||||
var evalAttrs FsAttrs
|
||||
var attrVal fsAttr
|
||||
var attrValBit bitmask.MaskBit
|
||||
var reflectVal reflect.Value
|
||||
var field reflect.Value
|
||||
var myPath string = path
|
||||
|
||||
if err = paths.RealPath(&myPath); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if f, err = os.Open(myPath); err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
reflectVal = reflect.ValueOf(&evalAttrs).Elem()
|
||||
|
||||
if attrVal, err = getAttrs(f); err != nil {
|
||||
return
|
||||
}
|
||||
attrValBit = bitmask.MaskBit(attrVal)
|
||||
|
||||
for attrNm, attrInt := range AttrNameValueMap {
|
||||
field = reflectVal.FieldByName(attrNm)
|
||||
field.SetBool(attrValBit.HasFlag(bitmask.MaskBit(attrInt)))
|
||||
}
|
||||
|
||||
attrs = new(FsAttrs)
|
||||
*attrs = evalAttrs
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getAttrs is the unexported low-level syscall to get attributes.
|
||||
func getAttrs(f *os.File) (attrVal fsAttr, err error) {
|
||||
|
||||
var u uint
|
||||
var curFlags int
|
||||
// var errNo syscall.Errno
|
||||
|
||||
/*
|
||||
if _, _, errNo = unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.FS_IOC_GETFLAGS, uintptr(unsafe.Pointer(&curFlags))); errNo != 0 {
|
||||
err = os.NewSyscallError("ioctl: FS_IOC_GETFLAGS", errNo)
|
||||
return
|
||||
}
|
||||
*/
|
||||
if curFlags, err = unix.IoctlGetInt(int(f.Fd()), unix.FS_IOC_GETFLAGS); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
u = uint(curFlags)
|
||||
|
||||
attrVal = fsAttr(u)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// invertMap returns some handy consts remapping for easier lookups.
|
||||
func invertMap(origMap map[string]fsAttr) (newMap map[fsAttr]string) {
|
||||
|
||||
if origMap == nil {
|
||||
return
|
||||
}
|
||||
newMap = make(map[fsAttr]string)
|
||||
|
||||
for k, v := range origMap {
|
||||
newMap[v] = k
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// setAttrs is the unexported low-level syscall to set attributes. attrs may be OR'd.
|
||||
func setAttrs(f *os.File, attrs fsAttr) (err error) {
|
||||
|
||||
var curAttrs fsAttr
|
||||
var ab bitmask.MaskBit
|
||||
var errNo unix.Errno
|
||||
var val uint
|
||||
|
||||
if curAttrs, err = getAttrs(f); err != nil {
|
||||
return
|
||||
}
|
||||
ab = bitmask.MaskBit(curAttrs)
|
||||
|
||||
if ab.HasFlag(bitmask.MaskBit(attrs)) {
|
||||
return
|
||||
}
|
||||
|
||||
ab.AddFlag(bitmask.MaskBit(attrs))
|
||||
|
||||
val = ab.Value()
|
||||
|
||||
/*
|
||||
if err = unix.IoctlSetInt(int(f.Fd()), unix.FS_IOC_SETFLAGS, int(ab.Value())); err != nil {
|
||||
return
|
||||
}
|
||||
*/
|
||||
if _, _, errNo = unix.Syscall(unix.SYS_IOCTL, f.Fd(), unix.FS_IOC_SETFLAGS, uintptr(unsafe.Pointer(&val))); errNo != 0 {
|
||||
err = os.NewSyscallError("ioctl: SYS_IOCTL", errNo)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// unsetAttrs is the unexported low-level syscall to remove attributes. attrs may be OR'd.
|
||||
func unsetAttrs(f *os.File, attrs fsAttr) (err error) {
|
||||
|
||||
var curAttrs fsAttr
|
||||
var ab bitmask.MaskBit
|
||||
|
||||
if curAttrs, err = getAttrs(f); err != nil {
|
||||
return
|
||||
}
|
||||
ab = bitmask.MaskBit(curAttrs)
|
||||
|
||||
if !ab.HasFlag(bitmask.MaskBit(attrs)) {
|
||||
return
|
||||
}
|
||||
|
||||
ab.ClearFlag(bitmask.MaskBit(attrs))
|
||||
|
||||
/*
|
||||
if err = unix.IoctlSetInt(int(f.Fd()), unix.FS_IOC_SETFLAGS, int(ab.Value())); err != nil {
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user