22#include "DevFs-block.h"
24#include "PosixSubsystem.h"
25#include "descriptor-path.h"
26#include "linux-fb-abi.h"
27#include "modules/system/vfs/Pipe.h"
28#include "modules/system/vfs/Symlink.h"
29#include "modules/system/vfs/VFS.h"
31#define MACHINE_FORWARD_DECL_ONLY
32#include "pedigree/kernel/ServiceManager.h"
33#include "pedigree/kernel/graphics/Graphics.h"
34#include "pedigree/kernel/graphics/GraphicsService.h"
35#include "pedigree/kernel/machine/Display.h"
36#include "pedigree/kernel/machine/Framebuffer.h"
37#include "pedigree/kernel/machine/InputManager.h"
38#include "pedigree/kernel/machine/Machine.h"
39#include "pedigree/kernel/machine/Serial.h"
40#include "pedigree/kernel/machine/Vga.h"
41#include "pedigree/kernel/process/Process.h"
42#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
43#include "pedigree/kernel/syscallError.h"
44#include "pedigree/kernel/utilities/SecureRandom.h"
45#include "pedigree/kernel/utilities/assert.h"
46#include "pedigree/kernel/utilities/lib.h"
47#include "pedigree/kernel/utilities/utility.h"
49#include "modules/system/console/Console.h"
50#include <pedigree/fb.h>
53#define ALT_KEY (1ULL << 60)
54#define SHIFT_KEY (1ULL << 61)
55#define CTRL_KEY (1ULL << 62)
56#define SPECIAL_KEY (1ULL << 63)
59class CttySelectorFile final :
public File {
61 CttySelectorFile(
size_t inode,
Filesystem* filesystem,
File* parent)
62 :
File(
String(
"tty"), 0, 0, 0, inode, filesystem, 0, parent) {
72class FullFile final :
public ZeroFile {
77 uint64_t
writeBytewise(uint64_t, uint64_t, uintptr_t,
bool)
override {
78 SYSCALL_ERROR(NoSpaceLeftOnDevice);
83class DeviceLink final :
public Symlink {
87 :
Symlink(name, 0, 0, 0, inode, filesystem, target.length(), parent) {
89 setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GW | FILE_GX | FILE_OR | FILE_OW |
94void setLinuxBitfield(
LinuxFbBitfield& field, uint32_t offset, uint32_t length) {
95 field.offset = offset;
96 field.length = length;
101 case Graphics::Bits32_Argb:
102 setLinuxBitfield(info.red, 16, 8);
103 setLinuxBitfield(info.green, 8, 8);
104 setLinuxBitfield(info.blue, 0, 8);
105 setLinuxBitfield(info.transparency, 24, 8);
107 case Graphics::Bits32_Rgba:
108 setLinuxBitfield(info.red, 24, 8);
109 setLinuxBitfield(info.green, 16, 8);
110 setLinuxBitfield(info.blue, 8, 8);
111 setLinuxBitfield(info.transparency, 0, 8);
113 case Graphics::Bits32_Rgb:
114 case Graphics::Bits24_Rgb:
115 setLinuxBitfield(info.red, 16, 8);
116 setLinuxBitfield(info.green, 8, 8);
117 setLinuxBitfield(info.blue, 0, 8);
119 case Graphics::Bits32_Bgr:
120 case Graphics::Bits24_Bgr:
121 setLinuxBitfield(info.red, 0, 8);
122 setLinuxBitfield(info.green, 8, 8);
123 setLinuxBitfield(info.blue, 16, 8);
125 case Graphics::Bits16_Argb:
126 setLinuxBitfield(info.red, 8, 4);
127 setLinuxBitfield(info.green, 4, 4);
128 setLinuxBitfield(info.blue, 0, 4);
129 setLinuxBitfield(info.transparency, 12, 4);
131 case Graphics::Bits16_Rgb565:
132 setLinuxBitfield(info.red, 11, 5);
133 setLinuxBitfield(info.green, 5, 6);
134 setLinuxBitfield(info.blue, 0, 5);
136 case Graphics::Bits16_Rgb555:
137 setLinuxBitfield(info.red, 10, 5);
138 setLinuxBitfield(info.green, 5, 5);
139 setLinuxBitfield(info.blue, 0, 5);
141 case Graphics::Bits8_Idx:
142 info.red.length = info.green.length = info.blue.length = 8;
144 case Graphics::Bits8_Rgb332:
145 setLinuxBitfield(info.red, 5, 3);
146 setLinuxBitfield(info.green, 2, 3);
147 setLinuxBitfield(info.blue, 0, 2);
153 info.xResolution = framebuffer.getWidth();
154 info.yResolution = framebuffer.getHeight();
155 info.virtualXResolution = info.xResolution;
156 info.virtualYResolution = info.yResolution;
157 info.bitsPerPixel = depth ? depth : Graphics::bitsPerPixel(framebuffer.getFormat());
158 info.heightMillimeters = UINT32_MAX;
159 info.widthMillimeters = UINT32_MAX;
160 setLinuxPixelFormat(info, framebuffer.getFormat());
175 uint8_t snapshot[256];
177 while (done < size) {
178 const size_t count = size - done <
sizeof(snapshot) ? size - done :
sizeof(snapshot);
179 const size_t produced = secure_random_bytes(snapshot, count);
182 SYSCALL_ERROR(NoMoreProcesses);
187 MemoryCopy(
reinterpret_cast<void*
>(buffer + done), snapshot, produced);
190 pedigree_random::erase(snapshot,
sizeof(snapshot));
202 return command == 0x40085203UL;
207 SYSCALL_ERROR(InvalidArgument);
211 if (process->getEffectiveUserId() != 0) {
212 SYSCALL_ERROR(NotEnoughPermissions);
224 pedigree_random::erase(&request,
sizeof(request));
225 SYSCALL_ERROR(BadAddress);
228 if (request.entropyBits != 256 || request.bytes != 32) {
229 pedigree_random::erase(&request,
sizeof(request));
230 SYSCALL_ERROR(InvalidArgument);
233 const int accepted = secure_random_seed(request.seed,
sizeof(request.seed));
234 pedigree_random::erase(&request,
sizeof(request));
236 SYSCALL_ERROR(InvalidArgument);
253 DevFsDirectory* ptsDirectory, uint32_t slavePermissions,
bool callerOwns)
254 :
File(str, 0, 0, 0, inode, pParentFS, 0, pParent),
256 m_pPtsDirectory(ptsDirectory),
257 m_SlavePermissions(slavePermissions),
258 m_CallerOwns(callerOwns) {
264PtmxFile::~PtmxFile() {
265 for (
auto* master : m_Masters) {
282 if (!m_Masters.tryReserve(m_Masters.
count() + 1)) {
283 SYSCALL_ERROR(OutOfMemory);
290 String masterName, slaveName;
291 masterName.Format(
"pty%d", terminal);
292 slaveName.Format(
"%d", terminal);
297 new ConsoleSlaveFile(terminal, slaveName, m_pPtsDirectory->getFilesystem(), m_pPtsDirectory);
298 if (!pMaster || !pSlave) {
301 SYSCALL_ERROR(OutOfMemory);
304 pMaster->setInode(getFilesystem() == g_pDevFs ? g_pDevFs->getNextInode() : 3 + terminal * 2);
305 pSlave->setInode(getFilesystem() == g_pDevFs ? g_pDevFs->getNextInode() : 4 + terminal * 2);
306 pSlave->setPermissions(m_SlavePermissions);
309 if (!Process::currentFilesystemCredentials(credentials)) {
312 SYSCALL_ERROR(NotEnoughPermissions);
315 pMaster->setUid(credentials.uid);
316 pMaster->setGid(credentials.gid);
317 pSlave->setUid(credentials.uid);
318 pSlave->setGid(credentials.gid);
321 pMaster->setOther(pSlave);
322 pSlave->setOther(pMaster);
324 if (!m_pPtsDirectory->addEntry(slaveName, pSlave)) {
327 SYSCALL_ERROR(OutOfMemory);
332 m_Terminals.
set(terminal);
343 ByteSet(
reinterpret_cast<void*
>(buffer), 0, size);
354 :
File(str, 0, 0, 0, inode, pParentFS, 0, pParent), m_Serial(serial) {
362 if (!m_Serial || !size) {
366 char* destination =
reinterpret_cast<char*
>(buffer);
369 const char c = m_Serial->read();
373 destination[count++] = c;
376 while (count < size) {
377 const char c = m_Serial->readNonBlock();
381 destination[count++] = c;
392 const char* source =
reinterpret_cast<const char*
>(buffer);
393 for (
size_t i = 0; i < size; ++i) {
394 m_Serial->write(source[i]);
401 return m_Serial ? 1 : 0;
403 return m_Serial && m_Serial->hasData() ? 1 : 0;
423 NOTICE(
"RtcFile: command " <<
Hex << command <<
" with buffer " << buffer);
427FramebufferFile::FramebufferFile(
String str,
size_t inode,
Filesystem* pParentFS,
File* pParentNode)
428 :
File(str, 0, 0, 0, inode, pParentFS, 0, pParentNode),
429 m_pGraphicsParameters(0),
436 for (
size_t i = 0; i < 256; ++i) {
437 m_LinuxPalette[i] = Graphics::createRgb(i, i, i);
441FramebufferFile::~FramebufferFile() {
445bool FramebufferFile::initialise() {
462 setPhysicalMappingFlags(
467 m_nDepth = currentMode.pf.
nBpp;
473 return pFeatures && pService;
480 if (location > getSize()) {
481 ERROR(
"FramebufferFile::readBlock with location > size: " << location);
486 return reinterpret_cast<uintptr_t
>(
493 return ~physical_uintptr_t(0);
505 return ((PEDIGREE_FB_CMD_MIN <= command) && (command <= PEDIGREE_FB_CMD_MAX)) ||
506 command == LinuxFbGetVariableInfo || command == LinuxFbPutVariableInfo ||
507 command == LinuxFbGetFixedInfo || command == LinuxFbGetColorMap ||
508 command == LinuxFbPutColorMap || command == LinuxFbPanDisplay || command == LinuxFbBlank;
513 ERROR(
"FramebufferFile::command called on an invalid FramebufferFile");
521 case LinuxFbGetFixedInfo: {
523 MemoryCopy(value.id,
"Pedigree fb", 11);
524 const uint64_t framebufferSize = getSize();
526 framebufferSize > UINT32_MAX ? UINT32_MAX :
static_cast<uint32_t
>(framebufferSize);
527 value.type = LinuxFbPackedPixels;
529 pFramebuffer->getFormat() == Graphics::Bits8_Idx ? LinuxFbPseudoColor : LinuxFbTrueColor;
530 value.lineLength = pFramebuffer->getBytesPerLine();
532 SYSCALL_ERROR(BadAddress);
537 case LinuxFbGetVariableInfo: {
540 size_t depth = m_nDepth;
542 depth = currentMode.pf.
nBpp;
544 fillLinuxVariableInfo(value, *pFramebuffer, depth);
546 SYSCALL_ERROR(BadAddress);
551 case LinuxFbPutVariableInfo: {
554 SYSCALL_ERROR(BadAddress);
557 if (!requested.xResolution || !requested.yResolution || requested.bitsPerPixel <= 8 ||
558 requested.xOffset || requested.yOffset ||
559 (requested.virtualXResolution && requested.virtualXResolution != requested.xResolution) ||
560 (requested.virtualYResolution && requested.virtualYResolution != requested.yResolution)) {
561 SYSCALL_ERROR(InvalidArgument);
564 if ((requested.activate & LinuxFbActivateMask) != LinuxFbActivateTest) {
565 if (!pDisplay->
setScreenMode(requested.xResolution, requested.yResolution,
566 requested.bitsPerPixel)) {
567 SYSCALL_ERROR(InvalidArgument);
570 m_nDepth = requested.bitsPerPixel;
572 setSize(pFramebuffer->getHeight() * pFramebuffer->getBytesPerLine());
575 fillLinuxVariableInfo(result, *pFramebuffer, m_nDepth);
577 SYSCALL_ERROR(BadAddress);
582 case LinuxFbPanDisplay: {
585 SYSCALL_ERROR(BadAddress);
588 if (requested.xOffset || requested.yOffset) {
589 SYSCALL_ERROR(InvalidArgument);
593 fillLinuxVariableInfo(result, *pFramebuffer, m_nDepth);
595 SYSCALL_ERROR(BadAddress);
600 case LinuxFbGetColorMap: {
603 SYSCALL_ERROR(BadAddress);
606 if (map.start > 256 || map.length > 256 - map.start) {
607 SYSCALL_ERROR(InvalidArgument);
610 for (
size_t i = 0; i < map.length; ++i) {
611 const uint32_t colour = m_LinuxPalette[map.start + i];
612 const uint16_t red =
static_cast<uint16_t
>(((colour >> 16) & 0xff) * 0x101);
613 const uint16_t green =
static_cast<uint16_t
>(((colour >> 8) & 0xff) * 0x101);
614 const uint16_t blue =
static_cast<uint16_t
>((colour & 0xff) * 0x101);
615 const uint16_t transparency = 0xffff;
616 if (!map.red || !map.green || !map.blue ||
621 sizeof(transparency)))) {
622 SYSCALL_ERROR(BadAddress);
628 case LinuxFbPutColorMap: {
631 SYSCALL_ERROR(BadAddress);
634 if (map.start > 256 || map.length > 256 - map.start) {
635 SYSCALL_ERROR(InvalidArgument);
638 for (
size_t i = 0; i < map.length; ++i) {
642 if (!map.red || !map.green || !map.blue ||
646 SYSCALL_ERROR(BadAddress);
649 m_LinuxPalette[map.start + i] = Graphics::createRgb(red >> 8, green >> 8, blue >> 8);
651 if (pFramebuffer->getFormat() == Graphics::Bits8_Idx) {
652 pFramebuffer->
setPalette(m_LinuxPalette, 256);
658 case PEDIGREE_FB_SETMODE: {
661 SYSCALL_ERROR(BadAddress);
665 size_t desiredWidth = arg->width;
666 size_t desiredHeight = arg->height;
667 size_t desiredDepth = arg->depth;
670 if (!(desiredWidth && desiredHeight && desiredDepth)) {
671 bool bSuccess =
false;
676 setSize(pFramebuffer->getHeight() * pFramebuffer->getBytesPerLine());
679 m_nDepth = currentMode.pf.
nBpp;
681 if (Machine::instance().getNumVga())
686 if (Machine::instance().getNumVga()) {
687 Vga* pVga = Machine::instance().
getVga(0);
700 :
"restored graphics mode"));
708 while (desiredDepth > 8) {
709 if (pDisplay->
setScreenMode(desiredWidth, desiredHeight, desiredDepth)) {
710 NOTICE(
"FramebufferFile: set mode " <<
Dec << desiredWidth <<
"x" << desiredHeight <<
"x"
711 << desiredDepth <<
Hex <<
".");
719 m_nDepth = desiredDepth;
721 setSize(pFramebuffer->getHeight() * pFramebuffer->getBytesPerLine());
726 return bSet ? 0 : -1;
728 case PEDIGREE_FB_GETMODE: {
732 ByteSet(arg, 0,
sizeof(*arg));
734 arg->width = pFramebuffer->getWidth();
735 arg->height = pFramebuffer->getHeight();
736 arg->depth = m_nDepth;
737 arg->bytes_per_pixel = pFramebuffer->getBytesPerPixel();
738 arg->format = pFramebuffer->getFormat();
739 arg->bytes_per_line = pFramebuffer->getBytesPerLine();
742 SYSCALL_ERROR(BadAddress);
747 case PEDIGREE_FB_REDRAW: {
750 pFramebuffer->
redraw(0, 0, pFramebuffer->getWidth(), pFramebuffer->getHeight(),
true);
754 SYSCALL_ERROR(BadAddress);
758 pFramebuffer->
redraw(arg->x, arg->y, arg->w, arg->h,
true);
769 :
File(str, 0, 0, 0, inode, pParentFS, 0, pParent), m_pDevFs(devfs) {
775Tty0File::~Tty0File() {}
789 return m_pDevFs->getTerminalManager().getCurrentTerminalFile();
801DevFsDirectory::~DevFsDirectory() =
default;
809 ERROR(
"DevFs: root directory did not get cleaned up");
825 m_pRoot->setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GW | FILE_GX | FILE_OR |
830 File* block = posix_make_block_directory(*
this, m_pRoot);
833 m_pRoot->addEntry(block->
getName(), block);
835 File* disk = posix_make_disk_directory(*
this, m_pRoot);
838 m_pRoot->addEntry(disk->
getName(), disk);
840 File* descriptors = posix_make_dev_fd_link(*
this, m_pRoot);
843 m_pRoot->addEntry(descriptors->
getName(), descriptors);
845 m_CttySelector =
new CttySelectorFile(getNextInode(),
this, m_pRoot);
848 m_pRoot->addEntry(m_CttySelector->
getName(), m_CttySelector);
853 FullFile* pFull =
new FullFile(getNextInode(),
this, m_pRoot);
854 m_pRoot->addEntry(pNull->
getName(), pNull);
855 m_pRoot->addEntry(pZero->
getName(), pZero);
856 m_pRoot->addEntry(pFull->getName(), pFull);
859 pShm->setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GW | FILE_GX | FILE_OR |
860 FILE_OW | FILE_OX | FILE_STICKY);
861 m_pRoot->addEntry(pShm->getName(), pShm);
866 } standardStreams[] = {
867 {
"stdin",
"/proc/self/fd/0"}, {
"stdout",
"/proc/self/fd/1"}, {
"stderr",
"/proc/self/fd/2"}};
868 for (
const auto& stream : standardStreams) {
870 new DeviceLink(
String(stream.name),
String(stream.target), getNextInode(),
this, m_pRoot);
871 m_pRoot->addEntry(link->getName(), link);
874 if (Machine::instance().getNumSerial()) {
876 Machine::instance().getSerial(0));
878 m_pRoot->addEntry(console->getName(), console);
883 m_pRoot->addEntry(pMem->
getName(), pMem);
888 pPts->setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
889 m_pRoot->addEntry(pPts->
getName(), pPts);
893 m_pRoot->addEntry(pPtmx->
getName(), pPtmx);
897 m_pRoot->addEntry(pUrandom->
getName(), pUrandom);
901 m_pRoot->addEntry(pRandom->
getName(), pRandom);
905 const bool framebufferAvailable = pFb->initialise();
906 if (framebufferAvailable)
907 m_pRoot->addEntry(pFb->
getName(), pFb);
909 WARNING(
"POSIX: no /dev/fb0 - framebuffer failed to initialise.");
913 if (framebufferAvailable) {
914 auto* pFbAlias =
new DeviceLink(
String(
"fb"),
String(
"fb0"), getNextInode(),
this, m_pRoot);
915 m_pRoot->addEntry(pFbAlias->getName(), pFbAlias);
919 if (!m_VtManager->initialise()) {
920 WARNING(
"POSIX: no /dev/tty - VT manager failed to initialise");
922 m_VtManager =
nullptr;
927 m_pRoot->addEntry(pTty0->
getName(), pTty0);
929 File* pConsole =
nullptr;
931 pConsole =
new Tty0File(
String(
"console"), getNextInode(),
this, m_pRoot,
this);
933 pConsole =
new DeviceLink(
String(
"console"),
String(
"ttyS0"), getNextInode(),
this, m_pRoot);
935 m_pRoot->addEntry(pConsole->
getName(), pConsole);
937 Pipe* initctl =
new Pipe(
String(
"initctl"), 0, 0, 0, getNextInode(),
this, 0, m_pRoot);
938 m_pRoot->addEntry(initctl->
getName(), initctl);
942 m_pRoot->addEntry(rtc->
getName(), rtc);
944 auto* pInputDirectory =
946 pInputDirectory->setPermissions(FILE_UR | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
947 m_pRoot->addEntry(pInputDirectory->getName(), pInputDirectory);
950 if (pInput && pInput->initialise()) {
951 pInputDirectory->addEntry(pInput->
getName(), pInput);
958 new EvdevFile(
String(
"event0"), getNextInode(),
this, pInputDirectory, EvdevFile::Keyboard);
959 if (keyboard && keyboard->initialise()) {
960 pInputDirectory->addEntry(keyboard->getName(), keyboard);
967 new EvdevFile(
String(
"event1"), getNextInode(),
this, pInputDirectory, EvdevFile::Pointer);
968 if (pointer && pointer->initialise()) {
969 pInputDirectory->addEntry(pointer->getName(), pointer);
975 auto* tablet =
new EvdevFile(
String(
"event2"), getNextInode(),
this, pInputDirectory,
976 EvdevFile::AbsolutePointer);
977 if (tablet && tablet->initialise()) {
978 pInputDirectory->addEntry(tablet->getName(), tablet);
986 if (pPsAux->initialise()) {
987 m_pRoot->addEntry(pPsAux->
getName(), pPsAux);
988 m_pPsAuxFile = pPsAux;
1000size_t DevFs::getNextInode() {
1001 return __atomic_fetch_add(&m_NextInode, 1, __ATOMIC_RELAXED);
1004void DevFs::revertInode() {
1005 __atomic_fetch_sub(&m_NextInode, 1, __ATOMIC_RELAXED);
1009 uint64_t c = in.data.key.key;
1010 if (!m_VtManager || (c & (CTRL_KEY | ALT_KEY)) != (CTRL_KEY | ALT_KEY)) {
1013 if (c & SPECIAL_KEY) {
1014 uint32_t k = c & 0xFFFFFFFFUL;
1015 char* s =
reinterpret_cast<char*
>(&k);
1018 if (!StringCompareN(s,
"f1", 3)) {
1020 }
else if (!StringCompareN(s,
"f2", 3)) {
1022 }
else if (!StringCompareN(s,
"f3", 3)) {
1024 }
else if (!StringCompareN(s,
"f4", 3)) {
1026 }
else if (!StringCompareN(s,
"f5", 3)) {
1028 }
else if (!StringCompareN(s,
"f6", 3)) {
virtual bool initialise(Disk *pDisk)
virtual bool getCurrentScreenMode(ScreenMode &sm)
virtual bool setScreenMode(ScreenMode sm)
virtual bool isBytewise() const
void setGidOnly(size_t gid)
void setPermissionsOnly(uint32_t perms)
void setUidOnly(size_t uid)
GraphicsService::GraphicsParameters * m_pGraphicsParameters
void returnPhysicalPage(size_t offset) override
virtual int command(const size_t command, void *buffer)
virtual bool supports(const size_t command) const
virtual physical_uintptr_t getPhysicalPage(size_t offset)
virtual uintptr_t readBlock(uint64_t location)
virtual physical_uintptr_t getPhysicalPage(size_t offset) const
virtual void * getRawBuffer() const
void setPalette(uint32_t *palette, size_t nEntries)
void redraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL, bool bChild=false)
virtual Vga * getVga(size_t n)=0
virtual void returnPhysicalPage(size_t offset)
virtual physical_uintptr_t getPhysicalPage(size_t offset)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
static constexpr size_t getPageSize() PURE
static bool copyFromUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static bool copyToUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static ProcessorInformation & information()
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
bool supports(size_t command) const override
int command(size_t command, void *buffer) override
virtual int command(const size_t command, void *buffer)
virtual bool supports(const size_t command) const
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual int select(bool bWriting=false, int timeout=0)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual bool provides(Type service)
Service * getService(const String &serviceName)
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
bool untrackFile(File *pFile, bool destroy=true)
void trackFile(File *pFile)
Track a File object that exists. It is necessary to keep track of File objects, or at least those tha...
virtual bool setLargestTextMode()=0
bool activate(size_t n)
Starts the process of activating the given tty.
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
void pushBack(const T &value)
All zeroes = 'revert to text mode'.