blob: 261d378c241bf690850df23bdae767be6045a0bd [file] [log] [blame]
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build fuchsia
package fdio
import (
"syscall/zx"
"syscall/zx/fidl"
"syscall/zx/io"
)
func nodeFromInfo(info *io.NodeInfo, node *io.NodeInterface) (result FDIO, err error) {
if info == nil {
if err = ((*fidl.Proxy)(node)).Channel.Close(); err != nil {
return nil, err
}
return nil, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
switch info.NodeInfoTag {
case io.NodeInfoService:
// TODO(mknyszek): Figure out the correct type to return here.
result = &Node{NodeInterface: node}
case io.NodeInfoFile:
result = &File{
Node: Node{NodeInterface: node},
Event: info.File.Event,
}
case io.NodeInfoDevice:
result = &File{
Node: Node{NodeInterface: node},
Event: info.Device.Event,
}
case io.NodeInfoDirectory:
result = &Directory{Node: Node{NodeInterface: node}}
case io.NodeInfoPipe:
if err = ((*fidl.Proxy)(node)).Channel.Close(); err != nil {
return nil, err
}
result = NewPipe(info.Pipe.Socket)
case io.NodeInfoVmofile:
if err = ((*fidl.Proxy)(node)).Channel.Close(); err != nil {
return nil, err
}
result, err = NewVMOFile(info.Vmofile.Vmo, info.Vmofile.Offset, info.Vmofile.Length)
if err != nil {
return nil, err
}
default:
if err = ((*fidl.Proxy)(node)).Channel.Close(); err != nil {
return nil, err
}
return nil, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
return result, nil
}
// Node is a wrapper around an NodeInterface which implements FDIO.
type Node struct {
*io.NodeInterface
}
// IsValid returns true if the Node is valid.
func (n *Node) IsValid() bool {
if n.NodeInterface == nil {
return false
}
return ((*fidl.Proxy)(n.NodeInterface)).IsValid()
}
// Handles returns a slice of untyped zx handles containing the underlying
// channel of the Node.
func (n *Node) Handles() []zx.Handle {
return []zx.Handle{
zx.Handle(((*fidl.Proxy)(n.NodeInterface)).Channel),
}
}
// Clone makes a clone of the node.
func (n *Node) Clone() (FDIO, error) {
req, newNode, err := io.NewNodeInterfaceRequest()
if err != nil {
return nil, err
}
if err := n.NodeInterface.Clone(io.OpenFlagDescribe, req); err != nil {
((*fidl.Proxy)(newNode)).Close()
return nil, err
}
status, info, err := newNode.ExpectOnOpen()
if err != nil {
((*fidl.Proxy)(newNode)).Close()
return nil, err
} else if status != zx.ErrOk {
((*fidl.Proxy)(newNode)).Close()
return nil, zx.Error{Status: status, Text: "io.node"}
}
return nodeFromInfo(info, newNode)
}
// Close closes the node.
func (n *Node) Close() error {
defer ((*fidl.Proxy)(n.NodeInterface)).Close()
if status, err := n.NodeInterface.Close(); err != nil {
return err
} else if status != zx.ErrOk {
return zx.Error{Status: status, Text: "io.node"}
}
return nil
}
// Sync performs a sync operation on a Node.
func (n *Node) Sync() error {
if status, err := n.NodeInterface.Sync(); err != nil {
return err
} else if status != zx.ErrOk {
return zx.Error{Status: status, Text: "io.node"}
}
return nil
}
// GetAttr returns the attributes for the Node.
func (n *Node) GetAttr() (io.NodeAttributes, error) {
status, attrs, err := n.NodeInterface.GetAttr()
if err != nil {
return io.NodeAttributes{}, err
} else if status != zx.ErrOk {
return io.NodeAttributes{}, zx.Error{Status: status, Text: "io.node"}
}
return attrs, nil
}
// SetAttr sets the attributes for Node as defined by flags.
func (n *Node) SetAttr(flags uint32, attr io.NodeAttributes) error {
if status, err := n.NodeInterface.SetAttr(flags, attr); err != nil {
return err
} else if status != zx.ErrOk {
return zx.Error{Status: status, Text: "io.node"}
}
return nil
}
// Ioctl calls an ioctl on Node.
func (n *Node) Ioctl(op uint32, max uint64, in []byte, handles []zx.Handle) ([]byte, []zx.Handle, error) {
status, h, b, err := n.NodeInterface.Ioctl(op, max, handles, in)
if err != nil {
return nil, nil, err
} else if status != zx.ErrOk {
return nil, nil, zx.Error{Status: status, Text: "io.node"}
}
return b, h, nil
}
// Read implements FDIO for Node.
func (n *Node) Read(data []byte) (int, error) {
return 0, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// ReadAt implements FDIO for Node.
func (n *Node) ReadAt(data []byte, off int64) (int, error) {
return 0, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Write implements FDIO for Node.
func (n *Node) Write(data []byte) (int, error) {
return 0, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// WriteAt implements FDIO for Node.
func (n *Node) WriteAt(data []byte, off int64) (int, error) {
return 0, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Seek implements FDIO for Node.
func (n *Node) Seek(offset int64, whence int) (int64, error) {
return 0, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Truncate implements FDIO for Node.
func (n *Node) Truncate(length uint64) error {
return zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Open implements FDIO for Node.
func (n *Node) Open(path string, flags uint32, mode uint32) (FDIO, error) {
return nil, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Link implements FDIO for Node.
func (n *Node) Link(oldpath, newpath string) error {
return zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Rename implements FDIO for Node.
func (n *Node) Rename(oldpath, newpath string) error {
return zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Unlink implements FDIO for Node.
func (n *Node) Unlink(path string) error {
return zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// ReadDirents implements FDIO for Node.
func (n *Node) ReadDirents(max uint64) ([]byte, error) {
return nil, zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}
// Rewind implements FDIO for Node.
func (n *Node) Rewind() error {
return zx.Error{Status: zx.ErrNotSupported, Text: "io.node"}
}