I am building a feature, where I can open and close files in vi
editor. I am using execlp()
system call in C for opening a file in a new terminal window in a new child process. Here is how it looks:
void openFile (char *fileName) {
int pid=fork();
if (pid==0){
execlp("gnome-terminal", "gnome-terminal", "--", "vi", fileName, NULL) ;
}
insert(fileName, pid);
return;
}
So for closing the file, I have the child process Id.
void closeProcess (int pid){
printf("killing %d\n", pid);
kill(pid, SIGKILL);
return;
}
Now the challenge is this process id is not the same as the vi
editor process id. Killing this process is not closing the vi
editor.
Here are some example processes. The process id that I have in pid variable is 25803 but is now dead. To kill vi
editor I need the process id 25815.
How killing vi
process working.
Here is my current program output, which doesn't close vi
editor for that file.
Between the fork()
and execlp()
you will need to set up a process group id. Then when killing, use the group id.
int setpgid(0, 0);
When this is called in the child, the first 0 is shorthand for "me". The second 0 is shorthand for "use the pid". So this means "create a new process group and put me in that group."
When killing, use the PID you have been using. But it will also handle all children of the group.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
int pid = 20989; // That PID has a PGID of 20988
int pgid = getpgid(pid);
printf("pgid = %d\n", pgid);
}
Alternatively you can use this ps
command:
ps xao pid,ppid,pgid,sid,command
The KILL signal instructs Linux to end the job immediately. Any open files are closed in place. There is no clean up of user land state by the application.
Alternatively, sending SIGTERM instructs the application to end. Permitting the application to close all files, save their state, and prepare to end.