[SCM] Socket Wrapper Repository - branch master updated

Michael Adam obnox at samba.org
Sun Jun 1 02:06:09 MDT 2014


The branch, master has been updated
       via  9e91b00 tests: add new test test_bind_ipv4_addr_in_use()
       via  0c3efeb tests: extend the ipv6 bind test
       via  a14a1af tests: greatly extend the ipv4 bind test
       via  f38c0b4 swrap: check whether an address:port is already in use in swrap_bind()
       via  da04f94 swrap: implement check_addr_port_in_use()
       via  f04ea32 swrap: fix AF_UNSPEC special case in swrap_bind()
       via  97a65a1 swrap: extend input checks in swrap_bind()
       via  af40930 Update the todo list.
       via  b357525 tests: Avoid using getenv() to retrieve the path.
       via  3029067 swrap: add check for rpc/rpc.h - needed on freebsd for bindresvport
       via  0025857 tests: Add tests for bindresvport().
       via  ccf4e64 swrap: Add support for bindresvport().
       via  b124fcb tests: Add tests for bind().
       via  45eb7c9 swrap: Add missing family check in bind().
       via  37b472d tests: Add test that getsockname is correct after socket().
       via  bdbbf38 swrap: Setup myname in swrap_socket() for getsockname().
       via  205d5c2 torture: Wait for the pidfile and then start the tests.
       via  323feb7 echo_srv: Write pidfile after we setup the listeners.
      from  1dbbd72 README.install: improvements and fixes.

http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9e91b00ee329578987c579b2c9d6db967055a59a
Author: Michael Adam <obnox at samba.org>
Date:   Sat May 31 03:35:22 2014 +0200

    tests: add new test test_bind_ipv4_addr_in_use()
    
    This tests binding an address that is already in use.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 0c3efeb3b07083e36068e354b20208316d02c79a
Author: Michael Adam <obnox at samba.org>
Date:   Sat May 31 03:31:56 2014 +0200

    tests: extend the ipv6 bind test
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a14a1afe966a45000fa768df43a25d84a68772dd
Author: Michael Adam <obnox at samba.org>
Date:   Sat May 31 03:31:29 2014 +0200

    tests: greatly extend the ipv4 bind test
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f38c0b43d5620ab6457bf8a4fbdaf3a7bf90627c
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 30 14:20:40 2014 +0200

    swrap: check whether an address:port is already in use in swrap_bind()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit da04f94dd0575245424cf7853d0a9fc5b7caacee
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 30 14:20:17 2014 +0200

    swrap: implement check_addr_port_in_use()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f04ea324f6079e74532ee1ae085945097073a305
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 30 13:21:00 2014 +0200

    swrap: fix AF_UNSPEC special case in swrap_bind()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 97a65a132d1b14cbfd539f327f260237c1afff3d
Author: Michael Adam <obnox at samba.org>
Date:   Fri May 30 13:06:02 2014 +0200

    swrap: extend input checks in swrap_bind()
    
    Not only check family, but depending on family, also check the length.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit af40930bebe0322d5876bda2aa36598e1bae2056
Author: Andreas Schneider <asn at samba.org>
Date:   Wed May 28 10:04:04 2014 +0200

    Update the todo list.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit b357525a2958e394fceb8c7b6165b572e944e8f2
Author: Andreas Schneider <asn at samba.org>
Date:   Wed May 28 09:46:57 2014 +0200

    tests: Avoid using getenv() to retrieve the path.
    
    CID 17221
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 3029067b21775c1f6fec43e0b03712defa69e9a6
Author: Michael Adam <obnox at samba.org>
Date:   Sun Jun 1 01:48:15 2014 +0200

    swrap: add check for rpc/rpc.h - needed on freebsd for bindresvport
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 00258577e86f4b6c15d504954ee6233086638a3e
Author: Andreas Schneider <asn at samba.org>
Date:   Wed May 28 09:46:40 2014 +0200

    tests: Add tests for bindresvport().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit ccf4e64fe7bf788c17ca1a41e456e3b9ecdcb85b
Author: Andreas Schneider <asn at samba.org>
Date:   Tue May 20 20:04:02 2014 +0200

    swrap: Add support for bindresvport().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit b124fcb2dfb6193f198bd47891c3286e527bd530
