Author: ngie
Date: Sat Nov  1 17:14:29 2014
New Revision: 273936
URL: https://svnweb.freebsd.org/changeset/base/273936

Log:
  Port lib/libc/net/h_dns_server to FreeBSD
  
  Submitted by: pho

Modified:
  head/contrib/netbsd-tests/lib/libc/net/h_dns_server.c

Modified: head/contrib/netbsd-tests/lib/libc/net/h_dns_server.c
==============================================================================
--- head/contrib/netbsd-tests/lib/libc/net/h_dns_server.c       Sat Nov  1 
17:13:13 2014        (r273935)
+++ head/contrib/netbsd-tests/lib/libc/net/h_dns_server.c       Sat Nov  1 
17:14:29 2014        (r273936)
@@ -49,7 +49,13 @@ __RCSID("$NetBSD: h_dns_server.c,v 1.4 2
 #include <sys/socket.h>
 
 #include <netinet/in.h>
+#ifdef __NetBSD__
 #include <netinet6/in6.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <paths.h>
+#endif
 
 union sockaddr_either {
        struct sockaddr s;
@@ -164,6 +170,106 @@ name2str(const void *v, char *buf, size_
 }
 #endif
 
+#ifdef __FreeBSD__
+/* XXX the daemon2_* functions should be in a library */
+
+int __daemon2_detach_pipe[2];
+
+static int
+daemon2_fork(void)
+{
+       int r;
+       int fd;
+       int i;
+
+       /*
+        * Set up the pipe, making sure the write end does not
+        * get allocated one of the file descriptors that will
+        * be closed in daemon2_detach().
+        */
+       for (i = 0; i < 3; i++) {
+           r = pipe(__daemon2_detach_pipe);
+           if (r < 0)
+                   return -1;
+           if (__daemon2_detach_pipe[1] <= STDERR_FILENO &&
+               (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+                   (void)dup2(fd, __daemon2_detach_pipe[0]);
+                   (void)dup2(fd, __daemon2_detach_pipe[1]);
+                   if (fd > STDERR_FILENO)
+                           (void)close(fd);
+                   continue;
+           }
+           break;
+       }
+
+       r = fork();
+       if (r < 0) {
+               return -1;
+       } else if (r == 0) {
+               /* child */
+               close(__daemon2_detach_pipe[0]);
+               return 0;
+       }
+       /* Parent */
+
+       (void) close(__daemon2_detach_pipe[1]);
+
+       for (;;) {
+              char dummy;
+              r = read(__daemon2_detach_pipe[0], &dummy, 1);
+              if (r < 0) {
+                      if (errno == EINTR)
+                              continue;
+                      _exit(1);
+              } else if (r == 0) {
+                      _exit(1);
+              } else { /* r > 0 */
+                      _exit(0);
+              }
+       }
+}
+
+static int
+daemon2_detach(int nochdir, int noclose)
+{
+       int r;
+       int fd;
+
+       if (setsid() == -1)
+               return -1;
+
+       if (!nochdir)
+               (void)chdir("/");
+
+       if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+               (void)dup2(fd, STDIN_FILENO);
+               (void)dup2(fd, STDOUT_FILENO);
+               (void)dup2(fd, STDERR_FILENO);
+               if (fd > STDERR_FILENO)
+                       (void)close(fd);
+       }
+
+       while (1) {
+               r = write(__daemon2_detach_pipe[1], "", 1);
+               if (r < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       /* May get "broken pipe" here if parent is killed */
+                       return -1;
+               } else if (r == 0) {
+                       /* Should not happen */
+                       return -1;
+               } else {
+                       break;
+               }
+       }
+
+       (void) close(__daemon2_detach_pipe[1]);
+
+       return 0;
+}
+#endif
+
 int main(int argc, char **argv) {
        int s, r, protocol;
        union sockaddr_either saddr;
@@ -176,6 +282,9 @@ int main(int argc, char **argv) {
        char buf1[1024], buf2[1024];
 #endif
 
+#ifdef __FreeBSD__
+       daemon2_fork();
+#endif
        if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6'))
                errx(1, "usage: dns_server 4 | 6");
        s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, 
IPPROTO_UDP);
@@ -212,11 +321,19 @@ int main(int argc, char **argv) {
        f = fopen(pidfile_name, "w");
        fprintf(f, "%d", getpid());
        fclose(f);
+#ifdef __FreeBSD__
+#ifdef DEBUG
+       daemon2_detach(0, 1);
+#else
+       daemon2_detach(0, 0);
+#endif
+#else
 #ifdef DEBUG
        daemon(0, 1);
 #else
        daemon(0, 0);
 #endif
+#endif
 
        for (;;) {
                unsigned char buf[512];
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to