How to open new terminal through C program in linux
Asked Answered
U

1

6

I have written client-sever code where I have many connections, let say each node represents different process on same machine. And to do that I have obviously use fork().

But now problem is that all results get displayed on same terminal. I want to know is there any way such that after each fork() or process creation new terminal gets opened and all results get displayed for that process on particular terminal.

P.S: I have tried system("gnome-terminal") but it just opens new terminal but all results get displayed again on same terminal only. All new terminals are just opens and remain blank without any result.

Also I have gone through this link How to invoke another terminal for output programmatically in C in Linux but I don't want to run my program with parameters or whatever. Its should be just like ./test

Here is my code:-

for(int i=0;i<node-1;i++)
  {
    n_number++;
    usleep(5000);
    child_pid[i]=fork();
    if(!child_pid[i])
    {
      system("gnome-terminal");
      file_scan();
      connection();          
      exit(0);
    }     
    if(child_pid[i]<0)
      printf("Error Process %d cannot be created",i);
  }
  for(int i=0;i<node-1;i++)
    wait(&status);

So basically what I want is for each process there should be new terminal displaying only that process information or result.

What I exactly want:

  • After fork() I have some data related to say process 1 then I want its output to one terminal
  • Same goes with each process. So its like if I have 3 process then there must be 3 terminals and each must display process related data only.

I know it can be doable using IPC(Inter Process Communication) but is there any other way around? I mean just 2-3 commands or so? Because I do not want to invest too much in coding this part.

Thanks in advance!!!

Uncinate answered 18/4, 2013 at 1:41 Comment(5)
How is the original process going to arrange to write to the terminal? What process in the new terminal is going display the information you write?Epigeous
@JonathanLeffler I wish I remembered file descriptors and streams more, but couldn't you theoretically open a new terminal and redirect stdout to whatever file descriptor exists for that terminal? Hm I think I am misunderstanding terminals...Festa
My suspicion/expectation is that in the absence of anything else, the terminal is set up with its own shell, and with its own (surprise) terminal (/dev/ttyXXX or /dev/ptyXXX). So, some careful plumbing will likely be necessary so that the input for the terminal window comes from your process that wants to write to it, and you'll need a program (maybe cat?) to read that input and write to the terminal window. I've not done it, so I don't know what the tricks are. (Have you tried man gnome-terminal?)Epigeous
Its like... after fork() I have some data related to say process 1 then I want its output to one terminal and same goes with each process. So its like if I have 3 process then there must be 3 terminal and each must display process related data.Uncinate
@JonathanLeffler yeah I look into the {man gnome-terminal} haven't found anything interesting. Also trying to do this by using {system("xterm")}. But no luck till now. Thank you!Uncinate
S
6

Maybe you want something like that. This program is using the unix98 pseudoterminal (PTS), which is a bidirectional channel between master and slave. So, for each fork that you do, you will need to create a new PTS, by calling the triad posix_openpt, grantpt, unlockpt at master side and ptsname at slave side. Do not forget to correct the initial filedescriptors (stdin, stdout and sdterr) at each side.

Note that is just a program to prove the concept, so I am not doing any form of error check.

#define _XOPEN_SOURCE 600 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <fcntl.h>

int main() {
  pid_t i;
  char buf[10];
  int fds, fdm, status;

  fdm = posix_openpt(O_RDWR);
  grantpt(fdm);
  unlockpt(fdm);

  close(0);
  close(1);
  close(2);

  i = fork();
  if ( i != 0 ) { // father
    dup(fdm);
    dup(fdm);
    dup(fdm);
    printf("Where do I pop up?\n");
    sleep(2);
    printf("Where do I pop up - 2?\n");
    waitpid(i, &status, 0);
  } else {  // child
    fds = open(ptsname(fdm), O_RDWR);
    dup(fds);
    dup(fds);
    dup(fds);
    strcpy(buf, ptsname(fdm));
    sprintf(buf, "xterm -S%c/2", basename(buf));
    system(buf);
    exit(0);
  }
}
Sonni answered 18/4, 2013 at 7:8 Comment(3)
sprintf(buf, "xterm -S%c/2", basename(buf)); should be %s for char *.Radford
why is i==0 the father. normaly the PID==0 is the child process, right? An change you wanted to write i!=0 ?Kurdistan
@Kurdistan from fork man page: On success, the PID of the child process is returned in the parent, and 0 is returned in the child. so, yes, if i==0 you are in child process. In this example, the correct would be i!=0. ThanksSonni

© 2022 - 2024 — McMap. All rights reserved.