There are three process groups: (1) the login shell, (2) the pty parent and child, and (3) the cat process. The first two process groups constitute a session with the login shell as the session leader. The second session contains only the cat process. The first process group (the login shell) is a background process group, and the other two are foreground process groups.
First, cat terminates when it receives the end of file from its line discipline. This causes the PTY slave to terminate, which causes the PTY master to terminate. This in turn generates an end of file for the pty parent that's reading from the PTY master. The parent sends SIGTERM to the child, so the child terminates next. (The child doesn't catch this signal.) Finally, the parent calls exit(0) at the end of the main function.
The relevant output from the program shown in Figure 8.29 is
cat e =270, chars =274, stat =0:
pty e =262, chars = 40, stat = 15: F X
pty e =288, chars =188, stat =0: