-1

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");
}
Michael Kotzjan
  • 2,093
  • 2
  • 14
  • 23
Vainres
  • 3
  • 2

1 Answers1

0

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?

tonebender
  • 69
  • 4
  • I have a problem with running commands by opening gnome-terminal in quick succession in a while loop. Only one of the terminals starts the command, and all other commands after open a blank terminal. If I put a delay in, then there is no issue. – Al G Johnston Nov 01 '21 at 20:39