The Pedigree Project 0.1
Console.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 CONSOLE_H
21#define CONSOLE_H
22
23#include "pedigree/kernel/Spinlock.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/process/ConditionVariable.h"
26#include "pedigree/kernel/process/Mutex.h"
27#include "pedigree/kernel/process/OperationBarrier.h"
28#include "pedigree/kernel/process/Semaphore.h"
29#include "pedigree/kernel/processor/types.h"
30#include "pedigree/kernel/utilities/Buffer.h"
31#include "pedigree/kernel/utilities/SharedPointer.h"
32#include "pedigree/kernel/utilities/String.h"
33#include "pedigree/kernel/utilities/Vector.h"
34#include "pedigree/kernel/utilities/utility.h"
35
36#include "ConsoleDefines.h"
37#include "modules/system/vfs/File.h"
38#include "modules/system/vfs/Filesystem.h"
39
40class Disk;
41class Process;
42class RequestQueue;
43
44#define DEFAULT_FLAGS \
45 (static_cast<size_t>(ConsoleManager::OPostProcess) | \
46 static_cast<size_t>(ConsoleManager::IMapCRToNL) | \
47 static_cast<size_t>(ConsoleManager::OMapNLToCRNL) | \
48 static_cast<size_t>(ConsoleManager::LEcho) | static_cast<size_t>(ConsoleManager::LEchoErase) | \
49 static_cast<size_t>(ConsoleManager::LEchoKill) | \
50 static_cast<size_t>(ConsoleManager::LCookedMode) | \
51 static_cast<size_t>(ConsoleManager::LGenerateEvent))
52
53class EXPORTED_PUBLIC ConsoleControlState {
54 public:
55 enum class Character { Interrupt, Quit, Suspend };
56 virtual ~ConsoleControlState() = default;
57 virtual void controlCharacter(Character) {}
58};
59
60class EXPORTED_PUBLIC ConsoleIoState {
61 public:
64 bool revoked() const;
65 void closeAdmission();
66 void cancelAndDrain();
67 OperationBarrier operations;
68 Buffer<char> input;
69 Buffer<char> output;
70 Mutex inputLock;
71 char line[LINEBUFFER_MAXIMUM];
72 size_t lineSize;
73 size_t firstNewline;
74 Semaphore physicalWake;
75
76 private:
77 bool m_Revoked;
78};
79
80class EXPORTED_PUBLIC ConsoleFile : public File {
81 friend class ConsoleMasterFile;
82 friend class ConsoleSlaveFile;
83 friend class ConsoleManager;
84
85 public:
86 ConsoleFile(size_t consoleNumber, String consoleName, Filesystem* pFs);
87 ConsoleFile(size_t consoleNumber, String consoleName, Filesystem* pFs, File* pParent);
88 virtual ~ConsoleFile() {}
89
90 SharedPointer<ConsoleIoState> captureOpenEpoch(bool waitForReopen = true);
91 bool beginRevocation(SharedPointer<ConsoleIoState>& retired);
92 void finishRevocation(const SharedPointer<ConsoleIoState>& retired,
93 const SharedPointer<ConsoleIoState>& replacement);
94 uint64_t readEpoch(const SharedPointer<ConsoleIoState>& epoch, uint64_t size, uintptr_t buffer,
95 bool canBlock);
96 uint64_t writeEpoch(const SharedPointer<ConsoleIoState>& epoch, uint64_t size, uintptr_t buffer,
97 bool canBlock);
98 ReadyMask queryEpoch(const SharedPointer<ConsoleIoState>& epoch, bool reading, bool writing);
99 ReadinessGenerations epochGenerations(const SharedPointer<ConsoleIoState>& epoch);
101 void setControlState(const SharedPointer<ConsoleControlState>& state);
102
103 virtual bool isMaster() = 0;
104
105 bool isPtySlave() {
106 return !isMaster() && getParent() != nullptr;
107 }
108
109 bool isPtyMaster() {
110 return isMaster() && m_pOther != nullptr && m_pOther->getParent() != nullptr;
111 }
112
113 virtual bool isSeekable() const {
114 return false;
115 }
116
117 ReadyMask queryReady(bool reading, bool writing) override;
118 ReadinessGenerations readinessGenerations() override;
119
120 bool supportsReadinessNotifications() const override {
121 return true;
122 }
123
125 void getControlCharacters(char* out) {
126 MemoryCopy(out, m_ControlChars, MAX_CONTROL_CHAR);
127 }
128
129 virtual size_t getBlockSize() const {
130 return PTY_BUFFER_SIZE;
131 }
132
133 size_t getConsoleNumber() const {
134 return m_ConsoleNumber;
135 }
136
137 virtual size_t getPhysicalConsoleNumber() const {
138 return ~0U;
139 }
140
141 protected:
143 virtual int select(bool bWriting, int timeout);
144
145 virtual uint64_t readIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
146 bool canBlock) = 0;
147 virtual uint64_t writeIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
148 bool canBlock) = 0;
149 void changed();
150 ConsoleFile* stateOwner();
151
154
155 size_t m_Flags;
156 char m_ControlChars[MAX_CONTROL_CHAR];
157
158 unsigned short m_Rows;
159 unsigned short m_Cols;
160
162 static size_t outputLineDiscipline(char* buf, size_t len, size_t maxSz, size_t flags = 0);
163
165 size_t processInput(char* buf, size_t len);
166
168 size_t inputLineDiscipline(ConsoleIoState& state, char* buf, size_t len, bool canBlock,
169 size_t flags = ~0U, const char* controlChars = nullptr);
170
171 mutable Mutex m_IoLock;
172 ConditionVariable m_IoChanged;
173 bool m_HangingUp;
176
177 private:
178 size_t m_ConsoleNumber;
179 String m_ConsoleName;
180
181 bool isControlCharacter(size_t flags, char check, const char* controlChars);
182 void notifyControlCharacter(char cause, const char* controlChars);
183
184 virtual bool isBytewise() const {
185 return true;
186 }
187};
188
189class EXPORTED_PUBLIC ConsoleMasterFile : public ConsoleFile {
190 public:
191 ConsoleMasterFile(size_t consoleNumber, String consoleName, Filesystem* pFs);
192 virtual ~ConsoleMasterFile() {}
193
194 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
195 bool bCanBlock = true);
196 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
197 bool bCanBlock = true);
198
199 void setOther(ConsoleFile* pOther) {
200 m_pOther = pOther;
201 m_Flags = pOther->m_Flags;
202 }
203
206
210
213
214 virtual bool isMaster() {
215 return true;
216 }
217
218 private:
219 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
220 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
221};
222
223class EXPORTED_PUBLIC ConsoleSlaveFile : public ConsoleFile {
224 public:
225 ConsoleSlaveFile(size_t consoleNumber, String consoleName, Filesystem* pFs);
226 ConsoleSlaveFile(size_t consoleNumber, String consoleName, Filesystem* pFs, File* pParent);
227 virtual ~ConsoleSlaveFile() {}
228
229 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
230 bool bCanBlock = true);
231 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
232 bool bCanBlock = true);
233
234 void setOther(ConsoleFile* pOther) {
235 m_pOther = pOther;
236 }
237
238 virtual bool isMaster() {
239 return false;
240 }
241
242 private:
243 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
244 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
245};
246
247class EXPORTED_PUBLIC ConsolePhysicalFile : public ConsoleFile {
248 public:
249 ConsolePhysicalFile(size_t nth, File* pTerminal, String consoleName, Filesystem* pFs);
250 virtual ~ConsolePhysicalFile() {}
251
252 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
253 bool bCanBlock = true);
254 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
255 bool bCanBlock = true);
256
257 virtual bool isMaster() {
258 return false;
259 }
260
261 virtual size_t getPhysicalConsoleNumber() const {
262 return m_TerminalNumber;
263 }
264
265 virtual int select(bool bWriting, int timeout);
266
267 ReadyMask queryReady(bool reading, bool writing) override {
268 return File::queryReady(reading, writing);
269 }
270
271 bool supportsReadinessNotifications() const override {
272 return true;
273 }
274
275 void terminalReadinessChanged(ReadyMask mask);
276
277 private:
278 File* m_pTerminal;
279 size_t m_TerminalNumber;
280 SharedPointer<ReadinessObserver> m_TerminalReadinessObserver;
281 ReadinessSubscription m_TerminalReadinessSubscription;
282
283 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
284 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
285};
286
298class EXPORTED_PUBLIC ConsoleManager : public Filesystem {
299 public:
300 enum IAttribute { IMapCRToNL = 1, IIgnoreCR = 2, IMapNLToCR = 4, IStripToSevenBits = 8 };
301 enum OAttribute {
302 OPostProcess = 16,
303 OMapCRToNL = 32,
304 ONoCrAtCol0 = 64,
305 OMapNLToCRNL = 128,
306 ONLCausesCR = 256
307 };
308 enum LAttribute {
309 LEcho = 512,
310 LEchoErase = 1024,
311 LEchoKill = 2048,
312 LEchoNewline = 4096,
313 LCookedMode = 8192,
314 LGenerateEvent = 16384
315 };
316
318
319 virtual ~ConsoleManager();
320
321 static ConsoleManager& instance();
322
323 //
324 // ConsoleManager interface.
325 //
326 File* getConsole(String consoleName);
327 ConsoleFile* getConsoleFile(RequestQueue* pBackend);
328
331 bool lockConsole(File* file);
332
334 void unlockConsole(File* file);
335
337 bool setPtyLock(File* file, bool locked);
338
340 bool isPtySlaveLocked(File* file);
341
344 void newConsole(char c, size_t i);
345
346 bool isConsole(File* file);
347 bool isMasterConsole(File* file);
348
349 void setAttributes(File* file, size_t flags);
350 void getAttributes(File* file, size_t* flags);
351 void getControlChars(File* file, void* p);
352 void setControlChars(File* file, void* p);
353 int getWindowSize(File* file, unsigned short* rows, unsigned short* cols);
354 int setWindowSize(File* file, unsigned short rows, unsigned short cols);
355 bool hasDataAvailable(File* file);
356 void flush(File* file);
357
358 File* getOther(File* file);
359
360 //
361 // Filesystem interface.
362 //
363
364 virtual bool initialise(Disk* pDisk) {
365 return false;
366 }
367 virtual File* getRoot() const {
368 return 0;
369 }
370 virtual const String& getVolumeLabel() const {
371 static String volumeLabel("consolemanager");
372 return volumeLabel;
373 }
374
375 protected:
376 virtual bool createFile(File* parent, const String& filename, uint32_t mask) {
377 return false;
378 }
379 virtual bool createDirectory(File* parent, const String& filename, uint32_t mask) {
380 return false;
381 }
382 virtual bool createSymlink(File* parent, const String& filename, const String& value) {
383 return false;
384 }
385 virtual bool removeNode(File*, const String&, File*) {
386 return false;
387 }
388
389 private:
390 Vector<ConsoleFile*> m_Consoles;
391 static ConsoleManager m_Instance;
392 Spinlock m_Lock;
393
394 void newConsole(char c, size_t i, bool lock);
395};
396
397#endif
ConsoleFile * m_pOther
Other side of the console.
Definition Console.h:153
bool supportsReadinessNotifications() const override
Definition Console.h:120
void getControlCharacters(char *out)
Grabs the current array of control characters.
Definition Console.h:125
virtual bool isSeekable() const
Definition Console.h:113
virtual size_t getBlockSize() const
Definition Console.h:129
virtual bool isBytewise() const
Definition Console.h:184
virtual bool removeNode(File *, const String &, File *)
Definition Console.h:385
virtual const String & getVolumeLabel() const
Definition Console.h:370
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
Definition Console.h:376
virtual File * getRoot() const
Definition Console.h:367
virtual bool initialise(Disk *pDisk)
Definition Console.h:364
virtual bool createSymlink(File *parent, const String &filename, const String &value)
Definition Console.h:382
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
Definition Console.h:379
bool bLocked
Is this master locked (ie, already opened)?
Definition Console.h:205
bool bSlaveLocked
Whether the corresponding UNIX 98 slave rejects new opens.
Definition Console.h:212
Process * pLocker
Definition Console.h:209
ReadyMask queryReady(bool reading, bool writing) override
Definition Console.h:267
bool supportsReadinessNotifications() const override
Definition Console.h:271
Definition Disk.h:35
Definition File.h:75
virtual ReadyMask queryReady(bool reading, bool writing)
Definition File.cc:1054
Definition Mutex.h:56
A vector / dynamic array.
Definition Vector.h:33