Normally fd0 == stdin. But when process is started in background and fd0 is owned by terminal again, what is it set in that background process then? How can the background process accepts input? (if there was no redirection)
FD 0 is defined to be standard input, no matter what it's connected to.
Whether a process is run in the foreground or background, it inherits all the descriptors from its parent. So FD 0 will be connected to the terminal when there's no redirection.
However, terminal devices have a foreground process group, and only processes in that group are permitted to read input. Shells that implement job control put each job into a different process group, and set the terminal's foreground process group to the group of the foreground process. The result of this is that background processes will be stopped if they try to read from the terminal.
You can also use stty tostop
to stop background processes if they try to write to the terminal. This can be useful if you don't want output from background processes to interfere with what you're doing in the foreground.