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__);

Reply via email to