svn commit: r273936 - head/contrib/netbsd-tests/lib/libc/net
Garrett Cooper
ngie at FreeBSD.org
Sat Nov 1 17:14:30 UTC 2014
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];
More information about the svn-src-head
mailing list