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/Readiness.h"
29#include "pedigree/kernel/process/TerminationDeferral.h"
30#include "pedigree/kernel/processor/types.h"
31#include "pedigree/kernel/utilities/SharedPointer.h"
32#include "pedigree/kernel/utilities/String.h"
33
34#include "advisory-lock-state.h"
35
36class ConsoleIoState;
37class File;
38class UnixSocket;
39class IoEvent;
40class NetworkSyscalls;
41class EpollInstance;
42class EventFd;
43class TimerFd;
44class SignalFd;
45class InotifyInstance;
48
52class EXPORTED_PUBLIC FileDescriptor {
53 public:
54 class PositionGuard;
56
62 public:
64
65 AdvisoryOwner& advisoryOwner() {
66 return m_AdvisoryOwner;
67 }
68
69 uint64_t identity() const {
70 return m_AdvisoryOwner.identity();
71 }
72
73 File* getFile() const {
74 return path ? path->node() : anonymousFile;
75 }
76 FilesystemPathRef openingPath() const;
77 ReadyMask queryFileReady(bool reading, bool writing) const;
78 ReadinessGenerations fileReadinessGenerations() const;
79 SharedPointer<ConsoleIoState> terminalEpoch(bool waitForReopen = true) const;
80 SharedPointer<NetworkSyscalls> getNetworkImpl() const;
81 SharedPointer<EventFd> getEventFdImpl() const;
82 SharedPointer<TimerFd> getTimerFdImpl() const;
83 SharedPointer<SignalFd> getSignalFdImpl() const;
84 SharedPointer<InotifyInstance> getInotifyImpl() const;
85 SharedPointer<FanotifyInstance> getFanotifyImpl() const;
86 SharedPointer<PosixMessageQueue> getMqueueImpl() const;
87 size_t descriptorOwnerCount() const;
88
89 private:
90 friend class FileDescriptor;
91 friend class PositionGuard;
92 friend class TransferPositionGuard;
93
94 OpenFileDescription(File* file, uint64_t initialOffset, int initialStatusFlags);
95 OpenFileDescription(const FilesystemPathRef& path, uint64_t initialOffset,
96 int initialStatusFlags);
97
98 void addDescriptorOwner();
99 void removeDescriptorOwner();
100 void ensureVfsLease();
101
102 AdvisoryOwner m_AdvisoryOwner;
103 mutable Mutex lock;
104 // Exactly one arm is set. Path-based descriptions derive their File from path.
106 File* anonymousFile;
108 SharedPointer<EventFd> eventFdImpl;
109 SharedPointer<TimerFd> timerFdImpl;
110 SharedPointer<SignalFd> signalFdImpl;
115 uint64_t offset;
116 const int accessFlags;
117 int statusFlags;
118 size_t descriptorOwners;
119 bool vfsLease;
120 };
121
123
126 public:
127 uint64_t offset() const {
128 return m_Description->offset;
129 }
130
131 int statusFlags() const {
132 return m_Description->statusFlags;
133 }
134
135 File* file() const {
136 return m_Description->getFile();
137 }
138
139 bool isNoopSeekEndpoint() const {
140 return m_Description->timerFdImpl || m_Description->signalFdImpl ||
141 m_Description->fanotifyImpl;
142 }
143
144 void setOffset(uint64_t offset) {
145 m_Description->offset = offset;
146 }
147
148 void advanceOffset(uint64_t amount) {
149 m_Description->offset += amount;
150 }
151
152 private:
153 friend class FileDescriptor;
154
155 explicit PositionGuard(const SharedPointer<OpenFileDescription>& description);
156
158 LockGuard<Mutex> m_Guard;
159 };
160
162 public:
163 enum class Endpoint { Input, Output };
165 const OpenFileDescriptionLease& output, bool lockInput, bool lockOutput);
168 TransferPositionGuard& operator=(const TransferPositionGuard&) = delete;
169
170 int statusFlags(Endpoint endpoint) const;
171 uint64_t offset(Endpoint endpoint) const;
172 void commitOffset(Endpoint endpoint, uint64_t finalOffset);
173 bool sameDescription() const;
174
175 private:
176 OpenFileDescription& lockedDescription(Endpoint endpoint) const;
177
178#if THREADS && !defined(STANDALONE_MUTEXES)
179 TerminationDeferral m_TerminationDeferral;
180#endif
183 OpenFileDescription* m_First;
184 OpenFileDescription* m_Second;
185 int m_InputFlags;
186 int m_OutputFlags;
187 };
188
191
193 FileDescriptor(File* newFile, uint64_t newOffset = 0, size_t newFd = 0xFFFFFFFF, int fdFlags = 0,
194 int flFlags = 0);
195
196 FileDescriptor(const FilesystemPathRef& path, uint64_t newOffset = 0, size_t newFd = 0xFFFFFFFF,
197 int fdFlags = 0, int flFlags = 0);
198
201
204
207
209 virtual ~FileDescriptor();
210
212 void setFlags(int newFlags);
213
215 void addFlag(int newFlag);
216
218 int getFlags() const;
219
221 void setStatusFlags(int newFlags);
222
224 void addStatusFlag(int newFlag);
225
227 void removeStatusFlag(int flag);
228
230 int getStatusFlags() const;
231
232 // F_SETFL cannot change access permissions; permission checks need no OFD lock.
233 int getAccessFlags() const {
234 return m_OpenFile->accessFlags;
235 }
236
238 OpenFileDescriptionLease acquireOpenFileDescription() const;
239
241 void setNetworkImpl(const SharedPointer<NetworkSyscalls>& implementation);
242
244 bool networkPublished() const;
245
247 void setEventFdImpl(const SharedPointer<EventFd>& implementation);
248
250 SharedPointer<EventFd> getEventFdImpl() const;
251
253 bool eventFdPublished() const;
254
255 void setTimerFdImpl(const SharedPointer<TimerFd>& implementation);
256 SharedPointer<TimerFd> getTimerFdImpl() const;
257 bool timerFdPublished() const;
258
259 void setSignalFdImpl(const SharedPointer<SignalFd>& implementation);
260 SharedPointer<SignalFd> getSignalFdImpl() const;
261 bool signalFdPublished() const;
262
264 void setInotifyImpl(const SharedPointer<InotifyInstance>& implementation);
265
267 SharedPointer<InotifyInstance> getInotifyImpl() const;
268 void setFanotifyImpl(const SharedPointer<FanotifyInstance>& implementation);
269 SharedPointer<FanotifyInstance> getFanotifyImpl() const;
270
271 void setMqueueImpl(const SharedPointer<PosixMessageQueue>& implementation);
272 SharedPointer<PosixMessageQueue> getMqueueImpl() const;
273
275 void unpublish();
276
278 PositionGuard lockPosition() const;
279
281 uint64_t getOffset() const;
282
284 void setOffset(uint64_t offset);
285
287 uint64_t read(uint64_t size, uintptr_t buffer, bool canBlock = true);
288
290 uint64_t write(uint64_t size, uintptr_t buffer, bool canBlock = true);
291
293 public:
296
297 private:
298 friend class FileDescriptor;
299 TerminationDeferral lifetime;
301 OperationBarrier::Lease operation;
302 };
303
304 bool acquireTerminalOperation(TerminalOperation& operation) const;
305 bool terminalHungUp() const;
306 bool terminalAvailable() const;
307 SharedPointer<ConsoleIoState> terminalEpoch(bool waitForReopen = true) const;
308 uint64_t readFile(uint64_t location, uint64_t size, uintptr_t buffer, bool canBlock);
309 uint64_t writeFile(uint64_t location, uint64_t size, uintptr_t buffer, bool canBlock);
310
311 File* getFile() const {
312 return m_OpenFile ? m_OpenFile->getFile() : nullptr;
313 }
314 FilesystemPathRef openingPath() const;
315
317 size_t fd;
318
321
324
327
328 public:
331
332 private:
333 friend class PosixSubsystem;
334
337
342 bool m_TimerFdPublished = false;
343 bool m_SignalFdPublished = false;
344};
345
346#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:74
Definition Mutex.h:56