Ver código fonte

neercs: spawn a shell and read what it tries to print.

master
Sam Hocevar 12 anos atrás
pai
commit
929af5c5e0
8 arquivos alterados com 1319 adições e 10 exclusões
  1. +2
    -2
      neercs/Makefile.am
  2. +1
    -0
      neercs/neercs.vcxproj
  3. +3
    -0
      neercs/neercs.vcxproj.filters
  4. +1143
    -0
      neercs/term/ansi.cpp
  5. +48
    -4
      neercs/term/pty.cpp
  6. +3
    -2
      neercs/term/pty.h
  7. +21
    -2
      neercs/term/term.cpp
  8. +98
    -0
      neercs/term/term.h

+ 2
- 2
neercs/Makefile.am Ver arquivo

@@ -8,8 +8,8 @@ neercs_SOURCES = \
\
$(old_sources) \
\
term/term.cpp term/term.h \
term/pty.cpp term/pty.h \
term/term.h term/term.cpp term/ansi.cpp \
term/pty.h term/pty.cpp \
\
video/render.cpp video/render.h \
video/text-render.cpp video/text-render.h \


+ 1
- 0
neercs/neercs.vcxproj Ver arquivo

@@ -70,6 +70,7 @@
<ClCompile Include="old\server.c" />
<ClCompile Include="old\widgets.c" />
<ClCompile Include="old\wm.cpp" />
<ClInclude Include="term\ansi.cpp" />
<ClInclude Include="term\pty.cpp" />
<ClInclude Include="term\term.cpp" />
<ClCompile Include="video\render.cpp" />


+ 3
- 0
neercs/neercs.vcxproj.filters Ver arquivo

@@ -74,6 +74,9 @@
<ClCompile Include="old\python\py_module.c">
<Filter>old\python</Filter>
</ClCompile>
<ClCompile Include="term\ansi.cpp">
<Filter>term</Filter>
</ClCompile>
<ClCompile Include="term\pty.cpp">
<Filter>term</Filter>
</ClCompile>


+ 1143
- 0
neercs/term/ansi.cpp
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 48
- 4
neercs/term/pty.cpp Ver arquivo

@@ -42,14 +42,19 @@ using namespace lol;
#include "neercs.h"

Pty::Pty(ivec2 size)
: m_size(size)
: m_fd(-1),
m_pid(-1),
m_size(size)
{
;
}

Pty::~Pty()
{

if (m_fd >= 0)
{
close((int)m_fd);
}
}

void Pty::Run(char const *command)
@@ -58,8 +63,8 @@ void Pty::Run(char const *command)
int fd;
pid_t pid;

m_pid = 0;
m_fd = 0;
m_pid = -1;
m_fd = -1;

pid = forkpty(&fd, NULL, NULL, NULL);
if (pid < 0)
@@ -94,6 +99,45 @@ void Pty::Run(char const *command)
#endif
}

size_t Pty::ReadData(char *data, size_t maxlen)
{
fd_set fdset;
int maxfd = -1;

FD_ZERO(&fdset);
if (m_fd >= 0)
{
FD_SET((int)m_fd, &fdset);
maxfd = std::max(maxfd, (int)m_fd);
}

if (maxfd >= 0)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 50000;
int ret = select(maxfd + 1, &fdset, NULL, NULL, &tv);

if (ret < 0)
{
Log::Error("cannot read from PTY\n");
return 0;
}

if (ret)
{
if (FD_ISSET((int)m_fd, &fdset))
{
ssize_t nr = read((int)m_fd, data, maxlen);
if (nr >= 0)
return nr;
}
}
}

return 0;
}

void Pty::SetWindowSize(ivec2 size)
{
#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H


+ 3
- 2
neercs/term/pty.h Ver arquivo

@@ -12,11 +12,12 @@ public:
~Pty();

void Run(char const *command);
size_t ReadData(char *data, size_t maxlen);
void SetWindowSize(ivec2 size);

private:
uint64_t m_fd;
uint64_t m_pid;
int64_t m_fd;
int64_t m_pid;
char const *m_argv[2];
ivec2 m_size;
};


+ 21
- 2
neercs/term/term.cpp Ver arquivo

@@ -7,7 +7,6 @@
#endif

#include "core.h"
#include "lolgl.h"

using namespace std;
using namespace lol;
@@ -19,6 +18,14 @@ Term::Term(ivec2 size)
: m_time(0.f)
{
m_caca = caca_create_canvas(size.x, size.y);

#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H
m_pty = new Pty(size);
char const *shell = getenv("SHELL");
if (!shell)
shell = "/bin/sh";
m_pty->Run(shell);
#endif
}

void Term::TickGame(float seconds)
@@ -29,7 +36,15 @@ void Term::TickGame(float seconds)
/* This is the real terminal code */
/* XXX: for now we draw fancy shit */
m_time += seconds;
DrawFancyShit();

for (;;)
{
char buf[BUFSIZ];
size_t bytes = m_pty->ReadData(buf, BUFSIZ);
if (bytes <= 0)
break;
ReadAnsi(buf, bytes);
}
#else
/* Unsupported platform - draw some fancy shit instead */
m_time += seconds;
@@ -44,6 +59,10 @@ void Term::TickDraw(float seconds)

