The Pedigree Project 0.1
FileDescriptor.cc
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#include "FileDescriptor.h"
21
22#include <fcntl.h>
23
24#include "modules/subsys/posix/IoEvent.h"
25#include "modules/subsys/posix/epoll-syscalls.h"
26#include "modules/subsys/posix/eventfd-syscalls.h"
27#include "modules/subsys/posix/fanotify-syscalls.h"
28#include "modules/subsys/posix/inotify-syscalls.h"
29#include "modules/subsys/posix/mqueue-syscalls.h"
30#include "modules/subsys/posix/signalfd-syscalls.h"
31#include "modules/subsys/posix/timerfd-syscalls.h"
32#include "modules/system/console/Console.h"
33#include "modules/system/vfs/File.h"
34#include "net-syscalls.h" // to get destructor for SharedPointer<NetworkSyscalls>
35
36namespace {
37constexpr int MutableStatusFlags = O_APPEND | O_NONBLOCK;
38
39bool isReadWrite(int flags) {
40 return (flags & O_ACCMODE) == O_RDWR;
41}
42
43void increaseFileReferences(File* file, int flags) {
44 if (!file || (flags & O_PATH)) {
45 return;
46 }
47
48 const bool writer = (flags & O_ACCMODE) != O_RDONLY;
49 file->increaseRefCount(writer);
50
51 // The historical boolean API cannot express that O_RDWR is both ends of a
52 // FIFO. Account its reader side separately so it satisfies waiting writers.
53 if (isReadWrite(flags) && (file->isPipe() || file->isFifo())) {
54 file->increaseRefCount(false);
55 }
56}
57
58void decreaseFileReferences(File* file, int flags) {
59 if (!file || (flags & O_PATH)) {
60 return;
61 }
62
63 const bool writer = (flags & O_ACCMODE) != O_RDONLY;
64 file->decreaseRefCount(writer);
65 if (isReadWrite(flags) && (file->isPipe() || file->isFifo())) {
66 file->decreaseRefCount(false);
67 }
68}
69
70void retireIoEvent(File* file, SharedPointer<NetworkSyscalls>& networkImpl, IoEvent*& ioevent) {
71 if (!ioevent) {
72 return;
73 }
74
75 IoEvent* retiring = ioevent;
76 ioevent = nullptr;
77 Event::Retirement retirement;
78 retiring->beginRetirement(retirement);
79
80 // Close admission before removing raw registry pointers. A callback which
81 // is already active can no longer re-arm itself after this pass.
82 if (file) {
83 file->cullMonitorTargets(retiring);
84 }
85 if (networkImpl) {
86 networkImpl->unmonitor(retiring);
87 }
88}
89} // namespace
90
91FileDescriptor::OpenFileDescription::OpenFileDescription(File* newFile, uint64_t initialOffset,
92 int initialStatusFlags)
93 : m_AdvisoryOwner(AdvisoryOwner::Kind::OpenDescription),
94 lock(),
95 path(),
96 anonymousFile(newFile),
97 networkImpl(nullptr),
98 eventFdImpl(nullptr),
99 inotifyImpl(nullptr),
100 mqueueImpl(nullptr),
101 consoleEpoch(newFile && !(initialStatusFlags & O_PATH) &&
102 ConsoleManager::instance().isConsole(newFile)
103 ? static_cast<ConsoleFile*>(newFile)->captureOpenEpoch()
105 offset(initialOffset),
106 accessFlags(initialStatusFlags & (O_PATH | O_ACCMODE)),
107 statusFlags(initialStatusFlags),
108 descriptorOwners(1),
109 vfsLease(newFile && newFile->retainVfsReference()) {
110 assert(!newFile || !newFile->isDirectory());
111 increaseFileReferences(getFile(), statusFlags);
112}
113
114FileDescriptor::OpenFileDescription::OpenFileDescription(const FilesystemPathRef& opening,
115 uint64_t initialOffset,
116 int initialStatusFlags)
117 : OpenFileDescription(static_cast<File*>(nullptr), initialOffset, initialStatusFlags) {
118 assert(static_cast<bool>(opening));
119 path = opening;
120 File* node = getFile();
121 if (!(initialStatusFlags & O_PATH) && ConsoleManager::instance().isConsole(node))
122 consoleEpoch = static_cast<ConsoleFile*>(node)->captureOpenEpoch();
123 increaseFileReferences(node, initialStatusFlags);
124}
125
126FilesystemPathRef FileDescriptor::OpenFileDescription::openingPath() const {
127 return path;
128}
129FilesystemPathRef FileDescriptor::openingPath() const {
130 return m_OpenFile ? m_OpenFile->openingPath() : FilesystemPathRef();
131}
132
133FileDescriptor::OpenFileDescription::~OpenFileDescription() {
134 assert(!descriptorOwners);
135 posix_advisory_owner_closed(m_AdvisoryOwner);
136 if (vfsLease) {
137 getFile()->releaseVfsReference();
138 }
139}
140
141SharedPointer<ConsoleIoState> FileDescriptor::OpenFileDescription::terminalEpoch(
142 bool waitForReopen) const {
143 if (getFile() && ConsoleManager::instance().isMasterConsole(getFile()))
144 return static_cast<ConsoleFile*>(getFile())->captureOpenEpoch(waitForReopen);
145 return consoleEpoch;
146}
147
148ReadyMask FileDescriptor::OpenFileDescription::queryFileReady(bool reading, bool writing) const {
149 if (getFile() && ConsoleManager::instance().isConsole(getFile()))
150 return static_cast<ConsoleFile*>(getFile())->queryEpoch(terminalEpoch(false), reading, writing);
151 return getFile() ? getFile()->queryReady(reading, writing) : ReadyInvalid;
152}
153
154ReadinessGenerations FileDescriptor::OpenFileDescription::fileReadinessGenerations() const {
155 if (getFile() && ConsoleManager::instance().isConsole(getFile()))
156 return static_cast<ConsoleFile*>(getFile())->epochGenerations(terminalEpoch(false));
157 return getFile() ? getFile()->readinessGenerations() : ReadinessGenerations();
158}
159
160FileDescriptor::TerminalOperation::TerminalOperation() = default;
161FileDescriptor::TerminalOperation::~TerminalOperation() = default;
162
163SharedPointer<ConsoleIoState> FileDescriptor::terminalEpoch(bool waitForReopen) const {
164 return m_OpenFile->terminalEpoch(waitForReopen);
165}
166
167bool FileDescriptor::terminalHungUp() const {
168 if (!getFile() || !ConsoleManager::instance().isConsole(getFile()))
169 return false;
170 auto epoch = terminalEpoch();
171 return !epoch || epoch->revoked();
172}
173
174bool FileDescriptor::terminalAvailable() const {
175 return !getFile() || (getStatusFlags() & O_PATH) ||
176 !ConsoleManager::instance().isConsole(getFile()) || static_cast<bool>(terminalEpoch());
177}
178
179bool FileDescriptor::acquireTerminalOperation(TerminalOperation& operation) const {
180 if (!getFile() || !ConsoleManager::instance().isConsole(getFile()))
181 return true;
182 operation.state = terminalEpoch();
183 return operation.state && operation.state->operations.tryAcquire(operation.operation) &&
184 !operation.state->revoked();
185}
186
187uint64_t FileDescriptor::readFile(uint64_t location, uint64_t size, uintptr_t buffer,
188 bool canBlock) {
189 if (getFile() && ConsoleManager::instance().isConsole(getFile()))
190 return static_cast<ConsoleFile*>(getFile())->readEpoch(terminalEpoch(), size, buffer, canBlock);
191 return getFile() ? getFile()->read(location, size, buffer, canBlock) : 0;
192}
193
194uint64_t FileDescriptor::writeFile(uint64_t location, uint64_t size, uintptr_t buffer,
195 bool canBlock) {
196 if (getFile() && ConsoleManager::instance().isConsole(getFile()))
197 return static_cast<ConsoleFile*>(getFile())->writeEpoch(terminalEpoch(), size, buffer,
198 canBlock);
199 return getFile() ? getFile()->write(location, size, buffer, canBlock) : 0;
200}
201
202SharedPointer<NetworkSyscalls> FileDescriptor::OpenFileDescription::getNetworkImpl() const {
203 return networkImpl;
204}
205
206SharedPointer<EventFd> FileDescriptor::OpenFileDescription::getEventFdImpl() const {
207 return eventFdImpl;
208}
209
210SharedPointer<TimerFd> FileDescriptor::OpenFileDescription::getTimerFdImpl() const {
211 return timerFdImpl;
212}
213
214SharedPointer<SignalFd> FileDescriptor::OpenFileDescription::getSignalFdImpl() const {
215 return signalFdImpl;
216}
217
218SharedPointer<InotifyInstance> FileDescriptor::OpenFileDescription::getInotifyImpl() const {
219 return inotifyImpl;
220}
221
222SharedPointer<FanotifyInstance> FileDescriptor::OpenFileDescription::getFanotifyImpl() const {
223 return fanotifyImpl;
224}
225
226size_t FileDescriptor::OpenFileDescription::descriptorOwnerCount() const {
227 LockGuard<Mutex> guard(lock);
228 return descriptorOwners;
229}
230
231void FileDescriptor::OpenFileDescription::addDescriptorOwner() {
232 LockGuard<Mutex> guard(lock);
233 assert(descriptorOwners);
234 ++descriptorOwners;
235}
236
237void FileDescriptor::OpenFileDescription::removeDescriptorOwner() {
238 bool closeEndpoint = false;
239 int flags = 0;
240 SharedPointer<NetworkSyscalls> closingNetwork;
241 SharedPointer<InotifyInstance> closingInotify;
242 SharedPointer<FanotifyInstance> closingFanotify;
243 {
244 LockGuard<Mutex> guard(lock);
245 assert(descriptorOwners);
246 --descriptorOwners;
247 closeEndpoint = descriptorOwners == 0;
248 flags = statusFlags;
249 if (closeEndpoint) {
250 closingNetwork = networkImpl;
251 closingInotify = inotifyImpl;
252 closingFanotify = fanotifyImpl;
253 }
254 }
255 if (closeEndpoint) {
256 decreaseFileReferences(getFile(), flags);
257 if (getFile() && !(flags & O_PATH)) {
258 getFile()->publishEvent((flags & O_ACCMODE) == O_RDONLY ? FileEvents::CloseNoWrite
259 : FileEvents::CloseWrite);
260 }
261 if (closingNetwork) {
262 closingNetwork->lastDescriptorClosed();
263 }
264 if (closingInotify) {
265 closingInotify->lastDescriptorClosed();
266 }
267 if (closingFanotify) {
268 closingFanotify->lastDescriptorClosed();
269 }
270 }
271}
272
273void FileDescriptor::OpenFileDescription::ensureVfsLease() {
274 LockGuard<Mutex> guard(lock);
275 if (!path && !vfsLease && getFile()) {
276 vfsLease = getFile()->retainVfsReference();
277 }
278}
279
282 : fd(0xFFFFFFFF),
283 networkImpl(nullptr),
284 epollImpl(nullptr),
285 ioevent(nullptr),
286 fdflags(0),
287 m_OpenFile(new OpenFileDescription(nullptr, 0, 0)),
288 m_NetworkPublished(false),
289 m_EventFdPublished(false) {}
290
292FileDescriptor::FileDescriptor(File* newFile, uint64_t newOffset, size_t newFd, int fdFlags,
293 int flFlags)
294 : fd(newFd),
295 networkImpl(nullptr),
296 epollImpl(nullptr),
297 ioevent(nullptr),
298 fdflags(fdFlags | ((flFlags & O_CLOEXEC) ? FD_CLOEXEC : 0)),
299 m_OpenFile(new OpenFileDescription(newFile, newOffset, flFlags & ~O_CLOEXEC)),
300 m_NetworkPublished(false),
301 m_EventFdPublished(false) {
303}
304
305FileDescriptor::FileDescriptor(const FilesystemPathRef& path, uint64_t newOffset, size_t newFd,
306 int fdFlags, int flFlags)
307 : fd(newFd),
308 networkImpl(nullptr),
309 epollImpl(nullptr),
310 ioevent(nullptr),
311 fdflags(fdFlags | ((flFlags & O_CLOEXEC) ? FD_CLOEXEC : 0)),
312 m_OpenFile(new OpenFileDescription(path, newOffset, flFlags & ~O_CLOEXEC)),
313 m_NetworkPublished(false),
314 m_EventFdPublished(false) {}
315
318 : fd(desc.fd),
319 networkImpl(desc.networkImpl),
320 epollImpl(desc.epollImpl),
321 ioevent(nullptr),
322 fdflags(desc.fdflags),
323 m_OpenFile(desc.m_OpenFile),
324 m_NetworkPublished(false),
325 m_EventFdPublished(false) {
326 m_OpenFile->addDescriptorOwner();
327 m_OpenFile->ensureVfsLease();
328 if (networkImpl) {
330 }
331 SharedPointer<EventFd> eventFd = m_OpenFile->getEventFdImpl();
332 if (eventFd) {
333 m_EventFdPublished = eventFd->addDescriptorOwner();
334 }
335 auto timerFd = m_OpenFile->getTimerFdImpl();
336 if (timerFd) {
337 m_TimerFdPublished = timerFd->addDescriptorOwner();
338 }
339 auto signalFd = m_OpenFile->getSignalFdImpl();
340 if (signalFd) {
341 m_SignalFdPublished = signalFd->addDescriptorOwner();
342 }
343
344#if THREADS
345 if (desc.ioevent) {
346 ioevent = new IoEvent(*desc.ioevent);
347 }
348#endif
349}
350
353 : fd(0),
354 networkImpl(nullptr),
355 epollImpl(nullptr),
356 ioevent(nullptr),
357 fdflags(0),
358 m_OpenFile(nullptr),
359 m_NetworkPublished(false),
360 m_EventFdPublished(false) {
361 if (!desc) {
362 m_OpenFile.reset(new OpenFileDescription(nullptr, 0, 0));
363 return;
364 }
365
366 fd = desc->fd;
367 fdflags = desc->fdflags;
368 networkImpl = desc->networkImpl;
369 epollImpl = desc->epollImpl;
370 m_OpenFile = desc->m_OpenFile;
371 m_OpenFile->addDescriptorOwner();
372 m_OpenFile->ensureVfsLease();
373 if (networkImpl) {
375 }
376 SharedPointer<EventFd> eventFd = m_OpenFile->getEventFdImpl();
377 if (eventFd) {
378 m_EventFdPublished = eventFd->addDescriptorOwner();
379 }
380 auto timerFd = m_OpenFile->getTimerFdImpl();
381 if (timerFd) {
382 m_TimerFdPublished = timerFd->addDescriptorOwner();
383 }
384 auto signalFd = m_OpenFile->getSignalFdImpl();
385 if (signalFd) {
386 m_SignalFdPublished = signalFd->addDescriptorOwner();
387 }
388
389#if THREADS
390 if (desc->ioevent) {
391 ioevent = new IoEvent(*desc->ioevent);
392 }
393#endif
394}
395
398 unpublish();
399#if THREADS
400 retireIoEvent(getFile(), networkImpl, ioevent);
401#endif
402
403 if (m_OpenFile) {
404 m_OpenFile->removeDescriptorOwner();
405 }
406
409}
410
411void FileDescriptor::setFlags(int newFlags) {
412 fdflags = newFlags;
413}
414
415void FileDescriptor::addFlag(int newFlag) {
416 setFlags(fdflags | newFlag);
417}
418
420 return fdflags;
421}
422
424 LockGuard<Mutex> guard(m_OpenFile->lock);
425 m_OpenFile->statusFlags =
426 (m_OpenFile->statusFlags & ~MutableStatusFlags) | (newFlags & MutableStatusFlags);
427
428 if (m_OpenFile->networkImpl) {
429 bool nonblock = (m_OpenFile->statusFlags & O_NONBLOCK) == O_NONBLOCK;
430 m_OpenFile->networkImpl->setBlocking(!nonblock);
431 }
432}
433
435 LockGuard<Mutex> guard(m_OpenFile->lock);
436 m_OpenFile->statusFlags |= newFlag & MutableStatusFlags;
437 if (m_OpenFile->networkImpl) {
438 m_OpenFile->networkImpl->setBlocking(!(m_OpenFile->statusFlags & O_NONBLOCK));
439 }
440}
441
443 LockGuard<Mutex> guard(m_OpenFile->lock);
444 m_OpenFile->statusFlags &= ~(flag & MutableStatusFlags);
445 if (m_OpenFile->networkImpl) {
446 m_OpenFile->networkImpl->setBlocking(!(m_OpenFile->statusFlags & O_NONBLOCK));
447 }
448}
449
451 LockGuard<Mutex> guard(m_OpenFile->lock);
452 return m_OpenFile->statusFlags;
453}
454
458
460 LockGuard<Mutex> guard(m_OpenFile->lock);
461 assert(!m_OpenFile->getFile() && !m_OpenFile->networkImpl);
462 networkImpl = implementation;
463 m_OpenFile->networkImpl = implementation;
464 if (networkImpl) {
465 networkImpl->setBlocking(!(m_OpenFile->statusFlags & O_NONBLOCK));
466 }
467 if (implementation) {
468 m_NetworkPublished = implementation->addDescriptorOwner();
469 assert(m_NetworkPublished);
470 if (m_NetworkPublished) {
471 implementation->retainDescriptorLifetime(implementation);
472 }
473 }
474}
475
479
481 {
482 LockGuard<Mutex> guard(m_OpenFile->lock);
483 assert(!m_OpenFile->getFile());
484 assert(!m_OpenFile->eventFdImpl);
485 m_OpenFile->eventFdImpl = implementation;
486 }
487
488 if (implementation) {
489 m_EventFdPublished = implementation->addDescriptorOwner();
490 assert(m_EventFdPublished);
491 }
492}
493
495 return m_OpenFile->getEventFdImpl();
496}
497
501
502void FileDescriptor::setTimerFdImpl(const SharedPointer<TimerFd>& implementation) {
503 {
504 LockGuard<Mutex> guard(m_OpenFile->lock);
505 assert(!m_OpenFile->getFile());
506 assert(!m_OpenFile->timerFdImpl);
507 m_OpenFile->timerFdImpl = implementation;
508 }
509 if (implementation) {
510 m_TimerFdPublished = implementation->addDescriptorOwner();
511 assert(m_TimerFdPublished);
512 }
513}
514
515SharedPointer<TimerFd> FileDescriptor::getTimerFdImpl() const {
516 return m_OpenFile->getTimerFdImpl();
517}
518
519bool FileDescriptor::timerFdPublished() const {
520 return m_TimerFdPublished;
521}
522
523void FileDescriptor::setSignalFdImpl(const SharedPointer<SignalFd>& implementation) {
524 {
525 LockGuard<Mutex> guard(m_OpenFile->lock);
526 assert(!m_OpenFile->getFile());
527 assert(!m_OpenFile->signalFdImpl);
528 m_OpenFile->signalFdImpl = implementation;
529 }
530 if (implementation) {
531 m_SignalFdPublished = implementation->addDescriptorOwner();
532 assert(m_SignalFdPublished);
533 }
534}
535
536SharedPointer<SignalFd> FileDescriptor::getSignalFdImpl() const {
537 return m_OpenFile->getSignalFdImpl();
538}
539
540bool FileDescriptor::signalFdPublished() const {
541 return m_SignalFdPublished;
542}
543
545 LockGuard<Mutex> guard(m_OpenFile->lock);
546 assert(!m_OpenFile->getFile());
547 assert(!m_OpenFile->inotifyImpl);
548 m_OpenFile->inotifyImpl = implementation;
549}
550
554
555void FileDescriptor::setFanotifyImpl(const SharedPointer<FanotifyInstance>& implementation) {
556 LockGuard<Mutex> guard(m_OpenFile->lock);
557 assert(!m_OpenFile->getFile());
558 assert(!m_OpenFile->fanotifyImpl);
559 m_OpenFile->fanotifyImpl = implementation;
560}
561
562SharedPointer<FanotifyInstance> FileDescriptor::getFanotifyImpl() const {
563 return m_OpenFile->getFanotifyImpl();
564}
565
566SharedPointer<PosixMessageQueue> FileDescriptor::OpenFileDescription::getMqueueImpl() const {
567 return mqueueImpl;
568}
569
570void FileDescriptor::setMqueueImpl(const SharedPointer<PosixMessageQueue>& implementation) {
571 LockGuard<Mutex> guard(m_OpenFile->lock);
572 assert(!getFile() && !m_OpenFile->getFile());
573 assert(!m_OpenFile->mqueueImpl);
574 m_OpenFile->mqueueImpl = implementation;
575}
576
577SharedPointer<PosixMessageQueue> FileDescriptor::getMqueueImpl() const {
578 return m_OpenFile->getMqueueImpl();
579}
580
582 if (m_TimerFdPublished) {
583 m_TimerFdPublished = false;
584 auto timerFd = m_OpenFile->getTimerFdImpl();
585 if (timerFd) {
586 timerFd->removeDescriptorOwner();
587 }
588 }
589 if (m_SignalFdPublished) {
590 m_SignalFdPublished = false;
591 auto signalFd = m_OpenFile->getSignalFdImpl();
592 if (signalFd) {
593 signalFd->removeDescriptorOwner();
594 }
595 }
596 if (m_NetworkPublished) {
597 m_NetworkPublished = false;
598 if (networkImpl) {
599 networkImpl->removeDescriptorOwner();
600 }
601 }
602
603 if (m_EventFdPublished) {
604 m_EventFdPublished = false;
605 SharedPointer<EventFd> eventFd = m_OpenFile->getEventFdImpl();
606 if (eventFd) {
607 eventFd->removeDescriptorOwner();
608 }
609 }
610}
611
612FileDescriptor::PositionGuard::PositionGuard(const SharedPointer<OpenFileDescription>& description)
613 : m_Description(description), m_Guard(m_Description->lock) {}
614
618
620 PositionGuard position = lockPosition();
621 return position.offset();
622}
623
624void FileDescriptor::setOffset(uint64_t offset) {
625 PositionGuard position = lockPosition();
626 position.setOffset(offset);
627}
628
629uint64_t FileDescriptor::read(uint64_t size, uintptr_t buffer, bool canBlock) {
630 if (!getFile()) {
631 return 0;
632 }
633 if (!getFile()->isSeekable()) {
634 return readFile(0, size, buffer, canBlock && !(getStatusFlags() & O_NONBLOCK));
635 }
636
637 LockGuard<Mutex> guard(m_OpenFile->lock);
638 const bool shouldBlock = canBlock && !(m_OpenFile->statusFlags & O_NONBLOCK);
639 uint64_t amount = getFile()->read(m_OpenFile->offset, size, buffer, shouldBlock);
640 m_OpenFile->offset += amount;
641 return amount;
642}
643
644uint64_t FileDescriptor::write(uint64_t size, uintptr_t buffer, bool canBlock) {
645 if (!getFile()) {
646 return 0;
647 }
648 if (!getFile()->isSeekable()) {
649 return writeFile(0, size, buffer, canBlock && !(getStatusFlags() & O_NONBLOCK));
650 }
651
652 LockGuard<Mutex> guard(m_OpenFile->lock);
653 const bool shouldBlock = canBlock && !(m_OpenFile->statusFlags & O_NONBLOCK);
654 uint64_t location = m_OpenFile->offset;
655 const uint64_t amount = (m_OpenFile->statusFlags & O_APPEND)
656 ? getFile()->append(size, buffer, location, shouldBlock)
657 : getFile()->write(location, size, buffer, shouldBlock);
658 if (amount) {
659 m_OpenFile->offset = location + amount;
660 }
661 return amount;
662}
void beginRetirement(Retirement &retirement)
Definition Event.cc:484
SharedPointer< EpollInstance > epollImpl
Epoll implementation for this descriptor (if it is an epoll object).
void setNetworkImpl(const SharedPointer< NetworkSyscalls > &implementation)
OpenFileDescriptionLease acquireOpenFileDescription() const
int fdflags
File descriptor flags (fcntl)
void setFlags(int newFlags)
Set flags, distributing any associated changes as needed.
OpenFileDescriptionLease m_OpenFile
void setEventFdImpl(const SharedPointer< EventFd > &implementation)
bool eventFdPublished() const
void addFlag(int newFlag)
Helper to add a single flag to the descriptor flags.
void setOffset(uint64_t offset)
void removeStatusFlag(int flag)
Helper to remove a single flag from the status flags.
IoEvent * ioevent
IO event for reporting changes to files.
SharedPointer< InotifyInstance > getInotifyImpl() const
PositionGuard lockPosition() const
SharedPointer< EventFd > getEventFdImpl() const
int getFlags() const
Get current descriptor flags.
int getStatusFlags() const
Get current status flags.
void addStatusFlag(int newFlag)
Helper to add a single flag to the status flags.
void setStatusFlags(int newFlags)
Set status flags, distributing any associated changes as needed.
SharedPointer< NetworkSyscalls > networkImpl
Network syscall implementation for this descriptor (if it's a socket).
virtual ~FileDescriptor()
Destructor - decreases file reference count.
size_t fd
Descriptor number.
uint64_t write(uint64_t size, uintptr_t buffer, bool canBlock=true)
bool networkPublished() const
uint64_t read(uint64_t size, uintptr_t buffer, bool canBlock=true)
FileDescriptor()
Default constructor.
void setInotifyImpl(const SharedPointer< InotifyInstance > &implementation)
uint64_t getOffset() const
Definition File.h:75
virtual bool retainVfsReference()
Definition File.cc:910
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
Definition File.cc:239
void cullMonitorTargets(Thread *pThread)
Definition File.cc:1496
uint64_t append(uint64_t size, uintptr_t buffer, uint64_t &location, bool bCanBlock=true)
Definition File.cc:415
virtual void releaseVfsReference()
Definition File.cc:914
virtual uint64_t write(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
Definition File.cc:342
virtual bool isDirectory()
Definition File.cc:804
void publishEvent(FileEventMask mask, const StringView &name=StringView(), bool targetIsDirectory=false)
Definition File.cc:861
virtual bool isFifo() const
Definition File.cc:812
virtual bool isPipe() const
Definition File.cc:808
virtual ReadyMask queryReady(bool reading, bool writing)
Definition File.cc:1054
MUST_USE_RESULT bool addDescriptorOwner()
virtual ReadinessGenerations readinessGenerations()
Definition Readiness.cc:177