Author: Andreas Schneider <asn at samba.org>
Date:   Wed May 21 09:15:10 2014 +0200

    tests: Add tests for bind().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 45eb7c9070fdd99b63fe01d31e26616d8f047f71
Author: Andreas Schneider <asn at samba.org>
Date:   Wed May 21 08:30:53 2014 +0200

    swrap: Add missing family check in bind().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 37b472d7972f0d18bd343137d4991f5e091a2ed7
Author: Andreas Schneider <asn at samba.org>
Date:   Tue May 27 20:53:51 2014 +0200

    tests: Add test that getsockname is correct after socket().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit bdbbf3853c644da05e1fd74c523380a846394cec
Author: Andreas Schneider <asn at samba.org>
Date:   Tue May 27 20:43:51 2014 +0200

    swrap: Setup myname in swrap_socket() for getsockname().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 205d5c2348a5ae4858c2fe07a8b3080b19c900be
Author: Andreas Schneider <asn at samba.org>
Date:   Fri May 30 13:59:43 2014 +0200

    torture: Wait for the pidfile and then start the tests.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 323feb7398527294d1102e24470c0761b1661d99
Author: Andreas Schneider <asn at samba.org>
Date:   Fri May 30 13:57:25 2014 +0200

    echo_srv: Write pidfile after we setup the listeners.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 ConfigureChecks.cmake        |    5 +
 TODO                         |    7 +-
 config.h.cmake               |    2 +
 src/socket_wrapper.c         |  287 ++++++++++++++++++++++++
 tests/CMakeLists.txt         |    2 +
 tests/echo_srv.c             |   20 +-
 tests/test_echo_tcp_bind.c   |  494 ++++++++++++++++++++++++++++++++++++++++++
 tests/test_echo_tcp_socket.c |   69 ++++++
 tests/test_ioctl.c           |   14 +-
 tests/torture.c              |   14 +-
 10 files changed, 896 insertions(+), 18 deletions(-)
 create mode 100644 tests/test_echo_tcp_bind.c
 create mode 100644 tests/test_echo_tcp_socket.c


Changeset truncated at 500 lines:

diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 3a31f50..df65411 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -52,6 +52,7 @@ check_include_file(sys/signalfd.h HAVE_SYS_SIGNALFD_H)
 check_include_file(sys/eventfd.h HAVE_SYS_EVENTFD_H)
 check_include_file(sys/timerfd.h HAVE_SYS_TIMERFD_H)
 check_include_file(gnu/lib-names.h HAVE_GNU_LIB_NAMES_H)
+check_include_file(rpc/rpc.h HAVE_RPC_RPC_H)
 
 # FUNCTIONS
 check_function_exists(strncpy HAVE_STRNCPY)
@@ -60,6 +61,10 @@ check_function_exists(snprintf HAVE_SNPRINTF)
 check_function_exists(signalfd HAVE_SIGNALFD)
 check_function_exists(eventfd HAVE_EVENTFD)
 check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
+set(CMAKE_REQUIRED_FLAGS -D_GNU_SOURCE)
+check_function_exists(bindresvport HAVE_BINDRESVPORT)
+set(CMAKE_REQUIRED_FLAGS)
+
 
 if (UNIX)
     if (NOT LINUX)
diff --git a/TODO b/TODO
index 205cfaf..fe05c75 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,14 @@
 TODO
 =====
 
+This is the TODO list of this project. It should give you some hints of things
+which need to be implemented. If you can spend some time on this project, then
+look at the list below.
+
+
 Library:
 ---------
 
-* Add IP_PKTINFO support for sendmsg/recvmsg.
 * Add support for fd passing in sendmsg/recvmsg.
   Scenario:
   We accept a connection from a client and need to pass the fd to another
@@ -12,6 +16,7 @@ Library:
   to the child first and set it up there.
   Or do it like swrap_accept() and call getpeername() and getsockname().
 * Add support for threading.
+* Use realpath() in socket_wrapper_dir().
 
 Testing:
 ---------