Term::~Term()
{
#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H
delete m_pty;
#endif
caca_free_canvas(m_caca);
}

/*


+ 98
- 0
neercs/term/term.h Ver arquivo

@@ -7,6 +7,80 @@

#include "term/pty.h"

struct Iso2022Conversion
{
Iso2022Conversion() { Reset(); }
void Reset();

/* cs = coding system/coding method: */
/* (with standard return) */
/* '@' = ISO-2022, */
/* 'G' = UTF-8 without implementation level, */
/* '8' = UTF-8 (Linux console and imitators), */
/* and many others that are rarely used; */
/* (without standard return) */
/* '/G' = UTF-8 Level 1, */
/* '/H' = UTF-8 Level 2, */
/* '/I' = UTF-8 Level 3, */
/* and many others that are rarely used */
uint32_t cs;
/* ctrl8bit = allow 8-bit controls */
uint8_t ctrl8bit;
/* cn[0] = C0 control charset (0x00 ... 0x1f):
* '@' = ISO 646,
* '~' = empty,
* and many others that are rarely used */
/* cn[1] = C1 control charset (0x80 ... 0x9f):
* 'C' = ISO 6429-1983,
* '~' = empty,
* and many others that are rarely used */
uint32_t cn[2];
/* glr[0] = GL graphic charset (94-char. 0x21 ... 0x7e,
* 94x94-char. 0x21/0x21 ... 0x7e/0x7e),
* and
* glr[1] = GR graphic charset (94-char. 0xa1 ... 0xfe,
* 96-char. 0xa0 ... 0xff,
* 94x94-char. 0xa1/0xa1 ... 0xfe/0xfe,
* 96x96-char. 0xa0/0xa0 ... 0xff/0xff):
* 0 = G0, 1 = G1, 2 = G2, 3 = G3 */
uint8_t glr[2];
/* gn[i] = G0/G1/G2/G3 graphic charset state:
* (94-char. sets)
* '0' = DEC ACS (VT100 and imitators),
* 'B' = US-ASCII,
* and many others that are rarely used for e.g. various national ASCII variations;
* (96-char. sets)
* '.A' = ISO 8859-1 "Latin 1" GR,
* '.~' = empty 96-char. set,
* and many others that are rarely used for e.g. ISO 8859-n GR;
* (double-byte 94x94-charsets)
* '$@' = Japanese Character Set ("old JIS") (JIS C 6226:1978),
* '$A' = Chinese Character Set (GB 2312),
* '$B' = Japanese Character Set (JIS X0208/JIS C 6226:1983),
* '$C' = Korean Graphic Character Set (KSC 5601:1987),
* '$D' = Supplementary Japanese Graphic Character Set (JIS X0212),
* '$E' = CCITT Chinese Set (GB 2312 + GB 8565),
* '$G' = CNS 11643 plane 1,
* '$H' = CNS 11643 plane 2,
* '$I' = CNS 11643 plane 3,
* '$J' = CNS 11643 plane 4,
* '$K' = CNS 11643 plane 5,
* '$L' = CNS 11643 plane 6,
* '$M' = CNS 11643 plane 7,
* '$O' = JIS X 0213 plane 1,
* '$P' = JIS X 0213 plane 2,
* '$Q' = JIS X 0213-2004 Plane 1,
* and many others that are rarely used for e.g. traditional
* ideographic Vietnamese and BlissSymbolics;
* (double-byte 96x96-charsets)
* none standardized or in use on terminals AFAIK (Mule does use
* some internally)
*/
uint32_t gn[4];
/* ss = single-shift state: 0 = GL, 2 = G2, 3 = G3 */
uint8_t ss;
};

class Term : public Entity
{
public:
@@ -20,11 +94,35 @@ protected:
virtual void TickGame(float seconds);
virtual void TickDraw(float seconds);

private:
/* Terminal emulation main entry point */
size_t ReadAnsi(void const *data, size_t size);
size_t SendAnsi(char const *str);

/* Utility functions for terminal emulation */
void ReadGrcm(unsigned int argc, unsigned int const *argv);
inline int ReadChar(unsigned char c, int *x, int *y);
inline int ReadDuplet(unsigned char const *buffer, unsigned int *skip,
int top, int bottom, int width, int height);

private:
Pty *m_pty;
caca_canvas_t *m_caca;
ivec2 m_size;

/* Terminal attributes */
char *m_title;

int m_bell, m_init, m_report_mouse;
int m_changed; /* content was updated */
Iso2022Conversion m_conv_state; /* charset mess */

uint8_t m_fg, m_bg; /* ANSI-context fg/bg */
uint8_t m_dfg, m_dbg; /* Default fg/bg */
uint8_t m_bold, m_blink, m_italics, m_negative, m_concealed, m_underline;
uint8_t m_faint, m_strike, m_proportional; /* unsupported */
uint32_t m_clearattr;

/* Mostly for fancy shit */
void DrawFancyShit();
float m_time;


Carregando…
Cancelar
Salvar