This diff is an improvement and an attempt to fix the bug where the ntpd(8) not always stays running.
During the review of syslogd fork+exec diff I noticed the use of dup3() and went to read its man page: dup2() doesn't always remove the CLOEXEC flag from the descriptor, so using dup3() is a better idea because it does check the flag and if the oldd == newd then it retuns an useful error. So if dup3() returns us an error it means oldd == newd and we should remove the CLOEXEC flag ourself. ok? Index: util.c =================================================================== RCS file: /home/obsdcvs/src/usr.sbin/ntpd/util.c,v retrieving revision 1.22 diff -u -p -r1.22 util.c --- util.c 14 Sep 2016 13:20:16 -0000 1.22 +++ util.c 2 Oct 2016 18:31:41 -0000 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <errno.h> +#include <fcntl.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -184,7 +186,12 @@ start_child(char *pname, int cfd, int ar break; case 0: /* Prepare the parent socket and execute. */ - dup2(cfd, PARENT_SOCK_FILENO); + if (dup3(cfd, PARENT_SOCK_FILENO, 0) == -1) { + if (errno != EINVAL) + fatal("%s: dup3", __func__); + if (fcntl(cfd, F_SETFD, 0) == -1) + fatal("%s: fcntl", __func__); + } execvp(argv[0], nargv); fatal("%s: execvp", __func__);