在 C 中实现类似 shell 的作业控制
Implementing shell-like job control in C
我正在尝试用 C 语言实现简单的 shell,但我很难实现作业控制。网上的一切似乎都足够复杂,我认为简单一些总是好的。所以让我问这个......在调用 fork() 之后,我可以只用 2 个函数和 pid 处理 Ctrl-Z 信号吗?
我想调用一个函数e.x。 put_background(pid_t pid)
当我按下 Ctrl-Z 并使用 pid = pid 处理到 运行 后台,最后调用另一个函数 e.x。 put_foreground(pid_t pid)
当我写 fg 并且我希望 pid = pid 的进程再次进入前台时。
那么,这可能吗?任何帮助表示赞赏..但是更多代码。
I am trying to implement simple shell in C language and i am having a
hard time implementing job control. Everything online seems
complicated enough and i think some simplicity is always good.
So let
me ask this ... After fork() is called can i handle Ctrl-Z signal with
just 2 function and just with the pid ?
请注意,Ctrl-Z 主要对终端驱动程序有意义。它会导致 SIGTSTP
被发送到键入该字符的终端的前台进程组——也就是说,以该终端为控制终端并有权从中读取的进程组。默认情况下,这会导致该组中的进程停止,仅此而已。您无需执行任何操作即可实现。*
I want to call a function e.x. put_background(pid_t pid) when i hit
Ctrl-Z and make process with pid = pid to run background and finally
call another function e.x. put_foreground(pid_t pid) when i write fg
and i want the process with pid = pid to go to foreground again.
根据定义和设计,最多一个进程组在任何特定时间控制给定终端。因此,要将一个前台作业移到后台,您需要做的就是将另一个作业移到前台。这可以是 shell 本身或它控制下的其他作业。 tcsetpgrp()
库函数实现了这一点。除非它是 shell 本身,否则您还需要向该进程组发送一个 SIGCONT
以防它停止。
您还需要一种机制来恢复已停止的后台作业,但这很简单:只需向该进程组发送 SIGCONT
。
So, is this possible? Any help is appreciated.. code more however.
当然可以,您可以编写一个函数来将作业移至前台并恢复它,并编写一个函数来恢复后台作业。这些功能需要的关于它们所操作的作业的唯一信息是它们的进程组 ID(与它们的初始进程的进程 ID 相同)。
但是您还需要维护当前活动作业的一些簿记,并且需要注意开始新作业,并且需要监控当前作业——尤其是前台作业——以便能够适当地编排所有转换。
GLIBC 手册有 an entire chapter on job control,包括专门关于实现作业控制的重要部分 shell。即使您不是为基于 GLIBC 的系统编写代码,这也可能对您有用。实际所需的代码并没有那么复杂,但要正确使用代码需要对相当广泛的概念有很好的理解。
*但是你做需要确保你的shell将它启动的命令放入不同于它自己的进程组, 否则 Ctrl-Z 也会停止它。
我正在尝试用 C 语言实现简单的 shell,但我很难实现作业控制。网上的一切似乎都足够复杂,我认为简单一些总是好的。所以让我问这个......在调用 fork() 之后,我可以只用 2 个函数和 pid 处理 Ctrl-Z 信号吗?
我想调用一个函数e.x。 put_background(pid_t pid)
当我按下 Ctrl-Z 并使用 pid = pid 处理到 运行 后台,最后调用另一个函数 e.x。 put_foreground(pid_t pid)
当我写 fg 并且我希望 pid = pid 的进程再次进入前台时。
那么,这可能吗?任何帮助表示赞赏..但是更多代码。
I am trying to implement simple shell in C language and i am having a hard time implementing job control. Everything online seems complicated enough and i think some simplicity is always good.
So let me ask this ... After fork() is called can i handle Ctrl-Z signal with just 2 function and just with the pid ?
请注意,Ctrl-Z 主要对终端驱动程序有意义。它会导致 SIGTSTP
被发送到键入该字符的终端的前台进程组——也就是说,以该终端为控制终端并有权从中读取的进程组。默认情况下,这会导致该组中的进程停止,仅此而已。您无需执行任何操作即可实现。*
I want to call a function e.x. put_background(pid_t pid) when i hit Ctrl-Z and make process with pid = pid to run background and finally call another function e.x. put_foreground(pid_t pid) when i write fg and i want the process with pid = pid to go to foreground again.
根据定义和设计,最多一个进程组在任何特定时间控制给定终端。因此,要将一个前台作业移到后台,您需要做的就是将另一个作业移到前台。这可以是 shell 本身或它控制下的其他作业。 tcsetpgrp()
库函数实现了这一点。除非它是 shell 本身,否则您还需要向该进程组发送一个 SIGCONT
以防它停止。
您还需要一种机制来恢复已停止的后台作业,但这很简单:只需向该进程组发送 SIGCONT
。
So, is this possible? Any help is appreciated.. code more however.
当然可以,您可以编写一个函数来将作业移至前台并恢复它,并编写一个函数来恢复后台作业。这些功能需要的关于它们所操作的作业的唯一信息是它们的进程组 ID(与它们的初始进程的进程 ID 相同)。
但是您还需要维护当前活动作业的一些簿记,并且需要注意开始新作业,并且需要监控当前作业——尤其是前台作业——以便能够适当地编排所有转换。
GLIBC 手册有 an entire chapter on job control,包括专门关于实现作业控制的重要部分 shell。即使您不是为基于 GLIBC 的系统编写代码,这也可能对您有用。实际所需的代码并没有那么复杂,但要正确使用代码需要对相当广泛的概念有很好的理解。
*但是你做需要确保你的shell将它启动的命令放入不同于它自己的进程组, 否则 Ctrl-Z 也会停止它。