4

I have an application that uses a gui to do most of its interface with the user. However I would like to have a separate terminal window that I can write to for some error checking, raw values etc.

I know I can spawn a new terminal with the system() command but I have no idea if interaction is possible.

in the best possible scenario I would like to have a function which takes a string(char array I know...), and prints it to the newly spawned console window:

something like:

int func(char *msg) {
    static // initiate some static interface with a newly spawned terminal window.

    // check if interface is still valid

    // send data to terminal

    return 0; //succes

}
  • have a look into ncurses – RamblingMad Jul 02 '14 at 04:11
  • 1
    I know ncurses, but as far as I know ncurses doesn`t allow me to spawn NEW terminal window, only take control of the current opened window. I have used ncurses in several application prior. –  Jul 02 '14 at 04:13

2 Answers2

2
  1. Open a pipe.
  2. Fork.
  3. In the child process, close the write end and exec to an xterm running cat /dev/fd/<rdfd>.
  4. In the parent process, close the read end and write to the write end.
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>

int main(int argc, char **argv) {
    (void)argc, (void)argv;

    int fds[2];
    if(pipe(fds) == -1) {
        abort();
    }

    int child_pid = fork();
    if(child_pid == -1) {
        abort();
    }

    if(child_pid == 0) {
        close(fds[1]);
        char f[PATH_MAX + 1];
        sprintf(f, "/dev/fd/%d", fds[0]);
        execlp("xterm", "xterm", "-e", "cat", f, NULL);
        abort();
    }

    close(fds[0]);
    write(fds[1], "Hi there!\n", sizeof("Hi there!\n"));
    sleep(10);
    close(fds[1]);
    sleep(3);

    return EXIT_SUCCESS;
}

You can use fdopen to turn fds[1] into a FILE * that you can use fprintf and such on.

icktoofay
  • 126,289
  • 21
  • 250
  • 231
  • I like this approach, forking and using the pid is probably far easier than opening another process separately and sending commands through a socket. – RamblingMad Jul 02 '14 at 04:43
  • thank you. It works! even though I kind of have a dislike for `fork()` –  Jul 02 '14 at 09:40
0

Well, imagine a scenario where the terminal is your main output device (e.g. tty[n]), how would one open a "new" terminal then?

The only reason you can open multiple terminals in a graphical DE is because they are terminal emulators. You would need to launch another terminal emulator and write to the standard output of that using something like a socket or maybe shared memory.

RamblingMad
  • 5,332
  • 2
  • 24
  • 48
  • tl;dr : no standard way – RamblingMad Jul 02 '14 at 04:17
  • that kind of sucks... `/dev/pts` contains all virtual terminals but is there a way I can Identify or 'name' a newly spawned terminal? `pts` would allow me to spawn a new terminal but linking it to a terminal emulator is not documented –  Jul 02 '14 at 04:26
  • Just open a socket and send your commands and what-not through that to the other terminal, then all you need is the same port number. If you don't want to do that you could use a shared file or shared memory (the shm approach would be faster) but that is a huge security risk; if that matters from your point of view – RamblingMad Jul 02 '14 at 04:29
  • [posix_openpt()](http://linux.die.net/man/3/posix_openpt) followed by [unlockpt()](http://linux.die.net/man/3/unlockpt) then get the name (/dev/pts/x) with [ptsname()](http://linux.die.net/man/3/ptsname) – RamblingMad Jul 02 '14 at 04:36