The Pedigree Project  0.1
ConsolePhysical.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 "ConsoleDefines.h"
22 #include "modules/system/vfs/File.h"
23 #include "pedigree/kernel/processor/types.h"
24 #include "pedigree/kernel/utilities/Buffer.h"
25 #include "pedigree/kernel/utilities/String.h"
26 #include "pedigree/kernel/utilities/utility.h"
27 
28 class Filesystem;
29 
30 ConsolePhysicalFile::ConsolePhysicalFile(
31  size_t nth, File *pTerminal, String consoleName, Filesystem *pFs)
32  : ConsoleFile(~0U, consoleName, pFs), m_pTerminal(pTerminal),
33  m_ProcessedInput(PTY_BUFFER_SIZE), m_TerminalNumber(nth)
34 {
35 }
36 
38  uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock)
39 {
40  // read from terminal and perform line discipline as needed
41  // we loop because we need to perform line discipline even though a
42  // terminal might give us input a byte a time (e.g. cooked mode won't have
43  // real input to return until we've done line discipline for every
44  // character including the carriage return)
45  while (true)
46  {
47  if (!m_ProcessedInput.canRead(false))
48  {
49  char *temp = new char[size];
50  size_t nRead = m_pTerminal->read(
51  location, size, reinterpret_cast<uintptr_t>(temp), bCanBlock);
52 
53  if (nRead)
54  {
55  inputLineDiscipline(temp, nRead, m_Flags, m_ControlChars);
56  }
57  delete[] temp;
58  }
59 
60  // handle any bytes that the input discipline created
61  while (m_Buffer.canRead(false))
62  {
63  char *buff = new char[512];
64  size_t nTransfer = m_Buffer.read(buff, 512);
65  write(0, nTransfer, reinterpret_cast<uintptr_t>(buff), true);
66  delete[] buff;
67  }
68 
69  // and then return the processed content to the caller when ready
70  if (m_ProcessedInput.canRead(false))
71  {
72  return m_ProcessedInput.read(
73  reinterpret_cast<char *>(buffer), size, bCanBlock);
74  }
75  else if (!bCanBlock)
76  {
77  return 0;
78  }
79  }
80 }
81 
83  uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock)
84 {
85  // we allocate a buffer to allow for a input buffer exclusively filled with
86  // NL characters to be converted to CRNL
87  char *outputBuffer = new char[size * 2];
88  ByteSet(outputBuffer, 0, size * 2);
89  StringCopyN(outputBuffer, reinterpret_cast<char *>(buffer), size);
90  size_t disciplineSize =
91  outputLineDiscipline(outputBuffer, size, size * 2, m_Flags);
95  m_pTerminal->write(
96  location, disciplineSize, reinterpret_cast<uintptr_t>(outputBuffer),
97  bCanBlock);
98  delete[] outputBuffer;
99  return size;
100 }
101 
102 void ConsolePhysicalFile::performInject(char *buf, size_t len, bool canBlock)
103 {
104  m_ProcessedInput.write(buf, len, canBlock);
105  dataChanged();
106 }
107 
108 int ConsolePhysicalFile::select(bool bWriting, int timeout)
109 {
110  // if we're writing, we only care about the attached terminal
111  if (bWriting)
112  {
113  return m_pTerminal->select(true, timeout);
114  }
115 
116  // if we're reading, though, we might be able to return quickly
117  if (m_ProcessedInput.canRead(false))
118  {
119  return 1;
120  }
121 
122  // or maybe not
123  return m_pTerminal->select(false, timeout);
124 }
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
static size_t outputLineDiscipline(char *buf, size_t len, size_t maxSz, size_t flags=0)
Output line discipline.
bool canRead(bool block)
Definition: Buffer.cc:437
size_t read(T *buffer, size_t count, bool block=true)
Definition: Buffer.cc:236
Definition: String.h:49
virtual int select(bool bWriting, int timeout)
select - check and optionally for a particular state.
void dataChanged()
Definition: File.cc:654
void inputLineDiscipline(char *buf, size_t len, size_t flags=~0U, const char *controlChars=0)
Input line discipline.
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual void performInject(char *buf, size_t len, bool canBlock)
Definition: File.h:66
virtual uint64_t write(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
Definition: File.cc:183