Kit Fisto
Kit Fisto

Reputation: 4515

Unix/C++: Open new terminal and redirect output to it

My program (C++ on Solaris 10) writes output via wcout to its terminal when it is started from a shell. But when I execute it from within Sun Studio or the file manager is does not have a terminal and the ouput appears in the Sun Studio output window or nowhere at all.

I would like it to open its own terminal window in any of the three cases and attach wcout to this terminal window. I want this to be done be the program itself with C++ system calls not by the way how the program is executed from some shell or script. Because then execution in the Studio IDE and double-click in the file manager would still have the same effect.

Being a Windows programmer that seems quite natural to me but I could not find out how this is done in my Unix books nor in the web. Am I requesting the wrong thing, is it really so hard to do or am I missing something?

Upvotes: 4

Views: 7547

Answers (5)

Foxie Flakey
Foxie Flakey

Reputation: 420

Using mknod to create pipe in /tmp every linux have /tmp and everyone always allowed to use it

system("mknod /tmp/printing_pipe pipe");
system("qterminal -e tail -f /tmp/printing_pipe");

write to the /tmp/printing_pipe to use it

Upvotes: 0

user3458
user3458

Reputation:

You want to output to a file (redirect, using a logging API or close stdout/reopen it as a file). And then tail it with tail -f in a terminal of your choice.

This has added benefit of saving your log output for review even if the terminal crashes/is killed.

Upvotes: 3

celtschk
celtschk

Reputation: 19721

The following is close to what you want. It still has a few bugs:

  • The xterm cannot be normally closed (it closes when the program terminates, though). I have no idea why this is so.
  • Before the intended output, a number is output. Again, I have no idea why.
  • I don't seem to be able to redirect input.

Maybe someone else know how to fix those bugs (and any others I might not have noticed).

#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sstream>

int main()
{
  int pt = posix_openpt(O_RDWR);
  if (pt == -1)
  {
    std::cerr << "Could not open pseudo terminal.\n";
    return EXIT_FAILURE;
  }
  char* ptname = ptsname(pt);
  if (!ptname)
  {
    std::cerr << "Could not get pseudo terminal device name.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  if (unlockpt(pt) == -1)
  {
    std::cerr << "Could not get pseudo terminal device name.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  std::ostringstream oss;
  oss << "xterm -S" << (strrchr(ptname, '/')+1) << "/" << pt << " &";
  system(oss.str().c_str());

  int xterm_fd = open(ptname,O_RDWR);
  char c;
  do read(xterm_fd, &c, 1); while (c!='\n');

  if (dup2(pt, 1) <0)
  {
    std::cerr << "Could not redirect standard output.\n";
    close(pt);
    return EXIT_FAILURE;
  }
  if (dup2(pt, 2) <0)
  {
    std::cerr << "Could not redirect standard error output.\n";
    close(pt);
    return EXIT_FAILURE;
  }

  std::cout << "This should appear on the xterm." << std::endl;
  std::cerr << "So should this.\n";
  std::cin.ignore(1);

  close(pt);
  return EXIT_SUCCESS;
}

Upvotes: 6

Mihai
Mihai

Reputation: 2155

I would recommnend to create a shell script that runs the terminal to which you pass your program to execute, then you should call that script instead of your program from the file manager.

Your script.sh:

#!/bin/sh

xterm -e /path_to_your_program/your_program

Upvotes: 0

Robᵩ
Robᵩ

Reputation: 168616

When you invoke your program, instead of running: myprog 1 2 3 a b c, run xterm -e myprog 1 2 3 a b c.

Upvotes: 0

Related Questions