The Pedigree Project 0.1
FileDescriptor.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef POSIX_FILEDESCRIPTOR_H
21#define POSIX_FILEDESCRIPTOR_H
22
23#include "pedigree/kernel/LockGuard.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/process/FilesystemContext.h"
26#include "pedigree/kernel/process/Mutex.h"
27#include "pedigree/kernel/process/OperationBarrier.h"
28#include "pedigree/kernel/process/Process.h"
29#include "pedigree/kernel/process/Readiness.h"
30#include "pedigree/kernel/process/TerminationDeferral.h"
31#include "pedigree/kernel/processor/types.h"
32#include "pedigree/kernel/utilities/SharedPointer.h"
33#include "pedigree/kernel/utilities/String.h"
34
35#include "advisory-lock-state.h"
36
37class ConsoleIoState;
38class File;
39class UnixSocket;
40class IoEvent;
41class NetworkSyscalls;
42class EpollInstance;
43class EventFd;
44class TimerFd;
45class SignalFd;
46class InotifyInstance;
49
53class EXPORTED_PUBLIC FileDescriptor {
54 public:
55 class PositionGuard;
57
63 public:
67
68 AdvisoryOwner& advisoryOwner() {
69 return m_AdvisoryOwner;
70 }
71
72 uint64_t identity() const {
73 return m_AdvisoryOwner.identity();
74 }
75
76 File* getFile() const {
77 return path ? path->node() : anonymousFile;
78 }
79 FilesystemPathRef openingPath() const;
80 ReadyMask queryFileReady(bool reading, bool writing) const;
81 ReadinessGenerations fileReadinessGenerations() const;
82 SharedPointer<ConsoleIoState> terminalEpoch(bool waitForReopen = true) const;
83 // Endpoint owners are set before descriptor publication and never replaced.
84 // Retaining the description therefore protects lock-free owner snapshots.
85 SharedPointer<NetworkSyscalls> getNetworkImpl() const;
86 SharedPointer<EventFd> getEventFdImpl() const;
87 SharedPointer<TimerFd> getTimerFdImpl() const;
88 SharedPointer<SignalFd> getSignalFdImpl() const;
89 SharedPointer<InotifyInstance> getInotifyImpl() const;
90 SharedPointer<FanotifyInstance> getFanotifyImpl() const;
91 SharedPointer<PosixMessageQueue> getMqueueImpl() const;
92 size_t descriptorOwnerCount() const;
93
94 private:
95 friend class FileDescriptor;
96 friend class PositionGuard;
97 friend class TransferPositionGuard;
98
99 OpenFileDescription(File* file, uint64_t initialOffset, int initialStatusFlags);
100 OpenFileDescription(const FilesystemPathRef& path, uint64_t initialOffset,
101 int initialStatusFlags);
102
103 void addDescriptorOwner();
104 void removeDescriptorOwner();
105 void ensureVfsLease();
106
107 AdvisoryOwner m_AdvisoryOwner;
108 mutable Mutex lock;
109 // Exactly one arm is set. Path-based descriptions derive their File from path.
111 File* anonymousFile;
113 SharedPointer<EventFd> eventFdImpl;
114 SharedPointer<TimerFd> timerFdImpl;
115 SharedPointer<SignalFd> signalFdImpl;
120 uint64_t offset;
121 const int accessFlags;
122 int statusFlags;
123 size_t descriptorOwners;
124 bool vfsLease;
125 bool allowTruncate = true;
126 };
127
129
132 public:
133 uint64_t offset() const {
134 return m_Description->offset;
135 }
136
137 int statusFlags() const {
138 return m_Description->statusFlags;
139 }
140
141 File* file() const {
142 return m_Description->getFile();
143 }
144
145 bool isNoopSeekEndpoint() const {
146 return m_Description->timerFdImpl || m_Description->signalFdImpl ||
147 m_Description->fanotifyImpl;
148 }
149
150 void setOffset(uint64_t offset) {
151 m_Description->offset = offset;
152 }
153
154 void advanceOffset(uint64_t amount) {
155 m_Description->offset += amount;
156 }
157
158 private:
159 friend class FileDescriptor;
160
161 explicit PositionGuard(const SharedPointer<OpenFileDescription>& description);
162
164 LockGuard<Mutex> m_Guard;
165 };
166
168 public:
169 enum class Endpoint { Input, Output };
171 const OpenFileDescriptionLease& output, bool lockInput, bool lockOutput);
174 TransferPositionGuard& operator=(const TransferPositionGuard&) = delete;
175
176 int statusFlags(Endpoint endpoint) const;
177 uint64_t offset(Endpoint endpoint) const;
178 void commitOffset(Endpoint endpoint, uint64_t finalOffset);
179 bool sameDescription() const;
180
181 private:
182 OpenFileDescription& lockedDescription(Endpoint endpoint) const;
183
184#if THREADS && !defined(STANDALONE_MUTEXES)
185 TerminationDeferral m_TerminationDeferral;
186#endif
189 OpenFileDescription* m_First;
190 OpenFileDescription* m_Second;
191 int m_InputFlags;
192 int m_OutputFlags;
193 };
194
197
199 FileDescriptor(File* newFile, uint64_t newOffset = 0, size_t newFd = 0xFFFFFFFF, int fdFlags = 0,
200 int flFlags = 0);
201
202 FileDescriptor(const FilesystemPathRef& path, uint64_t newOffset = 0, size_t newFd = 0xFFFFFFFF,
203 int fdFlags = 0, int flFlags = 0);
204
207
210
213
215 virtual ~FileDescriptor();
216
218 void setFlags(int newFlags);
219
221 void addFlag(int newFlag);
222
224 int getFlags() const;
225
227 void setStatusFlags(int newFlags);
228
230 void addStatusFlag(int newFlag);
231
233 void removeStatusFlag(int flag);
234
236 int getStatusFlags() const;
237 bool truncateAllowed() const {
238 return m_OpenFile && m_OpenFile->allowTruncate;
239 }
240 // Set before publication; duplicated and transferred descriptors share this grant.
241 void setTruncateAllowed(bool allowed) {
242 if (m_OpenFile) {
243 m_OpenFile->allowTruncate = allowed;
244 }
245 }
246
247 // F_SETFL cannot change access permissions; permission checks need no OFD lock.
248 int getAccessFlags() const {
249 return m_OpenFile->accessFlags;
250 }
251
253 OpenFileDescriptionLease acquireOpenFileDescription() const;
254
256 void setNetworkImpl(const SharedPointer<NetworkSyscalls>& implementation);
257
259 bool networkPublished() const;
260
262 void setEventFdImpl(const SharedPointer<EventFd>& implementation);
263
265 SharedPointer<EventFd> getEventFdImpl() const;
266
268 bool eventFdPublished() const;
269
270 void setTimerFdImpl(const SharedPointer<TimerFd>& implementation);
271 SharedPointer<TimerFd> getTimerFdImpl() const;
272 bool timerFdPublished() const;
273
274 void setSignalFdImpl(const SharedPointer<SignalFd>& implementation);
275 SharedPointer<SignalFd> getSignalFdImpl() const;
276 bool signalFdPublished() const;
277
279 void setInotifyImpl(const SharedPointer<InotifyInstance>& implementation);
280
282 SharedPointer<InotifyInstance> getInotifyImpl() const;
283 void setFanotifyImpl(const SharedPointer<FanotifyInstance>& implementation);
284 SharedPointer<FanotifyInstance> getFanotifyImpl() const;
285
286 void setMqueueImpl(const SharedPointer<PosixMessageQueue>& implementation);
287 SharedPointer<PosixMessageQueue> getMqueueImpl() const;
288
290 void unpublish();
291
293 PositionGuard lockPosition() const;
294
296 uint64_t getOffset() const;
297
299 void setOffset(uint64_t offset);
300
302 uint64_t read(uint64_t size, uintptr_t buffer, bool canBlock = true);
303
305 uint64_t write(uint64_t size, uintptr_t buffer, bool canBlock = true);
306
308 public:
311
312 private:
313 friend class FileDescriptor;
314 TerminationDeferral lifetime;
316 OperationBarrier::Lease operation;
317 };
318
319 bool acquireTerminalOperation(TerminalOperation& operation) const;
320 bool terminalHungUp() const;
321 bool terminalAvailable() const;
322 SharedPointer<ConsoleIoState> terminalEpoch(bool waitForReopen = true) const;
323 uint64_t readFile(uint64_t location, uint64_t size, uintptr_t buffer, bool canBlock);
324 uint64_t writeFile(uint64_t location, uint64_t size, uintptr_t buffer, bool canBlock);
325
326 File* getFile() const {
327 return m_OpenFile ? m_OpenFile->getFile() : nullptr;
328 }
329 FilesystemPathRef openingPath() const;
330
332 size_t fd;
333
336
339
342
343 public:
346
347 private:
348 friend class PosixSubsystem;
349
352
357 bool m_TimerFdPublished = false;
358 bool m_SignalFdPublished = false;
359};
360
361#endif
SharedPointer< EpollInstance > epollImpl
Epoll implementation for this descriptor (if it is an epoll object).
int fdflags
File descriptor flags (fcntl)
OpenFileDescriptionLease m_OpenFile
FileDescriptor & operator=(FileDescriptor &desc)=delete
Descriptors own registrations and references which cannot be replaced.
IoEvent * ioevent
IO event for reporting changes to files.
SharedPointer< NetworkSyscalls > networkImpl
Network syscall implementation for this descriptor (if it's a socket).
size_t fd
Descriptor number.
Definition File.h:75
Definition Mutex.h:56