- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在用 C 编写一个简单的 shell,但我遇到了信号问题。
例如,当我启动我的程序时,我输入 ping 命令,然后 CTRL-Z 我希望子进程(ping 命令)暂停,然后在我使用 fg 时返回。
我认为我需要将执行 ping 命令的子 pid 存储为全局变量。
我已经检查了其他帖子以自行解决问题,但我无法使其正常工作。
这是执行命令(带 | 的多个命令)以及我存储子 pid 的代码。
int exec_proc(int input, int output, char** command) {
pid_t runner;
runner = fork();
f_pid = runner;
if (runner == 0) {
// Use input for stdin
if (input != 0) {
dup2(input, 0);
close(input);
}
// Use output for stdout
if (output != 1) {
dup2(output, 1);
close(output);
}
// Return command code
execvp(command[0], command);
}
// An error occured
return -1;
这是我的处理程序 c 文件。
pid_t f_pid;
/**
* Handles every handler !
*/
void handlerManager()
{
signal(SIGINT,INTHandler);
signal(SIGTSTP,TSTPHandler);
signal(SIGCONT,CONTHandler);
}
/**
* Handler for CTRL-C
* @param sig
*/
void INTHandler(int sig)
{
printf("\nDo you really want to quit ? [y/n] \n");
int answer = getchar();
if(toupper(answer) == 'Y')
kill(f_pid,SIGINT);
}
/**
* Handler for CTRL-Z (processus sleep)
* @param sig
*/
void TSTPHandler(int sig)
{
printf("\nGoing to sleep! \n");
printf("%d", f_pid);
kill(f_pid,SIGTSTP);
}
/**
* Handler to reset a processus
* @param sig
*/
void CONTHandler(int sig)
{
printf("\nHey i'm awake\n");
kill(f_pid,SIGCONT);
}`
当我打印 pid 时,我得到了正确的 PID。
最后,这是我调用我的处理程序管理器的地方。
int main() {
char* line;
char** args[MAX_ARG_SIZE] = {NULL};
int status;
handlerManager();
do {
fflush(stdin);
prompt();
line = readline();
char linecpy[strlen(line)];
strcpy(linecpy, line);
splitBy(line, " ", args);
status = exec(args, linecpy);
switch (status) {
case EMPTY_LINE:
break;
}
} while (status);
return 0;
提前谢谢你,对不起我的英语。
最佳答案
进行适当的作业控制信号处理可以提升您的项目,使其超出我所说的“简单” shell 。 GLIBC 手册有 a whole multi-part section关于实现作业控制 shell,听起来其中大部分内容都适用于您的项目。
您似乎忽略的一个关键方面是管理进程组以及其中哪些进程组可以控制终端。你现在做事的方式,你的 shell 的子进程将与 shell 本身属于同一个进程组,并且当一个信号,比如 SIGSTP
,被发送到 child 全过程组。
为了避免此类问题,您的 shell 应该使新的子进程成为它们自己的进程组的进程组领导者(通过 setpgid()
)。当此类进程组最初要位于前台时,您的 shell 应将它们设为终端的控制进程组 (tcsetpgrp()
)。
当然,还有更多内容,但这应该能让您朝着正确的方向前进。
关于c - 使用子进程处理信号 SIGSTP、SIGCONT、SIGINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47489128/
我目前正在用 C 编写一个简单的 shell,但我遇到了信号问题。 例如,当我启动我的程序时,我输入 ping 命令,然后 CTRL-Z 我希望子进程(ping 命令)暂停,然后在我使用 fg 时返回
我有一个带有用户定义析构函数的类。如果该类最初是实例化的,然后在程序运行时发出 SIGINT(在 unix 中使用 CTRL+C),会调用析构函数吗? SIGSTP(unix 中的 CTRL + Z)
我正在练习信号。当我编译代码时,我收到了未声明的 SIGALRM 和未声明的 SIGSTP 错误消息。 main.c:46:16: error: ‘SIGALARM’ undeclared(首次在此函
我是一名优秀的程序员,十分优秀!