Search code examples
c++cubuntuvimgnome-terminal

How can new gnome terminal receive command in C


I have tried to write a program that run in ubuntu terminal .Program will open a new gnome terminal and run command in that new terminal to open new abcd.txt using vim.And then when i Ctrl+C in the first terminal which run the program ,new gnome terminal will shut vim down and have an announcement in the first terminal

I have tried system("`gnome-terminal`<< vim abcd.txt");

and this system("vim abcd.txt>>`gnome-terminal`");

but the new one terminal cannot recieve command

My full code

#include <stdio.h> 
#include <stdlib.h>
#include <unistd.h> 
#include <sys/wait.h> 
#include <pthread.h> 

int loop=1; 

void DEF() 
{ 
    system("kill -9 pidof vim"); 
    loop=0; 
}

void *subthreads(void *threadid) 
{ 
    loop=1; 
    long tid; 
    tid=(long)threadid; 
    system("`gnome-terminal`<< vim abcd.txt");
    signal(SIGINT,DEF); 
    while(loop){} 
    pthread_exit(NULL); 
}

void main() 
{ 
    int loop=1; 
    pthread_t threads; 
    int check; 
    long tID; 
    check= pthread_create(&threads,NULL,&subthreads,(void*)tID);
    while(loop){} 
    printf("Ctrl+C is pressed!\n");
}

Solution

  • Not sure what you are trying to achieve in the end. But here are a few ideas, starting from your code:

    • The terminal command (in system()) should be something like Mark Setchell pointed out, like for example system("gnome-terminal -e vim file.txt");

    • The system() command is blocking further execution of your code, so the call to signal() is not happening until you terminate the system() call.

    • pidof is not working on my Linux system. I would use pkill <program>. Still, that would kill all running instances of , for example vim or your terminal.

    • You are declaring the variable loop in the global scope first and then redeclaring it in main(). If you really want to use it as a global variable, it should just be loop=1 in main().

    • You are not using the variable tid for anything.

    Here is an improved version of your program, with additional printf calls to explain to the user what is happening. I also used xterm and nano because I don't have gnome-terminal, and I didn't want to interfere with my running instance of vim. But it still is maybe not exactly what you are trying to do. The main problem is that system("xterm -e sh &") is blocking and when you press Ctrl-C, that system call will terminate xterm so that the def() function will do nothing when it is called later.

    #include <stdio.h> 
    #include <stdlib.h>
    #include <unistd.h> 
    #include <sys/wait.h> 
    #include <pthread.h> 
    
    int loop = 1;
    
    void def()
    {
        printf("In def\n");
        system("pkill xterm"); 
        loop=0; 
    }
    
    void *subthreads(void *threadid)
    {
        printf("Starting subthread\n");
        loop = 1;
        long tid;
        tid = (long)threadid;
        signal(SIGINT, def);
        system("xterm -e sh -c nano &");   // Note: xterm will still exit when you press Ctrl-C
        printf("Terminal exited in subthread\n");
        while (loop);
        printf("Exited loop in subthread\n");
        pthread_exit(NULL);
    }
    
    void main()
    {
        pthread_t threads;
        int check;
        long tID;
        check = pthread_create(&threads, NULL, &subthreads, (void*)tID);
        printf("In main after thread creation\n");
        while (loop);
        printf("Ctrl+C is pressed!\n");
    }
    

    Another option is to use fork() instead of pthread to split into a separate process. (Note that processes are like separate applications while threads are processor threads in the same application.)

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    void def()
    {
        system("pkill nano");
        printf("def(): Killed nano\n");
    }
    
    int subprocess()
    {
        signal(SIGINT, def);
        pid_t parent_id = getpid();  // Get process ID of main process
        fork();                      // Fork into two identical copies of the running app.
        if (getpid() != parent_id) {  // The part in the if block is only done in the second process!
            system("xterm -e sh -c nano &");
            printf("subprocess(): system call ended in forked process\n");
            exit(0);
        }
    }
    
    int main()
    {
        subprocess();
        printf("Entering while loop in main process\n");
        while (1);
        printf("Exited main thread\n");
    }
    

    The one flaw with this version is the same as the previous one: when Ctrl-C is pressed, xterm/nano is killed and def() will subsequently do nothing except catch any Ctrl-C done afterwards.

    If you explain further what your final goal is, maybe I can give some suggestions. Like, why do you want to start vim in a terminal from a C application and then kill vim? Do you want to kill the whole terminal or only vim?