blob: 29d45beb9587e580ab758794d51cda73d0e824e2 [file] [log] [blame]
// Copyright 2019 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.
#ifndef LIB_VFS_CPP_FLAGS_H_
#define LIB_VFS_CPP_FLAGS_H_
#include <fuchsia/io/cpp/fidl.h>
namespace vfs {
class Flags {
public:
Flags() = delete;
static bool IsReadable(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::RIGHT_READABLE) != fuchsia::io::OpenFlags();
}
static bool IsWritable(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::RIGHT_WRITABLE) != fuchsia::io::OpenFlags();
}
static bool IsExecutable(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::RIGHT_EXECUTABLE) != fuchsia::io::OpenFlags();
}
static bool IsDirectory(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::DIRECTORY) != fuchsia::io::OpenFlags();
}
static bool IsNotDirectory(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::NOT_DIRECTORY) != fuchsia::io::OpenFlags();
}
static bool ShouldDescribe(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::DESCRIBE) != fuchsia::io::OpenFlags();
}
static bool IsNodeReference(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::NODE_REFERENCE) != fuchsia::io::OpenFlags();
}
static bool ShouldCloneWithSameRights(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::CLONE_SAME_RIGHTS) != fuchsia::io::OpenFlags();
}
static bool IsPosixWritable(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::POSIX_WRITABLE) != fuchsia::io::OpenFlags();
}
static bool IsPosixExecutable(fuchsia::io::OpenFlags flags) {
return (flags & fuchsia::io::OpenFlags::POSIX_EXECUTABLE) != fuchsia::io::OpenFlags();
}
// All known rights.
static constexpr fuchsia::io::OpenFlags kFsRights = fuchsia::io::OPEN_RIGHTS;
// Flags which can be modified by FIDL File::SetFlags.
static constexpr fuchsia::io::OpenFlags kSettableStatusFlags = fuchsia::io::OpenFlags::APPEND;
// All flags which indicate state of the connection (excluding rights).
static constexpr fuchsia::io::OpenFlags kStatusFlags =
kSettableStatusFlags | fuchsia::io::OpenFlags::NODE_REFERENCE;
// Returns true if the rights flags in |flags_a| does not exceed
// those in |flags_b|.
static bool StricterOrSameRights(fuchsia::io::OpenFlags flags_a, fuchsia::io::OpenFlags flags_b) {
fuchsia::io::OpenFlags rights_a = flags_a & kFsRights;
fuchsia::io::OpenFlags rights_b = flags_b & kFsRights;
return (rights_a & ~rights_b) == fuchsia::io::OpenFlags();
}
// Perform basic flags validation relevant to Directory::Open and Node::Clone.
// Returns false if the flags combination is invalid.
static bool InputPrecondition(fuchsia::io::OpenFlags flags) {
// Reject if OPEN_FLAG_DIRECTORY and OPEN_FLAG_NOT_DIRECTORY are both specified.
if (Flags::IsDirectory(flags) && Flags::IsNotDirectory(flags)) {
return false;
}
// Explicitly reject NODE_REFERENCE together with any invalid flags.
if (Flags::IsNodeReference(flags)) {
if ((flags & ~fuchsia::io::OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE) !=
fuchsia::io::OpenFlags()) {
return false;
}
}
return true;
}
};
} // namespace vfs
#endif // LIB_VFS_CPP_FLAGS_H_