I'm trying to make a shell with foreground and background processes, where if the foreground process tries to access the terminal, it will automatically stopped (since it doesn't have access to the terminal). What happens is that at first, I set my shell to IGNORE the signals
SIGTSTP
SIGINT
SIGTTOU
After forking, for the child of both foreground and background processes, I set the child to put the ignored signals above back to
SIG_DFL
Additionally, for each child, I also set their pgids, so that they are in different program groups.
The difference I have between the parent of foreground and background processes is that for foreground, I also give the child terminal access:
tcsetpgrp(ST开发者_运维百科DIN, getpgid(getpid()))
tcsetpgrp(STDOUT, getpgid(getpid()))
Additionally, the parent of the foreground process also waits for the child to finish before looping back and asking for user prompt again.
For the background child, the parent just calls
continue
to loop back and ask for more user prompt. Additionally, I also have a handler for SIGCHLD signals with a waitpid() line to ensure that no background process becomes a zombie.
PROBLEM: However, the problem I'm running into is that my background process still has access to terminal (using echo "hello" in background process still works), and my foreground process seems to be ignoring the signals generated by CTL+C and CTL+Z even though I re-enabled them in the foreground child, as well as the background child. Anyone have hints as to what may be wrong?
The "normal" shell works different, the foreground process is not a child. Thus I would do it like this:
fork background process, then in the child set signals, close all inherited file descriptors, setprgp (detach from controlling tty), open files for I/O redirection if needed
in the parent, decide if you want to wait for child processes or just ignore them (SIG_CHLD)
精彩评论