The Pedigree Project 0.1
Console.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 "Console.h"
21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/process/Thread.h"
23#include "pedigree/kernel/processor/Processor.h"
24#include "pedigree/kernel/processor/ProcessorInformation.h"
25
26#include "modules/Module.h"
27
28class RequestQueue;
29
30ConsoleManager ConsoleManager::m_Instance;
31
32void ConsoleManager::newConsole(char c, size_t i) {
33 newConsole(c, i, true);
34}
35
36void ConsoleManager::newConsole(char c, size_t i, bool lock) {
37 char a = 'a' + (i % 10);
38 if (i <= 9)
39 a = '0' + i;
40
41 char master[] = {'p', 't', 'y', c, a, 0};
42 char slave[] = {'t', 't', 'y', c, a, 0};
43
44 String masterName(master), slaveName(slave);
45
46 ConsoleMasterFile* pMaster = new ConsoleMasterFile(i, masterName, this);
47 ConsoleSlaveFile* pSlave = new ConsoleSlaveFile(i, slaveName, this);
48
49 pMaster->setOther(pSlave);
50 pSlave->setOther(pMaster);
51
52 {
53 LockGuard<Spinlock> guard(m_Lock, lock);
54 m_Consoles.pushBack(pMaster);
55 m_Consoles.pushBack(pSlave);
56 }
57}
58
59ConsoleManager::ConsoleManager() : m_Consoles(), m_Lock() {
60 // Create all consoles, so we can look them up easily.
61 for (size_t i = 0; i < 16; ++i) {
62 for (char c = 'p'; c <= 'z'; ++c) {
63 newConsole(c, i, false);
64 }
65 for (char c = 'a'; c <= 'e'; ++c) {
66 newConsole(c, i, false);
67 }
68 }
69}
70
71ConsoleManager::~ConsoleManager() {
72 for (auto it : m_Consoles) {
73 delete it;
74 }
75}
76
77ConsoleManager& ConsoleManager::instance() {
78 return m_Instance;
79}
80
81File* ConsoleManager::getConsole(String consoleName) {
82 LockGuard<Spinlock> guard(m_Lock);
83 for (size_t i = 0; i < m_Consoles.count(); i++) {
84 ConsoleFile* pC = m_Consoles[i];
85 if (pC->m_ConsoleName == consoleName) {
86 return pC;
87 }
88 }
89 // Error - not found.
90 return 0;
91}
92
93ConsoleFile* ConsoleManager::getConsoleFile(RequestQueue* pBackend) {
94 return 0;
95}
96
98 LockGuard<Spinlock> guard(m_Lock);
99 if (!isConsole(file))
100 return false;
101
102 ConsoleMasterFile* pConsole = static_cast<ConsoleMasterFile*>(file);
103 if (!pConsole->isMaster())
104 return false;
105
106 if (pConsole->bLocked)
107 return false;
108
109 Process* pProcess = Processor::information().getCurrentThread()->getParent();
110 pConsole->bLocked = true;
111 pConsole->pLocker = pProcess;
112
113 return true;
114}
115
117 LockGuard<Spinlock> guard(m_Lock);
118 if (!isConsole(file))
119 return;
120
121 ConsoleMasterFile* pConsole = static_cast<ConsoleMasterFile*>(file);
122 if (!pConsole->isMaster())
123 return;
124
125 // Make sure we are the owner of the master.
126 // Forked children shouldn't be able to close() and steal a master pty.
127 Process* pProcess = Processor::information().getCurrentThread()->getParent();
128 if (pConsole->pLocker != pProcess)
129 return;
130 pConsole->bLocked = false;
131}
132
133bool ConsoleManager::setPtyLock(File* file, bool locked) {
134 LockGuard<Spinlock> guard(m_Lock);
135 if (!isConsole(file) || !isMasterConsole(file) || !static_cast<ConsoleFile*>(file)->isPtyMaster())
136 return false;
137
138 ConsoleMasterFile* pConsole = static_cast<ConsoleMasterFile*>(file);
139 pConsole->bSlaveLocked = locked;
140 return true;
141}
142
144 LockGuard<Spinlock> guard(m_Lock);
145 if (!isConsole(file) || !static_cast<ConsoleFile*>(file)->isPtySlave())
146 return false;
147
148 ConsoleFile* other = static_cast<ConsoleFile*>(file)->m_pOther;
149 if (!other || !other->isMaster())
150 return false;
151 return static_cast<ConsoleMasterFile*>(other)->bSlaveLocked;
152}
153
154bool ConsoleManager::isConsole(File* file) {
155 if (!file)
156 return false;
157 return (file->getInode() == 0xdeadbeef);
158}
159
160bool ConsoleManager::isMasterConsole(File* file) {
161 if (!isConsole(file))
162 return false;
163
164 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
165 return pFile->isMaster();
166}
167
168void ConsoleManager::setAttributes(File* file, size_t flags) {
169 // \todo Sanity checking of the flags.
170 if (!file)
171 return;
172 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
173 pFile->m_Flags = flags;
174}
175
176void ConsoleManager::getAttributes(File* file, size_t* flags) {
177 if (!file || !flags)
178 return;
179 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
180 *flags = pFile->m_Flags;
181}
182
183void ConsoleManager::setControlChars(File* file, void* p) {
184 if (!file || !p)
185 return;
186 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
187 MemoryCopy(pFile->m_ControlChars, p, MAX_CONTROL_CHAR);
188}
189
190void ConsoleManager::getControlChars(File* file, void* p) {
191 if (!file || !p)
192 return;
193 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
194 MemoryCopy(p, pFile->m_ControlChars, MAX_CONTROL_CHAR);
195}
196
197int ConsoleManager::getWindowSize(File* file, unsigned short* rows, unsigned short* cols) {
198 if (!file)
199 return -1;
200 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
201 if (!pFile->isMaster()) {
202 if (pFile->m_pOther) {
203 pFile = pFile->m_pOther;
204 }
205 }
206
207 *rows = pFile->m_Rows;
208 *cols = pFile->m_Cols;
209 return 0;
210}
211
212int ConsoleManager::setWindowSize(File* file, unsigned short rows, unsigned short cols) {
213 if (!file)
214 return false;
215 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
216 if ((!pFile->isMaster()) && pFile->m_pOther) {
217 // Ignore. Slave cannot change window size.
218 return 0;
219 }
220 pFile->m_Rows = rows;
221 pFile->m_Cols = cols;
222 return 0;
223}
224
225bool ConsoleManager::hasDataAvailable(File* file) {
226 if (!file)
227 return false;
228 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
229 return pFile->select(false, 0);
230}
231
232void ConsoleManager::flush(File* file) {}
233
234File* ConsoleManager::getOther(File* file) {
235 if (!file)
236 return 0;
237 ConsoleFile* pFile = reinterpret_cast<ConsoleFile*>(file);
238 if (!pFile->m_pOther) {
239 return file; // some consoles (e.g. physical) don't have others
240 }
241 return pFile->m_pOther;
242}
243
244static bool initConsole() {
245 return true;
246}
247
248static void destroyConsole() {}
249
250MODULE_INFO("console", &initConsole, &destroyConsole, "vfs");
ConsoleFile * m_pOther
Other side of the console.
Definition Console.h:153
virtual int select(bool bWriting, int timeout)
select - check and optionally for a particular state.
bool lockConsole(File *file)
Definition Console.cc:97
bool setPtyLock(File *file, bool locked)
Set the UNIX 98 PTY slave lock associated with a master.
Definition Console.cc:133
void unlockConsole(File *file)
Release a console master locked as above.
Definition Console.cc:116
bool isPtySlaveLocked(File *file)
Returns whether a PTY slave is currently locked.
Definition Console.cc:143
void newConsole(char c, size_t i)
Definition Console.cc:32
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
Definition File.h:74
Process * getParent()
Definition Process.h:567
static ProcessorInformation & information()
void pushBack(const T &value)
Definition Vector.h:275
size_t count() const
Definition Vector.h:270