blob: ed879f91de6fa032f41c75dd1df72f3d7cf8a1c2 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_io/fidl_async.dart';
import 'package:zircon/zircon.dart';
import 'internal/_error_node.dart';
/// This interface declares a abstract Vnode class with
/// common operations that may be overwritten.
///
/// These nodes can be added to [PseudoDir] and can be accessed from filesystem.
abstract class Vnode {
final List<ErrorNodeForSendingEvent> _errorNodes = [];
/// Close this node and all of its bindings and children.
void close();
/// Connect to this vnode.
/// All flags and modes are defined in
/// https://fuchsia.googlesource.com/zircon/+/master/system/fidl/fuchsia-io/io.fidl
///
/// By default param [#parentFlags] is -1 so that open can validate all flags.
/// This param is used by clone to restrict cloning.
int connect(int flags, int mode, InterfaceRequest<Node> request,
[int parentFlags = -1]);
/// Filter flags when [openFlagNodeReference] is passed.
/// This will maintain compatibility with c++ layer.
int filterForNodeReference(int flags) {
if (flags & openFlagNodeReference != 0) {
return flags &
(openFlagNodeReference | openFlagDirectory | openFlagDescribe);
}
return flags;
}
/// Inode number as defined in io.fidl.
int inodeNumber();
/// This function is called from [fuchsia.io.Directory#open].
/// This function parses path and opens correct node.
///
/// Vnode provides a simplified implementation for non-directory types.
/// Behavior:
/// Bypasses to connect call for empty path and non-directory types.
/// For directory types, it will throw UnimplementedError error.
/// For non empty path it will fail with [ERR_NOT_DIR].
void open(int flags, int mode, String path, InterfaceRequest<Node> request) {
if (type() == direntTypeDirectory) {
// dir types should implement this function
throw UnimplementedError();
}
if (path == '') {
connect(flags, mode, request);
return;
}
sendErrorEvent(flags, ZX.ERR_NOT_DIR, request);
}
/// Create a error node to send onOpen event with failure status.
void sendErrorEvent(int flags, int status, InterfaceRequest<Node> request) {
if ((flags & openFlagDescribe) != 0) {
var e = ErrorNodeForSendingEvent(status, _removeErrorNode, request);
_errorNodes.add(e);
} else {
request.close();
}
}
/// Should be one of
///
/// direntTypeUnknown
/// direntTypeDirectory
/// direntTypeBlockDevice
/// direntTypeFile
/// direntTypeSocket
/// direntTypeService
///
/// These are defined in io.fidl.
int type();
void _removeErrorNode(ErrorNodeForSendingEvent e) {
_errorNodes.remove(e);
}
}