aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/sys/unix/syscall_solaris.go
diff options
context:
space:
mode:
authorGibheer <gibheer+git@zero-knowledge.org>2022-11-11 11:22:50 +0100
committerGibheer <gibheer+git@zero-knowledge.org>2022-11-11 11:22:50 +0100
commitfe6bd04947e26a962fab3cf7a354abd44333bda6 (patch)
treede4714364747c05d391ab665176413eb24938545 /vendor/golang.org/x/sys/unix/syscall_solaris.go
parentdc9dfb76ff9375e6368e9e05a40e6dc07b325a8d (diff)
update dependencies
Diffstat (limited to 'vendor/golang.org/x/sys/unix/syscall_solaris.go')
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_solaris.go217
1 files changed, 172 insertions, 45 deletions
diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go
index b5ec457..2109e56 100644
--- a/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -750,8 +750,8 @@ type EventPort struct {
// we should handle things gracefully. To do so, we need to keep an extra
// reference to the cookie around until the event is processed
// thus the otherwise seemingly extraneous "cookies" map
- // The key of this map is a pointer to the corresponding &fCookie.cookie
- cookies map[*interface{}]*fileObjCookie
+ // The key of this map is a pointer to the corresponding fCookie
+ cookies map[*fileObjCookie]struct{}
}
// PortEvent is an abstraction of the port_event C struct.
@@ -778,7 +778,7 @@ func NewEventPort() (*EventPort, error) {
port: port,
fds: make(map[uintptr]*fileObjCookie),
paths: make(map[string]*fileObjCookie),
- cookies: make(map[*interface{}]*fileObjCookie),
+ cookies: make(map[*fileObjCookie]struct{}),
}
return e, nil
}
@@ -799,6 +799,7 @@ func (e *EventPort) Close() error {
}
e.fds = nil
e.paths = nil
+ e.cookies = nil
return nil
}
@@ -826,17 +827,16 @@ func (e *EventPort) AssociatePath(path string, stat os.FileInfo, events int, coo
if _, found := e.paths[path]; found {
return fmt.Errorf("%v is already associated with this Event Port", path)
}
- fobj, err := createFileObj(path, stat)
+ fCookie, err := createFileObjCookie(path, stat, cookie)
if err != nil {
return err
}
- fCookie := &fileObjCookie{fobj, cookie}
- _, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
+ _, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
if err != nil {
return err
}
e.paths[path] = fCookie
- e.cookies[&fCookie.cookie] = fCookie
+ e.cookies[fCookie] = struct{}{}
return nil
}
@@ -858,7 +858,7 @@ func (e *EventPort) DissociatePath(path string) error {
if err == nil {
// dissociate was successful, safe to delete the cookie
fCookie := e.paths[path]
- delete(e.cookies, &fCookie.cookie)
+ delete(e.cookies, fCookie)
}
delete(e.paths, path)
return err
@@ -871,13 +871,16 @@ func (e *EventPort) AssociateFd(fd uintptr, events int, cookie interface{}) erro
if _, found := e.fds[fd]; found {
return fmt.Errorf("%v is already associated with this Event Port", fd)
}
- fCookie := &fileObjCookie{nil, cookie}
- _, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
+ fCookie, err := createFileObjCookie("", nil, cookie)
+ if err != nil {
+ return err
+ }
+ _, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
if err != nil {
return err
}
e.fds[fd] = fCookie
- e.cookies[&fCookie.cookie] = fCookie
+ e.cookies[fCookie] = struct{}{}
return nil
}
@@ -896,27 +899,31 @@ func (e *EventPort) DissociateFd(fd uintptr) error {
if err == nil {
// dissociate was successful, safe to delete the cookie
fCookie := e.fds[fd]
- delete(e.cookies, &fCookie.cookie)
+ delete(e.cookies, fCookie)
}
delete(e.fds, fd)
return err
}
-func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
- fobj := new(fileObj)
- bs, err := ByteSliceFromString(name)
- if err != nil {
- return nil, err
- }
- fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
- s := stat.Sys().(*syscall.Stat_t)
- fobj.Atim.Sec = s.Atim.Sec
- fobj.Atim.Nsec = s.Atim.Nsec
- fobj.Mtim.Sec = s.Mtim.Sec
- fobj.Mtim.Nsec = s.Mtim.Nsec
- fobj.Ctim.Sec = s.Ctim.Sec
- fobj.Ctim.Nsec = s.Ctim.Nsec
- return fobj, nil
+func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
+ fCookie := new(fileObjCookie)
+ fCookie.cookie = cookie
+ if name != "" && stat != nil {
+ fCookie.fobj = new(fileObj)
+ bs, err := ByteSliceFromString(name)
+ if err != nil {
+ return nil, err
+ }
+ fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
+ s := stat.Sys().(*syscall.Stat_t)
+ fCookie.fobj.Atim.Sec = s.Atim.Sec
+ fCookie.fobj.Atim.Nsec = s.Atim.Nsec
+ fCookie.fobj.Mtim.Sec = s.Mtim.Sec
+ fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
+ fCookie.fobj.Ctim.Sec = s.Ctim.Sec
+ fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
+ }
+ return fCookie, nil
}
// GetOne wraps port_get(3c) and returns a single PortEvent.
@@ -929,44 +936,50 @@ func (e *EventPort) GetOne(t *Timespec) (*PortEvent, error) {
p := new(PortEvent)
e.mu.Lock()
defer e.mu.Unlock()
- e.peIntToExt(pe, p)
+ err = e.peIntToExt(pe, p)
+ if err != nil {
+ return nil, err
+ }
return p, nil
}
// peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
// NOTE: Always call this function while holding the e.mu mutex
-func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) {
+func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
+ if e.cookies == nil {
+ return fmt.Errorf("this EventPort is already closed")
+ }
peExt.Events = peInt.Events
peExt.Source = peInt.Source
- cookie := (*interface{})(unsafe.Pointer(peInt.User))
- peExt.Cookie = *cookie
+ fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
+ _, found := e.cookies[fCookie]
+
+ if !found {
+ panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
+ }
+ peExt.Cookie = fCookie.cookie
+ delete(e.cookies, fCookie)
+
switch peInt.Source {
case PORT_SOURCE_FD:
- delete(e.cookies, cookie)
peExt.Fd = uintptr(peInt.Object)
// Only remove the fds entry if it exists and this cookie matches
if fobj, ok := e.fds[peExt.Fd]; ok {
- if &fobj.cookie == cookie {
+ if fobj == fCookie {
delete(e.fds, peExt.Fd)
}
}
case PORT_SOURCE_FILE:
- if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) {
- // Use our stashed reference rather than using unsafe on what we got back
- // the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
- peExt.fobj = fCookie.fobj
- } else {
- panic("mismanaged memory")
- }
- delete(e.cookies, cookie)
+ peExt.fobj = fCookie.fobj
peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
// Only remove the paths entry if it exists and this cookie matches
if fobj, ok := e.paths[peExt.Path]; ok {
- if &fobj.cookie == cookie {
+ if fobj == fCookie {
delete(e.paths, peExt.Path)
}
}
}
+ return nil
}
// Pending wraps port_getn(3c) and returns how many events are pending.
@@ -990,7 +1003,7 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
got := uint32(min)
max := uint32(len(s))
var err error
- ps := make([]portEvent, max, max)
+ ps := make([]portEvent, max)
_, err = port_getn(e.port, &ps[0], max, &got, timeout)
// got will be trustworthy with ETIME, but not any other error.
if err != nil && err != ETIME {
@@ -998,8 +1011,122 @@ func (e *EventPort) Get(s []PortEvent, min int, timeout *Timespec) (int, error)
}
e.mu.Lock()
defer e.mu.Unlock()
+ valid := 0
for i := 0; i < int(got); i++ {
- e.peIntToExt(&ps[i], &s[i])
+ err2 := e.peIntToExt(&ps[i], &s[i])
+ if err2 != nil {
+ if valid == 0 && err == nil {
+ // If err2 is the only error and there are no valid events
+ // to return, return it to the caller.
+ err = err2
+ }
+ break
+ }
+ valid = i + 1
+ }
+ return valid, err
+}
+
+//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
+
+func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
+ var clp, datap *strbuf
+ if len(cl) > 0 {
+ clp = &strbuf{
+ Len: int32(len(cl)),
+ Buf: (*int8)(unsafe.Pointer(&cl[0])),
+ }
}
- return int(got), err
+ if len(data) > 0 {
+ datap = &strbuf{
+ Len: int32(len(data)),
+ Buf: (*int8)(unsafe.Pointer(&data[0])),
+ }
+ }
+ return putmsg(fd, clp, datap, flags)
+}
+
+//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
+
+func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
+ var clp, datap *strbuf
+ if len(cl) > 0 {
+ clp = &strbuf{
+ Maxlen: int32(len(cl)),
+ Buf: (*int8)(unsafe.Pointer(&cl[0])),
+ }
+ }
+ if len(data) > 0 {
+ datap = &strbuf{
+ Maxlen: int32(len(data)),
+ Buf: (*int8)(unsafe.Pointer(&data[0])),
+ }
+ }
+
+ if err = getmsg(fd, clp, datap, &flags); err != nil {
+ return nil, nil, 0, err
+ }
+
+ if len(cl) > 0 {
+ retCl = cl[:clp.Len]
+ }
+ if len(data) > 0 {
+ retData = data[:datap.Len]
+ }
+ return retCl, retData, flags, nil
+}
+
+func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
+ return ioctlRet(fd, req, uintptr(arg))
+}
+
+func IoctlSetString(fd int, req uint, val string) error {
+ bs := make([]byte, len(val)+1)
+ copy(bs[:len(bs)-1], val)
+ err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
+ runtime.KeepAlive(&bs[0])
+ return err
+}
+
+// Lifreq Helpers
+
+func (l *Lifreq) SetName(name string) error {
+ if len(name) >= len(l.Name) {
+ return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
+ }
+ for i := range name {
+ l.Name[i] = int8(name[i])
+ }
+ return nil
+}
+
+func (l *Lifreq) SetLifruInt(d int) {
+ *(*int)(unsafe.Pointer(&l.Lifru[0])) = d
+}
+
+func (l *Lifreq) GetLifruInt() int {
+ return *(*int)(unsafe.Pointer(&l.Lifru[0]))
+}
+
+func (l *Lifreq) SetLifruUint(d uint) {
+ *(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
+}
+
+func (l *Lifreq) GetLifruUint() uint {
+ return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
+}
+
+func IoctlLifreq(fd int, req uint, l *Lifreq) error {
+ return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
+}
+
+// Strioctl Helpers
+
+func (s *Strioctl) SetInt(i int) {
+ s.Len = int32(unsafe.Sizeof(i))
+ s.Dp = (*int8)(unsafe.Pointer(&i))
+}
+
+func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
+ return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
}