Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- * * Copyright (c) 2021 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef FileManager_h #define FileManager_h #if !TARGET_OS_EXCLAVEKIT #include "UUID.h" #include "Defines.h" #include "Allocator.h" #include "OrderedMap.h" #include "DyldDelegates.h" #if !BUILDING_DYLD #include <os/lock.h> #endif namespace dyld4 { using lsl::UUID; using lsl::UniquePtr; using lsl::Allocator; using lsl::OrderedMap; struct FileManager; struct VIS_HIDDEN FileRecord { FileRecord() = default; FileRecord(const FileRecord&other); FileRecord(FileRecord&& other); ~FileRecord(); FileRecord& operator=(const FileRecord& other); FileRecord& operator=(FileRecord&& other); uint64_t objectID() const; uint64_t mtime() const; size_t size() const; const UUID& volume() const; int open(int flags); void close(); bool exists() const; const char* getPath() const; bool persistent() const; FileManager& fileManager() const; friend void swap(FileRecord& x, FileRecord& y) { x.swap(y); } private: friend FileManager; FileRecord(FileManager& fileManager, uint64_t objectID, uint64_t device, uint64_t mtime); FileRecord(FileManager& fileManager, const UUID& VID, uint64_t objectID); FileRecord(FileManager& fileManager, const struct stat& sb); FileRecord(FileManager& fileManager, UniquePtr<const char>&& filePath); void swap(FileRecord& other); void stat() const; FileManager* _fileManager = nullptr; mutable uint64_t _objectID = 0; mutable uint64_t _device = 0; mutable UUID _volume; mutable lsl::UniquePtr<const char> _path; mutable size_t _size = 0; mutable uint64_t _mtime = 0; int _fd = -1; mutable int _statResult = 1; // Tri-state: 1 not stated, 0 successful stat, -1 failed stat mutable mode_t _mode = 0; mutable bool _valid = true; }; struct VIS_HIDDEN FileManager { FileManager() = delete; FileManager(const FileManager&) = delete; FileManager(FileManager&&) = delete; FileManager& operator=(const FileManager& O) = delete; FileManager& operator=(FileManager&& O) = delete; FileManager(Allocator& allocator, const SyscallDelegate* syscall); FileRecord fileRecordForPath(Allocator& allocator, const char* filePath); FileRecord fileRecordForStat(const struct stat& sb); FileRecord fileRecordForVolumeUUIDAndObjID(const UUID& VID, uint64_t objectID); FileRecord fileRecordForVolumeDevIDAndObjID(uint64_t device, uint64_t objectID); FileRecord fileRecordForFileID(const FileID& fileID); const UUID uuidForFileSystem(uint64_t fsid) const; uint64_t fsidForUUID(const UUID& uuid) const; friend void swap(FileManager& x, FileManager& y) { x.swap(y); } private: friend FileRecord; void swap(FileManager& other); ssize_t fsgetpath(char result[], size_t resultBufferSize, uint64_t fsID, uint64_t objID) const; int getfsstat(struct statfs *buf, int bufsize, int flags) const; int getattrlist(const char* path, struct attrlist * attrList, void * attrBuf, size_t attrBufSize, uint32_t options) const; void reloadFSInfos() const; UniquePtr<char> getPath(const lsl::UUID& VID, uint64_t OID); UniquePtr<char> getPath(uint64_t fsid, uint64_t OID); const SyscallDelegate* _syscall = nullptr; Allocator* _allocator = nullptr; mutable UniquePtr<OrderedMap<uint64_t,UUID>> _fsUUIDMap = nullptr; //FIXME: We should probably have a more generic lock abstraction for locks we only need when not building dyld template<typename F> auto withFSInfoLock(F work) const { #if BUILDING_DYLD return work(); #else os_unfair_lock_lock(&_fsUUIDMapLock); auto result = work(); os_unfair_lock_unlock(&_fsUUIDMapLock); return result; #endif } #if !BUILDING_DYLD mutable os_unfair_lock_s _fsUUIDMapLock = OS_UNFAIR_LOCK_INIT; #endif }; }; /* namespace dyld4 */ #endif //!TARGET_OS_EXCLAVEKIT #endif /* FileManager_h */ |