The Pedigree Project 0.1
ConsoleMaster.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 "pedigree/kernel/processor/types.h"
21#include "pedigree/kernel/utilities/Buffer.h"
22#include "pedigree/kernel/utilities/String.h"
23
24#include "Console.h"
25
26class Filesystem;
27
28ConsoleMasterFile::ConsoleMasterFile(size_t consoleNumber, String consoleName, Filesystem* pFs)
29 : ConsoleFile(consoleNumber, consoleName, pFs),
30 bLocked(false),
31 pLocker(0),
32 bSlaveLocked(false) {}
33
34uint64_t ConsoleMasterFile::readIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
35 bool bCanBlock) {
36 // Check for NL->CRNL conversion which requires special logic.
37 size_t slaveFlags = m_pOther->m_Flags;
38 if (!(slaveFlags & ConsoleManager::OPostProcess) ||
39 !(slaveFlags & ConsoleManager::OMapNLToCRNL)) {
40 // Easy read/write - output line discipline will not need to do any
41 // conversions that involve expansion.
42 uint64_t nBytes = state.output.read(reinterpret_cast<char*>(buffer), size, bCanBlock);
43 if (!nBytes) {
44 return 0;
45 }
46
48 if (m_pOther) {
50 }
51
52 return outputLineDiscipline(reinterpret_cast<char*>(buffer), nBytes, size, m_pOther->m_Flags);
53 }
54
55 uint64_t totalBytes = 0;
56 while (totalBytes < size) {
57 // We assume that the worst-case buffer might be read, which contains
58 // 100% newlines that would expand to carriage return + newline.
59 // Once one byte remains, consume it directly; the line discipline keeps
60 // the result bounded by the caller's buffer in that case.
61 const uint64_t readSize = size > 1 ? size / 2 : 1;
62 uint64_t nBytes =
63 state.output.read(reinterpret_cast<char*>(buffer + totalBytes), readSize, bCanBlock);
64 if (!nBytes) {
65 break;
66 }
67
68 // Perform line discipline using the full, unhalved size so we can
69 // expand all available newlines.
70 size_t disciplineSize = outputLineDiscipline(reinterpret_cast<char*>(buffer + totalBytes),
71 nBytes, size, m_pOther->m_Flags);
72 totalBytes += disciplineSize;
73 size -= disciplineSize;
74
75 // After the first iteration, disallow any further blocking so we read
76 // the remainder of the buffer then terminate quickly.
77 bCanBlock = false;
78 }
79
80 if (totalBytes) {
82 if (m_pOther) {
84 }
85 }
86
87 return totalBytes;
88}
89
90uint64_t ConsoleMasterFile::writeIo(ConsoleIoState& state, uint64_t size, uintptr_t buffer,
91 bool bCanBlock) {
92 if (!state.input.canWrite(bCanBlock)) {
93 return 0;
94 }
95
96 // Pass on to the input discipline, which will write to the slave.
97 size_t amount = inputLineDiscipline(state, reinterpret_cast<char*>(buffer), size, bCanBlock);
98
99 return state.revoked() ? 0 : amount;
100}
101
102uint64_t ConsoleMasterFile::readBytewise(uint64_t, uint64_t size, uintptr_t buffer, bool canBlock) {
103 return readEpoch(captureOpenEpoch(), size, buffer, canBlock);
104}
105
106uint64_t ConsoleMasterFile::writeBytewise(uint64_t, uint64_t size, uintptr_t buffer,
107 bool canBlock) {
108 return writeEpoch(captureOpenEpoch(), size, buffer, canBlock);
109}
bool canWrite(bool block)
Definition Buffer.cc:491
size_t read(T *buffer, size_t count, bool block=true)
Definition Buffer.cc:296
ConsoleFile * m_pOther
Other side of the console.
Definition Console.h:160
static size_t outputLineDiscipline(char *buf, size_t len, size_t maxSz, size_t flags=0)
Output line discipline.
size_t inputLineDiscipline(ConsoleIoState &state, char *buf, size_t len, bool canBlock, size_t flags=~0U, const char *controlChars=nullptr)
Input line discipline.
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)
void dataChanged()
Definition File.cc:1452