diff --git a/config.h.cmake b/config.h.cmake
index 02c016e..466b951 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -19,6 +19,7 @@
 #cmakedefine HAVE_SYS_EVENTFD_H 1
 #cmakedefine HAVE_SYS_TIMERFD_H 1
 #cmakedefine HAVE_GNU_LIB_NAMES_H 1
+#cmakedefine HAVE_RPC_RPC_H 1
 
 /**************************** STRUCTS ****************************/
 
@@ -37,6 +38,7 @@
 #cmakedefine HAVE_SIGNALFD 1
 #cmakedefine HAVE_EVENTFD 1
 #cmakedefine HAVE_TIMERFD_CREATE 1
+#cmakedefine HAVE_BINDRESVPORT 1
 
 #cmakedefine HAVE_ACCEPT_PSOCKLEN_T 1
 #cmakedefine HAVE_IOCTL_INT 1
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index b8b1ca3..f6adc95 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -76,6 +76,9 @@
 #ifdef HAVE_GNU_LIB_NAMES_H
 #include <gnu/lib-names.h>
 #endif
+#ifdef HAVE_RPC_RPC_H
+#include <rpc/rpc.h>
+#endif
 
 enum swrap_dbglvl_e {
 	SWRAP_LOG_ERROR = 0,
@@ -111,6 +114,13 @@ enum swrap_dbglvl_e {
 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
 #endif
 
+#ifndef ZERO_STRUCTP
+#define ZERO_STRUCTP(x) do { \
+		if ((x) != NULL) \
+			memset((char *)(x), 0, sizeof(*(x))); \
+	} while(0)
+#endif
+
 #ifndef discard_const
 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
 #endif
@@ -843,6 +853,7 @@ static const char *socket_wrapper_dir(void)
 	if (s == NULL) {
 		return NULL;
 	}
+	/* TODO use realpath(3) here, when we add support for threads */
 	if (strncmp(s, "./", 2) == 0) {
 		s += 2;
 	}
@@ -1256,6 +1267,89 @@ static struct socket_info *find_socket_info(int fd)
 	return NULL;
 }
 
