blob: 8cfd6b065e90b7a51f47d87301ce1c014c6420ce [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(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_READABLE) != 0; }
static bool IsWritable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_WRITABLE) != 0; }
static bool IsAdminable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_ADMIN) != 0; }
static bool IsDirectory(uint32_t flags) {
return (flags & fuchsia::io::OPEN_FLAG_DIRECTORY) != 0;
}
static bool IsNotDirectory(uint32_t flags) {
return (flags & fuchsia::io::OPEN_FLAG_NOT_DIRECTORY) != 0;
}
static bool ShouldDescribe(uint32_t flags) {
return (flags & fuchsia::io::OPEN_FLAG_DESCRIBE) != 0;
}
static bool IsNodeReference(uint32_t flags) {
return (flags & fuchsia::io::OPEN_FLAG_NODE_REFERENCE) != 0;
}
static bool ShouldCloneWithSameRights(uint32_t flags) {
return (flags & fuchsia::io::CLONE_FLAG_SAME_RIGHTS) != 0;
}
static bool IsPosix(uint32_t flags) { return (flags & fuchsia::io::OPEN_FLAG_POSIX) != 0; }
// All known rights.
static constexpr uint32_t kFsRights = fuchsia::io::OPEN_RIGHT_READABLE |
fuchsia::io::OPEN_RIGHT_WRITABLE |
fuchsia::io::OPEN_RIGHT_ADMIN;
// All lower 16 bits are reserved for future rights extensions.
static constexpr uint32_t kFsRightsSpace = 0x0000FFFF;
// Flags which can be modified by FIDL File::SetFlags.
static constexpr uint32_t kSettableStatusFlags = fuchsia::io::OPEN_FLAG_APPEND;
// All flags which indicate state of the connection (excluding rights).
static constexpr uint32_t kStatusFlags =
kSettableStatusFlags | fuchsia::io::OPEN_FLAG_NODE_REFERENCE;
// Returns true if the rights flags in |flags_a| does not exceed
// those in |flags_b|.
static bool StricterOrSameRights(uint32_t flags_a, uint32_t flags_b) {
uint32_t rights_a = flags_a & kFsRights;
uint32_t rights_b = flags_b & kFsRights;
return (rights_a & ~rights_b) == 0;
}
// Perform basic flags validation relevant to Directory::Open and Node::Clone.
// Returns false if the flags combination is invalid.
static bool InputPrecondition(uint32_t flags) {
// If the caller specified an unknown right, reject the request.
if ((flags & Flags::kFsRightsSpace) & ~Flags::kFsRights) {
return false;
}
// Explicitly reject NODE_REFERENCE together with any invalid flags.
if (Flags::IsNodeReference(flags)) {
constexpr uint32_t kValidFlagsForNodeRef =
fuchsia::io::OPEN_FLAG_NODE_REFERENCE | fuchsia::io::OPEN_FLAG_DIRECTORY |
fuchsia::io::OPEN_FLAG_NOT_DIRECTORY | fuchsia::io::OPEN_FLAG_DESCRIBE;
if (flags & ~kValidFlagsForNodeRef) {
return false;
}
}
return true;
}
};
} // namespace vfs
#endif // LIB_VFS_CPP_FLAGS_H_