我正在创建自己的shell(如bash),并且我有一个函数,该函数调用execv函数并传入一个特定的进程pid以杀死。我基本上运行了10秒钟的睡眠命令,中途我想要终止它。但我的杀戮命令似乎不起作用。有人知道我该怎么修理它吗?
以下是与execv
相关的函数void run_execv(char *path, char *args[])
{
int result = execv(path, args);
}
void kill_process(char *target_pid)
{
char *bin_path = "/bin/kill";
char *args[] = {bin_path, "-15", target_pid, NULL};
run_execv(bin_path, args);
}
void ps()
{
char *bin_path = "/bin/ps";
char *args[] = {bin_path, NULL};
run_execv(bin_path, args);
}
和kill_process函数的调用如下所示。基本上,我是作为子进程调用kill命令的。
else if (strncmp(shellInput, "pkill", strlen("pkill")) == 0 || strncmp(shellInput, "kill", strlen("kill")) == 0)
{
char *target_pid = strtok(NULL, " n");
int childStatus;
pid_t spawnPid = fork();
switch (spawnPid)
{
case -1:
perror("fork()n");
exit(1);
break;
case 0:
// This is the child process where we will call the ls function
kill_process(target_pid);
perror("execv");
exit(2);
break;
default:
// This is the parent process that takes control back after child process finishes.
spawnPid = waitpid(spawnPid, &childStatus, 0);
printf("CHILD STATUS: %dn", childStatus);
processStatus = childStatus;
break;
}
即使在杀死睡眠进程后,当我检查我的当前进程运行ps时,它仍然显示。请参见下面的相同执行的截图。
~/Desktop/OSU/CS-344 (Operating Systems)/assignment3(main*) » ./a.out sampai@sams-mbp-2
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
: sleep 30 &
background pid is 41143
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
41143 ttys003 0:00.00 sleep 30
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
: kill 41143
CHILD STATUS: 0
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
41143 ttys003 0:00.00 (sleep)
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
:
明白了!基本上就像kaylum在评论中所说的那样,我需要在switch语句之外添加一个waitpid调用。我需要等待正确的pid,我需要它进入子进程。请看下面我更新的代码。
int process_pid;
pid_t spawnPid = fork();
switch (spawnPid)
{
case -1:
perror("fork()n");
exit(1);
break;
case 0:
// This is the child process where we will call the ls function
process_pid = getpid();
kill_process(target_pid);
perror("execv");
exit(2);
break;
default:
// This is the parent process that takes control back after child process finishes.
spawnPid = waitpid(process_pid, &childStatus, 0);
processStatus = childStatus;
break;
}
spawnPid = waitpid(process_pid, &childStatus, 0); // Need this to kill zombie process.
printf("CHILD STATUS: %dn", childStatus);