I’m writing a simple Shell here. In brief, I’m doing these stuff (pseudo code):
call fork()
if return value is zero: //child
setpgid(0,0)
if (foreground)
tcsetpgrp() //give this child access to terminal
reset all signal handlers messed up by parent
unblock all signals that are blocked by parent
execve()
else: //parent
if (foreground)
tcsetpgrp() //give child access to terminal
add this job to job list
unblock all signals
wait for this job to finish
tcsetpgrp() //get terminal access back
if (background)
add this job to job list
unblock all signals
What I want to test is /bin/cat. Now, this Shell works fine for /bin/cat if I run it in foreground. However, if I type /bin/cat & to let it run in background, I got an input/output error. According to what I learned, when a background job is trying to read from terminal, SIGTTIN should be sent to it. So ideally, when I type /bin/cat &, it will be stopped by a SIGTTIN. If I use “bg” command to resume it, it will again be stopped by a SIGTTIN.
What I am confused is how could I implement this. Is SIGTTIN automatically sent by the OS, or I have to send it myself? If it is that latter one, how could I tell a child is going to read from the terminal or not?
Thanks!
Finally got it. No response to SIGTTIN is because the parent has ignored this signal. In child, all the signal handlers has to set to default, including SIGTTIN signal.