6

I'm currently attempting to write a minimal terminal multiplexer using ncurses. However, when I try to execv a shell, it doesn't print to the window, and instead starts a new subprocess that takes control of the window (i.e. ignores ncurses).

How can I prevent that and have ncurses control it? Is there some way of getting the tty and controlling that?

EDIT

Thanks to Ross Ridge in the comments, I now know that I need to create a pseudo-terminal, which I then read into an ncurses window. However, I can't figure out how to get the stdout to print in an ncurses window. Is there an ncurses function that reads file descriptors? Or do I have to use read() with printw() somehow?

CharlesL
  • 265
  • 5
  • 21
  • 5
    You'd have to use a psuedo terminal. It's not going to be anywhere near as easy as you hoped. – Ross Ridge Sep 01 '14 at 00:32
  • Have a look at what GNU mc (midnight commander) does. It implements something similar to what you want. – fuz Sep 13 '14 at 22:12

1 Answers1

9

You will need to do roughly the following:

  • Create a pty (pseudoterminal). You don't mention which OS you are using, but if it's POSIX based, man pty will help. Also look at openpty
  • The slave end of the pty needs to be connected to whatever you are running (e.g. the shell), whereas the master end needs to be connected to your terminal emulator.
  • You'll thus have to fork(), and in the child, dup2 the slave fd onto the stdin, stdout and stderr
  • Then you need to connect the master fd in the parent to your ncurses environment (for output) and keyboard handling (for input).

This answer, This answer, and this answer might be useful, but I recommend especially the first given it refers Stephens' Advanced Programming in the UNIX Environment (I've linked to the more modern edition), and the source code is downloadable. Buy the book, because it's an invaluable resource, but if you look in the pty directory there (I won't copy and paste for copyright reasons) you'll find a good example of forkpty.

That leaves the question of how you get from output data from the process you are running to ncurses. Well, you need to write a terminal emulator. Pick the terminal you want to emulate, read up on all the control sequences it uses, and implement all of them.

If this sounds quite like hard work (which it is), I suggest you look at using tmux or screen instead; the latter which does exactly what you want, including a full VT100/ANSI terminal emulator; the former is almost as complete. tmux is a BSD licensed program, which means you can simply adapt the source to do your bidding in the unlikely event it doesn't already. screen is GPL, so unless your program is also GPL, it's for inspiration only.

Community
  • 1
  • 1
abligh
  • 24,573
  • 4
  • 47
  • 84
  • Stephen's UNIX book is definitely a must own. Between it and BSD's manpages, there is everything you need to program in UNIX. – D'Nabre Sep 14 '14 at 07:42
  • 3
    [libvterm](http://www.leonerd.org.uk/code/libvterm/) is a good option for this, it's what Neovim uses for its terminal window. – s4y May 09 '15 at 03:07