+static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
+{
+	struct socket_info *s;
+
+	/* first catch invalid input */
+	switch (sa->sa_family) {
+	case AF_INET:
+		if (len < sizeof(struct sockaddr_in)) {
+			return false;
+		}
+		break;
+#if HAVE_IPV6
+	case AF_INET6:
+		if (len < sizeof(struct sockaddr_in6)) {
+			return false;
+		}
+		break;
+#endif
+	default:
+		return false;
+		break;
+	}
+
+	for (s = sockets; s != NULL; s = s->next) {
+		if (s->myname == NULL) {
+			continue;
+		}
+		if (s->myname->sa_family != sa->sa_family) {
+			continue;
+		}
+		switch (s->myname->sa_family) {
+		case AF_INET: {
+			struct sockaddr_in *sin1, *sin2;
+
+			sin1 = (struct sockaddr_in *)s->myname;
+			sin2 = (struct sockaddr_in *)sa;
+
+			if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
+				continue;
+			}
+			if (sin1->sin_port != sin2->sin_port) {
+				continue;
+			}
+			if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
+				continue;
+			}
+
+			/* found */
+			return true;
+			break;
+		}
+#if HAVE_IPV6
+		case AF_INET6: {
+			struct sockaddr_in6 *sin1, *sin2;
+
+			sin1 = (struct sockaddr_in6 *)s->myname;
+			sin2 = (struct sockaddr_in6 *)sa;
+
+			if (sin1->sin6_port != sin2->sin6_port) {
+				continue;
+			}
+			if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
+						&sin2->sin6_addr))
+			{
+				continue;
+			}
+
+			/* found */
+			return true;
+			break;
+		}
+#endif
+		default:
+			continue;
+			break;
+
+		}
+	}
+
+	return false;
+}
+
+
 static void swrap_remove_stale(int fd)
 {
 	struct socket_info *si = find_socket_info(fd);
@@ -1298,6 +1392,26 @@ static int sockaddr_convert_to_un(struct socket_info *si,
 #endif
 
 	switch (in_addr->sa_family) {
+	case AF_UNSPEC: {
+		struct sockaddr_in *sin;
+		if (si->family != AF_INET) {
+			break;
+		}
+		if (in_len < sizeof(struct sockaddr_in)) {
+			break;
+		}
+		sin = (struct sockaddr_in *)in_addr;
+		if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
+			break;
+		}
+
+		/*
+		 * Note: in the special case of AF_UNSPEC and INADDR_ANY,
+		 * AF_UNSPEC is mapped to AF_INET and must be treated here.
+		 */
+
+		/* FALL THROUGH */
+	}
 	case AF_INET:
 #ifdef HAVE_IPV6
 	case AF_INET6:
@@ -2223,8 +2337,40 @@ static int swrap_socket(int family, int type, int protocol)
 	si->type = real_type;
 	si->protocol = protocol;
 
+	/*
+	 * Setup myname so getsockname() can succeed to find out the socket
+	 * type.
+	 */
+	switch(si->family) {
+	case AF_INET: {
+		struct sockaddr_in sin = {
+			.sin_family = AF_INET,
+		};
+
+		si->myname_len = sizeof(struct sockaddr_in);
+		si->myname = sockaddr_dup(&sin, si->myname_len);
+		break;
+	}
+	case AF_INET6: {
+		struct sockaddr_in6 sin6 = {
+			.sin6_family = AF_INET6,
+		};
+
+		si->myname_len = sizeof(struct sockaddr_in6);
+		si->myname = sockaddr_dup(&sin6, si->myname_len);
+		break;
+	}
+	default:
+		free(si);
+		errno = EINVAL;
+		return -1;
+	}
+
 	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
 	if (fi == NULL) {
+		if (si->myname != NULL) {
+			free (si->myname);
+		}
 		free(si);
 		errno = ENOMEM;
 		return -1;
@@ -2503,6 +2649,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 		in.sin_addr.s_addr = htonl(127<<24 | 
 					   socket_wrapper_default_iface());
 
+		free(si->myname);
 		si->myname_len = sizeof(in);
 		si->myname = sockaddr_dup(&in, si->myname_len);
 		break;
@@ -2532,6 +2679,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 		in6.sin6_family = AF_INET6;
 		in6.sin6_addr = *swrap_ipv6();
 		in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
+		free(si->myname);
 		si->myname_len = sizeof(in6);
 		si->myname = sockaddr_dup(&in6, si->myname_len);
 		break;
@@ -2680,11 +2828,70 @@ static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 	int ret;
 	struct sockaddr_un un_addr;
 	struct socket_info *si = find_socket_info(s);
+	int bind_error = 0;
+	bool in_use;
 
 	if (!si) {
 		return libc_bind(s, myaddr, addrlen);
 	}
 
+	switch (si->family) {
+	case AF_INET: {
+		const struct sockaddr_in *sin;
+		if (addrlen < sizeof(struct sockaddr_in)) {
+			bind_error = EINVAL;
+			break;
+		}
+
+		sin = (struct sockaddr_in *)myaddr;
+
+		if (sin->sin_family != AF_INET) {
+			bind_error = EAFNOSUPPORT;
+		}
+
+		/* special case for AF_UNSPEC */
+		if (sin->sin_family == AF_UNSPEC &&
+		    (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
+		{
+			bind_error = 0;
+		}
+
+		break;
+	}
+#ifdef HAVE_IPV6
+	case AF_INET6: {
+		const struct sockaddr_in6 *sin6;
+		if (addrlen < sizeof(struct sockaddr_in6)) {
+			bind_error = EINVAL;
+			break;
+		}
+
+		sin6 = (struct sockaddr_in6 *)myaddr;
+
+		if (sin6->sin6_family != AF_INET6) {
+			bind_error = EAFNOSUPPORT;
+		}
+
+		break;
+	}
+#endif
+	default:
+		bind_error = EINVAL;
+		break;
+	}
+
+	if (bind_error != 0) {
+		errno = bind_error;
+		return -1;
+	}
+
+	in_use = check_addr_port_in_use(myaddr, addrlen);
+	if (in_use) {
+		errno = EADDRINUSE;
+		return -1;
+	}
+
+	free(si->myname);
 	si->myname_len = addrlen;
 	si->myname = sockaddr_dup(myaddr, addrlen);
 
@@ -2713,6 +2920,86 @@ int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 }
 
 /****************************************************************************
+ *   BINDRESVPORT
+ ***************************************************************************/
+
+#ifdef HAVE_BINDRESVPORT
+static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
+
+static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
+{
+	struct sockaddr_storage myaddr;
+	socklen_t salen;
+	static uint16_t port;
+	uint16_t i;
+	int rc = -1;
+	int af;
+
+#define SWRAP_STARTPORT 600
+#define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
+#define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
+
+	if (port == 0) {
+		port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
+	}
+
+	if (sa == NULL) {
+		salen = sizeof(struct sockaddr);
+		sa = (struct sockaddr *)&myaddr;
+
+		rc = swrap_getsockname(sd, (struct sockaddr *)&myaddr, &salen);
+		if (rc < 0) {
+			return -1;
+		}
+
+		af = sa->sa_family;
+		memset(&myaddr, 0, salen);
+	} else {
+		af = sa->sa_family;
+	}
+
+	for (i = 0; i < SWRAP_NPORTS; i++, port++) {
+		switch(af) {
+		case AF_INET: {
+			struct sockaddr_in *sinp = (struct sockaddr_in *)sa;
+
+			salen = sizeof(struct sockaddr_in);
+			sinp->sin_port = htons(port);
+			break;
+		}
+		case AF_INET6: {
+			struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)sa;
+
+			salen = sizeof(struct sockaddr_in6);
+			sin6p->sin6_port = htons(port);
+			break;
+		}
+		default:
+			errno = EAFNOSUPPORT;
+			return -1;
+		}
+		sa->sa_family = af;
+
+		if (port > SWRAP_ENDPORT) {
+			port = SWRAP_STARTPORT;
+		}
+
+		rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
+		if (rc == 0 || errno != EADDRINUSE) {
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int bindresvport(int sockfd, struct sockaddr_in *sinp)
+{
+	return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
+}
+#endif
+
+/****************************************************************************
  *   LISTEN
  ***************************************************************************/
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 287539b..d3a4156 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -20,7 +20,9 @@ target_link_libraries(${TORTURE_LIBRARY}
 
 set(SWRAP_TESTS
     test_ioctl
+    test_echo_tcp_socket
     test_echo_tcp_connect
+    test_echo_tcp_bind
     test_echo_tcp_socket_options
     test_echo_tcp_write_read
     test_echo_tcp_writev_readv
diff --git a/tests/echo_srv.c b/tests/echo_srv.c
index 88d8170..e3973f5 100644
--- a/tests/echo_srv.c
+++ b/tests/echo_srv.c
@@ -153,7 +153,7 @@ static int pidfile(const char *path)
     return 0;
 }
 
-static int become_daemon(struct echo_srv_opts *opts)
+static int become_daemon(void)
 {
     int ret;
     pid_t child_pid;
@@ -178,13 +178,6 @@ static int become_daemon(struct echo_srv_opts *opts)
     chdir(WORKING_DIR);
 #endif
 
-    ret = pidfile(opts->pidfile);
-    if (ret != 0) {
-        fprintf(stderr, "Cannot create pidfile %s: %s\n",
-                        opts->pidfile, strerror(ret));
-        return ret;
-    }
-
     ret = setsid();
     if (ret == -1) {
         ret = errno;
@@ -895,7 +888,7 @@ int main(int argc, char **argv)
     }
 
     if (opts.daemon) {
-        ret = become_daemon(&opts);
+        ret = become_daemon();
         if (ret != 0) {
             fprintf(stderr, "Cannot become daemon: %s\n", strerror(ret));
             goto done;
@@ -908,6 +901,15 @@ int main(int argc, char **argv)
         goto done;
     }
 
+    if (opts.daemon && opts.pidfile != NULL) {
+        ret = pidfile(opts.pidfile);
+        if (ret != 0) {
+            fprintf(stderr, "Cannot create pidfile %s: %s\n",
+                    opts.pidfile, strerror(ret));
+            goto done;
+        }


-- 
Socket Wrapper Repository


More information about the samba-cvs mailing list