2

This is a question about an answer to Praveen Gollakota's answer in another question (is this the way I'm supposed to get around comment privileges?).

His answer to the question of why fork twice is, in essence, to make sure the forked process is not a session leader and thus cannot obtain a tty. He gives this example of a forking process, and shows that the second child is not the session leader (SID after the second fork is not the second child's PID).

1. `Parent`    = PID: 28084, PGID: 28084, SID: 28046
2. `Fork#1`    = PID: 28085, PGID: 28084, SID: 28046
3. `Decouple#1`= PID: 28085, PGID: 28085, SID: 28085
4. `Fork#2`    = PID: 28086, PGID: 28085, SID: 28085

However, you can also see here that after the first fork and before the "decouple" step (I'm assuming this is a call to setsid()), the child is not the session leader. Therefore my question is why call setsid()? Why not fork once and exit?

My guess is that this has something to do with the session leader being the controlling terminal (or other grandparent). So a follow up question would be, what happens to a process whose group leader exits, but whose session leader is still alive?

onlyanegg
  • 517
  • 7
  • 15

1 Answers1

0
1. `Parent`    = PID: 28084, PGID: 28084, SID: 28046

The program has a controlling terminal at this point.

2. `Fork#1`    = PID: 28085, PGID: 28084, SID: 28046

The program still has a controlling terminal at this point. If the parent exited, this child would belong to an abandoned process group. It can setpgid() to another process group in the same session.

3. `Decouple#1`= PID: 28085, PGID: 28085, SID: 28085

Now the program is in another session, and cannot setpgid() to switch to a process group in the original session.

4. `Fork#2`    = PID: 28086, PGID: 28085, SID: 28085

Reparent to init.

ephemient
  • 198,619
  • 38
  • 280
  • 391
  • Thanks for your response. I think by "program", you mean the process that spawned the Parent (ie. PID 28046). I can see that if the Parent exits after step two, the first child would belong to an abandoned process group. However, this also happens after step four; when the first child exits, the second child belongs to an abandoned process group. – onlyanegg Jul 19 '17 at 23:50
  • @onlyanegg It does, but at that point it doesn't matter what process group it belongs to - it cannot re-join the terminal session. – ephemient Jul 20 '17 at 00:03
  • Ok, I think I see the point. The controlling terminal is a property of the session. I think the [GNU C Library Reference Manual](https://www.gnu.org/software/libc/manual/html_node/Access-to-the-Terminal.html#Access-to-the-Terminal) says that all processes within a session can have write access to the terminal which is obviously something we don't want in a daemon. Additionally, we want to avoid the possibility that it can obtain it's own TTY by making sure it's not a session leader. Is that right? Why do we care that it cannot obtain a tty? Is that just a resource concern? – onlyanegg Jul 20 '17 at 02:31
  • @onlyanegg There are a variety of reasons, such as allowing the TTY to be freed while the program is still running (the program should also close its standard file descriptors), ensuring the program doesn't receive a hangup signal (from the terminal) or continue signal (from other processes in the same session), and reducing behavior differences between starting interactively or by the system (init normally doesn't run processes with a TTY). [Other steps](https://en.wikipedia.org/wiki/Daemon_%28computing%29#Unix-like_systems) are common. – ephemient Jul 20 '17 at 04:34
  • ok, if you want to add some of that information to the answer, I'd be happy to mark it as resolved. – onlyanegg Jul 20 '17 at 14:15