3

I wanted to create C/C++ application, that creates new (virtual) device in /dev/xxx and will be able to connect with 'screen' application.

For example program running in loop, that creates new /dev/ttyABC. Then I'll use 'screen /dev/ttyABC', and when I send there some chars, then app send it back to the 'screen'.

I really don't know where start. I found some referencies on pty library but I don't even know, if I have right direction.

Could you help me? Where to look? Post example? Thanks

Payne
  • 456
  • 6
  • 21

2 Answers2

3

You could use a Pseudoterminal via openpty to achieve this. openpty returns a pair of file descriptors (master and slave pty devices) that are connected to each other via their stdout / stdin. The output of one will appear at the input of another and vice-versa.

Using this (rough!) example...

#include <fcntl.h>
#include <cstdio>
#include <errno.h>
#include <pty.h>
#include <string.h>
#include <unistd.h>

int main(int, char const *[])
{
  int master, slave;
  char name[256];

  auto e = openpty(&master, &slave, &name[0], nullptr, nullptr);
  if(0 > e) {
    std::printf("Error: %s\n", strerror(errno));
    return -1;
  }

  std::printf("Slave PTY: %s\n", name);

  int r;

  while((r = read(master, &name[0], sizeof(name)-1)) > 0) {
    name[r] = '\0';
    std::printf("%s", &name[0]);
  }

  close(slave);
  close(master);

  return 0;
}

... Echoing some text (in another terminal session) to the slave pty sends it to master's input. E.g. echo "Hello" > /dev/pts/2

gmbeard
  • 674
  • 6
  • 19
  • It work's fine till I try to connect with screen. But when I connect to the code some mmaped file act like /dev/tty device, it could work. I'm right, don't I? – Payne Oct 20 '15 at 16:09
  • I'm not sure you can connect `screen` directly to the slave pty. – gmbeard Oct 20 '15 at 17:47
  • Becouse of that I wanted to create some file joined with slave pty.. That's what I need - screen connectable file/stream.. Is there some possibility make it? – Payne Oct 20 '15 at 17:52
0

Based on the answer provided by @gmbeard , I was able to create an echo PTY device and connect to it with screen and minicom. What made the difference was using a raw PTY device by initializing a termios struct.

Here is the code

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <cstdio>
#include <pty.h>
#include <termios.h>

#define BUF_SIZE (256)

int main(int, char const *[])
{
    int master, slave;
    char buf[BUF_SIZE];
    struct termios tty;
    tty.c_iflag = (tcflag_t) 0;
    tty.c_lflag = (tcflag_t) 0;
    tty.c_cflag = CS8;
    tty.c_oflag = (tcflag_t) 0;

    auto e = openpty(&master, &slave, buf, &tty, nullptr);
    if(0 > e) {
    std::printf("Error: %s\n", strerror(errno));
    return -1;
    }

    std::printf("Slave PTY: %s\n", buf);

    int r;

    while ( (r = read(master, buf, BUF_SIZE)) > 0 )
    {
        write(master, buf, r);
    }

    close(slave);
    close(master);

    return 0;
}
Dan Shemesh
  • 464
  • 3
  • 13
  • What was critical about using the raw termios here? You may be able to shed some light on - https://stackoverflow.com/q/65375849/1569204. – Bruce Adams Dec 20 '20 at 02:29