illumos-gate #872 ================= https://www.illumos.org/issues/872 Initial Email ============= https://www.illumos.org/issues/872 http://zinascii.com/pub/illumos/webrevs/872/ Besides the public daemon symbol in libc, two other libs define _private_ daemon symbols. 1. mech_krb5 2. libresolv2 According to README.mapfiles a private symbol may be removed at any time, though it is courteous to make sure it's not in wide use first. Given that daemon is now part of libc, and everything must link against libc, I don't see a reason to keep these symbols defined. The mDNS code also contains its own private daemon definition but since that is a command, and the source is copied from Apple, I decided to leave it alone. pbchk complains about copyrights needing update but all I did was remove code so that seems silly. cstyle goes bonkers against port_after.h but it didn't feel right to change that entire file for this ticket. Happy to make it cstyle clean if someone feels otherwise. Reply to Dan McDonald ===================== > Did you compare the implementations in those two vs. the libc one? I'd hate to think that one of them depends on some godawful side-effect that'll break when they switch to the libc version. The krb5 code is very old (it uses K&R style). It has ifdefs that have been obsolete for decades. For example, setsid(2) was introduced as part of X/Open Spec Issue 3 (POSIX.1:1988) in 1988. Most of the source differences are removed once cpp is done with it [1]. [1]: http://zinascii.com/pub/illumos/872/krb5-daemon-after-cpp-small.txt Apparently HAVE_SETSID is not defined so it falls back to setpgrp(2). setpgrp(2) and setsid(2) do the same thing except setsid(2) will error out if the calling process is already a group leader [2]. This is not a problem since both calls are preceded by a fork(2); the calling process can't be a group leader after the fork. [2]: https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/syscall/pgrpsys.c#L52 The biggest difference is the second fork(2) call found in libc but not krb5. This prevents the process from reacquiring a controlling terminal, at least according to the source comment and according to Stevens in UNIX Network Programming it does. I spent over 8 hours learning about terminals, pty, sessions, job control, etc. I wanted to write a test that proves that second fork is needed. But I still don't understand how it all fits together well enough and I didn't want to hold up this reply any longer. Finally, there is difference in the noclose handling. The libc version will return an error if any of the open(2) or dup2(3C) calls fail, krb5 ignores failure. I'd say the libc version is the correct behavior: if the function can't honor the caller's request then it should let the caller know. libresolv2 is the same as krb5 except it uses setsid(2) like the libc version. I don't think these differences, the additional fork and the error checking, should be cause for concern. But I understand if people are hesitant. One of the reasons I'm going through these old "bite sized" issues is to force a decision to be made so that some of the dead weight can get cleared off the board. Breakdown of pgrpsys.c:setpgrp() ================================ These two are the same exception `setsid()` will error if called by a process that is already a group leader. ### setpgrp() ### 1. IF (calling proc) IS NOT (a session leader) AND NOT (a group leader of a group of processes besides just itself) THEN (create new session) ELSE (nothing). 2. SET `sid` TO (the session leader id) 3. return `sid` ### setsid() ### 1. IF (calling proc) IS (a group leader) OR (a group leader of a group of processes besides just itself) THEN (EPERM) 2. (create new session) 3. SET `sid` to (the session leader id) 4. return `sid` The check in step 1 seems redundant. The man page for `setsid(2)` it says: EPERM The calling process is already a process group leader, or the process group ID of a process other than the calling process matches the process ID of the calling process. I don't think the semantics of `pgmembers()` lines up with that description. I think a simple `pgfind()` is what is needed. Resources ========= https://blog.nelhage.com/2011/02/changing-ctty/ http://uw714doc.sco.com/en/SDK_sysprog/_The_Controlling-Terminal_and_Pr.html