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 virtual size_t readableBytes(ConsoleIoState& state);
100 ReadinessGenerations epochGenerations(const SharedPointer<ConsoleIoState>& epoch);
102 void setControlState(const SharedPointer<ConsoleControlState>& state);
103
104 virtual bool isMaster() = 0;
105 bool isCharacterDevice() const override {
106 return true;
107 }
108 bool isConsole() const override {
109 return true;
110 }
111
112 bool isPtySlave() {
113 return !isMaster() && getParent() != nullptr;
114 }
115
116 bool isPtyMaster() {
117 return isMaster() && m_pOther != nullptr && m_pOther->getParent() != nullptr;
118 }
119
120 virtual bool isSeekable() const {
121 return false;
122 }
123
124 ReadyMask queryReady(bool reading, bool writing) override;
125 ReadinessGenerations readinessGenerations() override;
126
127 bool supportsReadinessNotifications() const override {
128 return true;
129 }
130
132 void getControlCharacters(char* out) {
133 MemoryCopy(out, m_ControlChars, MAX_CONTROL_CHAR);
134 }
135
136 virtual size_t getBlockSize() const {
137 return PTY_BUFFER_SIZE;
138 }
139
140 size_t getConsoleNumber() const {
141 return m_ConsoleNumber;
142 }
143
144 virtual size_t getPhysicalConsoleNumber() const {
145 return ~0U;
146 }
147
148 protected:
150 virtual int select(bool bWriting, int timeout);
151
152 virtual uint64_t readIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
153 bool canBlock) = 0;
154 virtual uint64_t writeIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
155 bool canBlock) = 0;
156 void changed();
157 ConsoleFile* stateOwner();
158
161
162 size_t m_Flags;
163 char m_ControlChars[MAX_CONTROL_CHAR];
164
165 unsigned short m_Rows;
166 unsigned short m_Cols;
167
169 static size_t outputLineDiscipline(char* buf, size_t len, size_t maxSz, size_t flags = 0);
170
172 size_t processInput(char* buf, size_t len);
173
175 size_t inputLineDiscipline(ConsoleIoState& state, char* buf, size_t len, bool canBlock,
176 size_t flags = ~0U, const char* controlChars = nullptr);
177
178 mutable Mutex m_IoLock;
179 ConditionVariable m_IoChanged;
180 bool m_HangingUp;
183
184 private:
185 size_t m_ConsoleNumber;
186 String m_ConsoleName;
187
188 bool isControlCharacter(size_t flags, char check, const char* controlChars);
189 void notifyControlCharacter(char cause, const char* controlChars);
190
191 virtual bool isBytewise() const {
192 return true;
193 }
194};
195
196class EXPORTED_PUBLIC ConsoleMasterFile : public ConsoleFile {
197 public:
198 ConsoleMasterFile(size_t consoleNumber, String consoleName, Filesystem* pFs);
199 virtual ~ConsoleMasterFile() {}
200
201 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
202 bool bCanBlock = true);
203 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
204 bool bCanBlock = true);
205
206 void setOther(ConsoleFile* pOther) {
207 m_pOther = pOther;
208 m_Flags = pOther->m_Flags;
209 }
210
213
217
220
221 virtual bool isMaster() {
222 return true;
223 }
224
225 private:
226 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
227 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
228};
229
230class EXPORTED_PUBLIC ConsoleSlaveFile : public ConsoleFile {
231 public:
232 ConsoleSlaveFile(size_t consoleNumber, String consoleName, Filesystem* pFs);
233 ConsoleSlaveFile(size_t consoleNumber, String consoleName, Filesystem* pFs, File* pParent);
234 virtual ~ConsoleSlaveFile() {}
235
236 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
237 bool bCanBlock = true);
238 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
239 bool bCanBlock = true);
240
241 void setOther(ConsoleFile* pOther) {
242 m_pOther = pOther;
243 }
244
245 virtual bool isMaster() {
246 return false;
247 }
248
249 private:
250 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
251 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
252};
253
254class EXPORTED_PUBLIC ConsolePhysicalFile : public ConsoleFile {
255 public:
256 ConsolePhysicalFile(size_t nth, File* pTerminal, String consoleName, Filesystem* pFs);
257 virtual ~ConsolePhysicalFile() {}
258
259 virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
260 bool bCanBlock = true);
261 virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
262 bool bCanBlock = true);
263
264 virtual bool isMaster() {
265 return false;
266 }
267
268 virtual size_t getPhysicalConsoleNumber() const {
269 return m_TerminalNumber;
270 }
271
272 virtual int select(bool bWriting, int timeout);
273
274 ReadyMask queryReady(bool reading, bool writing) override {
275 return File::queryReady(reading, writing);
276 }
277
278 bool supportsReadinessNotifications() const override {
279 return true;
280 }
281
282 void terminalReadinessChanged(ReadyMask mask);
283 size_t readableBytes(ConsoleIoState& state) override;
284
285 private:
286 File* m_pTerminal;
287 size_t m_TerminalNumber;
288 SharedPointer<ReadinessObserver> m_TerminalReadinessObserver;
289 ReadinessSubscription m_TerminalReadinessSubscription;
290
291 void collectInput(ConsoleIoState& state, bool canBlock);
292 uint64_t readIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
293 uint64_t writeIo(ConsoleIoState&, uint64_t, uintptr_t, bool) override;
294};
295
307class EXPORTED_PUBLIC ConsoleManager : public Filesystem {
308 public:
309 enum IAttribute { IMapCRToNL = 1, IIgnoreCR = 2, IMapNLToCR = 4, IStripToSevenBits = 8 };
310 enum OAttribute {
311 OPostProcess = 16,
312 OMapCRToNL = 32,
313 ONoCrAtCol0 = 64,
314 OMapNLToCRNL = 128,
315 ONLCausesCR = 256
316 };
317 enum LAttribute {
318 LEcho = 512,
319 LEchoErase = 1024,
320 LEchoKill = 2048,
321 LEchoNewline = 4096,
322 LCookedMode = 8192,
323 LGenerateEvent = 16384
324 };
325
327
328 virtual ~ConsoleManager();
329
330 static ConsoleManager& instance();
331
332 //
333 // ConsoleManager interface.
334 //
335 File* getConsole(String consoleName);
336 ConsoleFile* getConsoleFile(RequestQueue* pBackend);
337
340 bool lockConsole(File* file);
341
343 void unlockConsole(File* file);
344
346 bool setPtyLock(File* file, bool locked);
347
349 bool isPtySlaveLocked(File* file);
350
353 void newConsole(char c, size_t i);
354
355 bool isConsole(File* file);
356 bool isMasterConsole(File* file);
357
358 void setAttributes(File* file, size_t flags);
359 void getAttributes(File* file, size_t* flags);
360 void getControlChars(File* file, void* p);
361 void setControlChars(File* file, void* p);
362 int getWindowSize(File* file, unsigned short* rows, unsigned short* cols);
363 int setWindowSize(File* file, unsigned short rows, unsigned short cols);
364 bool hasDataAvailable(File* file);
365 void flush(File* file);
366
367 File* getOther(File* file);
368
369 //
370 // Filesystem interface.
371 //
372
373 virtual bool initialise(Disk* pDisk) {
374 return false;
375 }
376 virtual File* getRoot() const {
377 return 0;
378 }
379 virtual const String& getVolumeLabel() const {
380 static String volumeLabel("consolemanager");
381 return volumeLabel;
382 }
383
384 protected:
385 virtual bool createFile(File* parent, const String& filename, uint32_t mask) {
386 return false;
387 }
388 virtual bool createDirectory(File* parent, const String& filename, uint32_t mask) {
389 return false;
390 }
391 virtual bool createSymlink(File* parent, const String& filename, const String& value) {
392 return false;
393 }
394 virtual bool removeNode(File*, const String&, File*) {
395 return false;
396 }
397
398 private:
399 Vector<ConsoleFile*> m_Consoles;
400 static ConsoleManager m_Instance;
401 Spinlock m_Lock;
402
403 void newConsole(char c, size_t i, bool lock);
404};
405
406#endif
ConsoleFile * m_pOther
Other side of the console.
Definition Console.h:160
bool supportsReadinessNotifications() const override
Definition Console.h:127
void getControlCharacters(char *out)
Grabs the current array of control characters.
Definition Console.h:132
virtual bool isSeekable() const
Definition Console.h:120
virtual size_t getBlockSize() const
Definition Console.h:136
virtual bool isBytewise() const
Definition Console.h:191
virtual bool removeNode(File *, const String &, File *)
Definition Console.h:394
virtual const String & getVolumeLabel() const
Definition Console.h:379
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
Definition Console.h:385
virtual File * getRoot() const
Definition Console.h:376
virtual bool initialise(Disk *pDisk)
Definition Console.h:373
virtual bool createSymlink(File *parent, const String &filename, const String &value)
Definition Console.h:391
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
Definition Console.h:388
bool bLocked
Is this master locked (ie, already opened)?
Definition Console.h:212
bool bSlaveLocked
Whether the corresponding UNIX 98 slave rejects new opens.
Definition Console.h:219
Process * pLocker
Definition Console.h:216
ReadyMask queryReady(bool reading, bool writing) override
Definition Console.h:274
bool supportsReadinessNotifications() const override
Definition Console.h:278
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