summaryrefslogtreecommitdiff
path: root/ucoolib
diff options
context:
space:
mode:
authorNicolas Schodet2013-03-02 23:25:00 +0100
committerNicolas Schodet2019-10-07 00:01:14 +0200
commit225b02a03f40dbb3e348d54f64dd9f1aea0d7a2b (patch)
tree7f586eb03a652d2f520235ab9b8ff83ad48ccee7 /ucoolib
parentb6c88d52a54e5d66aa714b8b34d41e49a3a34c8c (diff)
ucoolib/arch/host: add pty host stream
Diffstat (limited to 'ucoolib')
-rw-r--r--ucoolib/arch/host/Module1
-rw-r--r--ucoolib/arch/host/host_stream.hh2
-rw-r--r--ucoolib/arch/host/host_stream.host.cc45
3 files changed, 47 insertions, 1 deletions
diff --git a/ucoolib/arch/host/Module b/ucoolib/arch/host/Module
index 6c5a9fa..2c7fead 100644
--- a/ucoolib/arch/host/Module
+++ b/ucoolib/arch/host/Module
@@ -1 +1,2 @@
arch_host_SOURCES := host.host.cc host_stream.host.cc
+host_LIBS += -lutil
diff --git a/ucoolib/arch/host/host_stream.hh b/ucoolib/arch/host/host_stream.hh
index 5351225..9739e6b 100644
--- a/ucoolib/arch/host/host_stream.hh
+++ b/ucoolib/arch/host/host_stream.hh
@@ -32,6 +32,8 @@ class HostStream : public Stream
public:
/// Default constructor, use stdin/stdout.
HostStream ();
+ /// PTY constructor, will make a link to PTY at the given name.
+ HostStream (const char *name);
/// Close if needed.
~HostStream ();
/// See Stream::block.
diff --git a/ucoolib/arch/host/host_stream.host.cc b/ucoolib/arch/host/host_stream.host.cc
index 6bf5f8b..3b99a42 100644
--- a/ucoolib/arch/host/host_stream.host.cc
+++ b/ucoolib/arch/host/host_stream.host.cc
@@ -25,24 +25,67 @@
#include "ucoolib/common.hh"
+#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
+#include <pty.h>
#include <fcntl.h>
#include <errno.h>
namespace ucoo {
+/// Setup non canonical mode.
+static void
+setup_raw (int fd)
+{
+ struct termios tc;
+ tcgetattr (fd, &tc);
+ tc.c_iflag &= ~(IGNPAR | PARMRK | ISTRIP | IGNBRK | BRKINT | IGNCR |
+ ICRNL | INLCR | IXON | IXOFF | IXANY | IMAXBEL);
+ tc.c_iflag |= INPCK;
+ tc.c_oflag &= ~(OPOST);
+ tc.c_cflag &= ~(HUPCL | CSTOPB | PARENB | PARODD | CSIZE);
+ tc.c_cflag |= CS8 | CLOCAL | CREAD;
+ tc.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN | NOFLSH | TOSTOP);
+ tc.c_cc[VTIME] = 0;
+ tc.c_cc[VMIN] = 1;
+ tcflush (fd, TCIFLUSH);
+ tcsetattr (fd, TCSANOW, &tc);
+}
+
HostStream::HostStream ()
: fdi_ (0), fdo_ (1)
{
}
+HostStream::HostStream (const char *name)
+ : fdi_ (-1), fdo_ (-1)
+{
+ int fd, slave_fd, r;
+ // Open and unlock pt.
+ if (openpty (&fd, &slave_fd, 0, 0, 0) == -1
+ || grantpt (fd) == -1
+ || unlockpt (fd) == -1)
+ halt_perror ();
+ // Make a link to the slave pts.
+ unlink (name);
+ const char *slave_name = ptsname (fd);
+ assert (slave_name);
+ r = symlink (slave_name, name);
+ assert_perror (r != -1);
+ // Make slave raw.
+ setup_raw (slave_fd);
+ // Use as both in and out.
+ fdi_ = fdo_ = fd;
+ // slave_fd is left open.
+}
+
HostStream::~HostStream ()
{
if (fdi_ != -1 && fdi_ != 0)
close (fdi_);
- if (fdo_ != -1 && fdo_ != 1)
+ if (fdo_ != -1 && fdo_ != 1 && fdo_ != fdi_)
close (fdo_);
}