[master] dcce66a Implement the vtc server and client commands for Unix domain sockets.
Geoff Simmons
geoff at uplex.de
Fri Feb 16 11:02:02 UTC 2018
commit dcce66a62c99cfe9697f196bd24272d8c32db10b
Author: Geoff Simmons <geoff at uplex.de>
Date: Thu Feb 15 20:02:30 2018 +0100
Implement the vtc server and client commands for Unix domain sockets.
This adds the VUS interface to libvarnish.
UDS code corresponding to VTCP_open() and VTCP_listen_on() is
implemented in the vtc code, since it will only ever be used
there.
diff --git a/bin/varnishtest/tests/a00002.vtc b/bin/varnishtest/tests/a00002.vtc
index 2aa6f64..2d8c755 100644
--- a/bin/varnishtest/tests/a00002.vtc
+++ b/bin/varnishtest/tests/a00002.vtc
@@ -21,3 +21,24 @@ client c1 -connect ${s1_sock} {
client c1 -run
server s1 -wait
+
+# The same tests with unix domain sockets
+server s2 -listen "${tmpdir}/s2.sock" {
+ rxreq
+ expect req.method == PUT
+ expect req.proto == HTTP/1.0
+ expect req.url == "/foo"
+ txresp -proto HTTP/1.2 -status 201 -reason Foo
+} -start
+
+client c2 -connect ${s2_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c2 -run
+
+server s2 -wait
diff --git a/bin/varnishtest/tests/a00003.vtc b/bin/varnishtest/tests/a00003.vtc
index 8855dba..7962eef 100644
--- a/bin/varnishtest/tests/a00003.vtc
+++ b/bin/varnishtest/tests/a00003.vtc
@@ -43,3 +43,48 @@ client c2 -wait
server s1 -wait
server s2 -wait
+
+# The same tests with Unix domain sockets
+server s3 -listen "${tmpdir}/s3.sock" {
+ rxreq
+ expect req.method == PUT
+ expect req.proto == HTTP/1.0
+ expect req.url == "/foo"
+ txresp -proto HTTP/1.2 -status 201 -reason Foo
+}
+
+server s4 -listen "${tmpdir}/s4.sock" {
+ rxreq
+ expect req.method == GET
+ expect req.proto == HTTP/1.1
+ expect req.url == "/"
+ txresp
+}
+
+server s3 -start
+server s4 -start
+
+client c3 -connect ${s3_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c4 -connect ${s4_sock} {
+ txreq
+ rxresp
+ expect resp.proto == HTTP/1.1
+ expect resp.status == 200
+ expect resp.reason == OK
+}
+
+client c3 -start
+client c4 -start
+
+client c3 -wait
+client c4 -wait
+
+server s3 -wait
+server s4 -wait
diff --git a/bin/varnishtest/tests/a00004.vtc b/bin/varnishtest/tests/a00004.vtc
index be185a6..05474f6 100644
--- a/bin/varnishtest/tests/a00004.vtc
+++ b/bin/varnishtest/tests/a00004.vtc
@@ -33,3 +33,38 @@ client c1 -wait
client c2 -wait
server s1 -wait
+
+# The same tests with Unix domain sockets
+server s2 -repeat 2 -listen "${tmpdir}/s2.sock" {
+ rxreq
+ expect req.method == PUT
+ expect req.proto == HTTP/1.0
+ expect req.url == "/foo"
+ txresp -proto HTTP/1.2 -status 201 -reason Foo
+}
+
+server s2 -start
+
+client c3 -connect ${s2_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c4 -connect ${s2_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c3 -start
+client c4 -start
+
+client c3 -wait
+client c4 -wait
+
+server s2 -wait
diff --git a/bin/varnishtest/tests/a00005.vtc b/bin/varnishtest/tests/a00005.vtc
index 7de7675..fe4885f 100644
--- a/bin/varnishtest/tests/a00005.vtc
+++ b/bin/varnishtest/tests/a00005.vtc
@@ -41,3 +41,46 @@ client c1 -run
server s1 -wait
server s2 -wait
+
+# The same tests with unix domain sockets
+server s3 -listen "${tmpdir}/s3.sock" {
+ rxreq
+ expect req.method == PUT
+ expect req.proto == HTTP/1.0
+ expect req.url == "/foo"
+ txresp -proto HTTP/1.2 -status 201 -reason Foo
+}
+
+server s4 -listen "${tmpdir}/s4.sock" {
+ rxreq
+ expect req.method == GET
+ expect req.proto == HTTP/1.1
+ expect req.url == "/"
+ txresp
+}
+
+server s3 -start
+server s4 -start
+
+client c2 -connect ${s3_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c2 -run
+
+client c2 -connect ${s4_sock} {
+ txreq
+ rxresp
+ expect resp.proto == HTTP/1.1
+ expect resp.status == 200
+ expect resp.reason == OK
+}
+
+client c2 -run
+
+server s3 -wait
+server s4 -wait
diff --git a/bin/varnishtest/tests/a00006.vtc b/bin/varnishtest/tests/a00006.vtc
index c01522d..2ca486b 100644
--- a/bin/varnishtest/tests/a00006.vtc
+++ b/bin/varnishtest/tests/a00006.vtc
@@ -23,3 +23,28 @@ client c1 -connect ${s1_sock} {
client c1 -run
server s1 -wait
+
+# The same tests with Unix domain sockets
+server s2 -listen "${tmpdir}/s2.sock" {
+ rxreq
+ expect req.method == PUT
+ expect req.proto == HTTP/1.0
+ expect req.url == "/foo"
+ txresp -proto HTTP/1.2 -status 201 -reason Foo \
+ -body "987654321\n"
+}
+
+server s2 -start
+
+client c2 -connect ${s2_sock} {
+ txreq -req PUT -proto HTTP/1.0 -url /foo \
+ -body "123456789\n"
+ rxresp
+ expect resp.proto == HTTP/1.2
+ expect resp.status == 201
+ expect resp.reason == Foo
+}
+
+client c2 -run
+
+server s2 -wait
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 6e99403..b404552 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -93,7 +93,8 @@ extern int feature_dns;
void init_server(void);
-int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd);
+int http_process(struct vtclog *vl, const char *spec, int sock, int *sfd,
+ const char *addr);
char * synth_body(const char *len, int rnd);
diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c
index 167d80c..754d4ec 100644
--- a/bin/varnishtest/vtc_client.c
+++ b/bin/varnishtest/vtc_client.c
@@ -29,17 +29,21 @@
#include "config.h"
#include <sys/socket.h>
+#include <sys/un.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <poll.h>
+#include <unistd.h>
#include "vtc.h"
#include "vsa.h"
#include "vss.h"
#include "vtcp.h"
+#include "vus.h"
struct client {
unsigned magic;
@@ -106,6 +110,83 @@ client_proxy(struct vtclog *vl, int fd, int version, const char *spec)
}
/**********************************************************************
+ * Socket connect.
+ */
+
+static int
+client_tcp_connect(struct vtclog *vl, const char *addr, double tmo,
+ const char **errp)
+{
+ int fd;
+ char mabuf[32], mpbuf[32];
+
+ fd = VTCP_open(addr, NULL, tmo, errp);
+ if (fd < 0)
+ return fd;
+ VTCP_myname(fd, mabuf, sizeof mabuf, mpbuf, sizeof mpbuf);
+ vtc_log(vl, 3, "connected fd %d from %s %s to %s", fd, mabuf, mpbuf,
+ addr);
+ return fd;
+}
+
+/* cf. VTCP_Open() */
+static int v_matchproto_(vus_resolved_f)
+uds_open(void *priv, const struct sockaddr_un *uds)
+{
+ double *p, tmo;
+ int s, i;
+ struct pollfd fds[1];
+ socklen_t sl = sizeof(*uds);
+
+ AN(priv);
+ AN(uds);
+ p = priv;
+ assert(*p > 0.);
+ tmo = *p * 1e3;
+
+ s = socket(uds->sun_family, SOCK_STREAM, 0);
+ if (s < 0)
+ return (s);
+
+ (void) VTCP_nonblocking(s);
+ i = connect(s, uds, sl);
+ if (i == 0)
+ return(s);
+ if (errno != EINPROGRESS) {
+ closefd(&s);
+ return (-1);
+ }
+
+ fds[0].fd = s;
+ fds[0].events = POLLWRNORM;
+ fds[0].revents = 0;
+ i = poll(fds, 1, tmo);
+
+ if (i == 0) {
+ closefd(&s);
+ errno = ETIMEDOUT;
+ return (-1);
+ }
+
+ return (VTCP_connected(s));
+}
+
+static int
+client_uds_connect(struct vtclog *vl, const char *path, double tmo,
+ const char **errp)
+{
+ int fd;
+
+ assert(tmo >= 0);
+
+ fd = VUS_resolver(path, uds_open, &tmo, errp);
+ if (fd < 0)
+ return fd;
+ vtc_log(vl, 3, "connected fd %d to %s", fd, path);
+ return fd;
+}
+
+/**********************************************************************
* Client thread
*/
@@ -117,7 +198,6 @@ client_thread(void *priv)
int fd;
unsigned u;
struct vsb *vsb;
- char mabuf[32], mpbuf[32];
const char *err;
CAST_OBJ_NOTNULL(c, priv, CLIENT_MAGIC);
@@ -133,20 +213,21 @@ client_thread(void *priv)
if (c->repeat != 1)
vtc_log(vl, 2, "Started (%u iterations)", c->repeat);
for (u = 0; u < c->repeat; u++) {
- vtc_log(vl, 3, "Connect to %s", VSB_data(vsb));
- fd = VTCP_open(VSB_data(vsb), NULL, 10., &err);
+ char *addr = VSB_data(vsb);
+
+ vtc_log(vl, 3, "Connect to %s", addr);
+ if (*addr == '/')
+ fd = client_uds_connect(vl, addr, 10., &err);
+ else
+ fd = client_tcp_connect(vl, VSB_data(vsb), 10., &err);
if (fd < 0)
vtc_fatal(c->vl, "Failed to open %s: %s",
VSB_data(vsb), err);
- assert(fd >= 0);
/* VTCP_blocking does its own checks, trust it */
(void)VTCP_blocking(fd);
- VTCP_myname(fd, mabuf, sizeof mabuf, mpbuf, sizeof mpbuf);
- vtc_log(vl, 3, "connected fd %d from %s %s to %s",
- fd, mabuf, mpbuf, VSB_data(vsb));
if (c->proxy_spec != NULL)
client_proxy(vl, fd, c->proxy_version, c->proxy_spec);
- fd = http_process(vl, c->spec, fd, NULL);
+ fd = http_process(vl, c->spec, fd, NULL, addr);
vtc_log(vl, 3, "closing fd %d", fd);
VTCP_close(&fd);
}
diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c
index c65139b..62df449 100644
--- a/bin/varnishtest/vtc_http.c
+++ b/bin/varnishtest/vtc_http.c
@@ -1840,7 +1840,8 @@ const struct cmds http_cmds[] = {
};
int
-http_process(struct vtclog *vl, const char *spec, int sock, int *sfd)
+http_process(struct vtclog *vl, const char *spec, int sock, int *sfd,
+ const char *addr)
{
struct http *hp;
int retval;
@@ -1870,8 +1871,13 @@ http_process(struct vtclog *vl, const char *spec, int sock, int *sfd)
hp->gziplevel = 0;
hp->gzipresidual = -1;
- VTCP_hisname(sock,
- hp->rem_ip, VTCP_ADDRBUFSIZE, hp->rem_port, VTCP_PORTBUFSIZE);
+ if (*addr != '/')
+ VTCP_hisname(sock, hp->rem_ip, VTCP_ADDRBUFSIZE, hp->rem_port,
+ VTCP_PORTBUFSIZE);
+ else {
+ strcpy(hp->rem_ip, "0.0.0.0");
+ strcpy(hp->rem_port, "0");
+ }
parse_string(spec, http_cmds, hp, vl);
if (hp->h2)
stop_h2(hp);
diff --git a/bin/varnishtest/vtc_server.c b/bin/varnishtest/vtc_server.c
index fb811df..a0e531a 100644
--- a/bin/varnishtest/vtc_server.c
+++ b/bin/varnishtest/vtc_server.c
@@ -29,15 +29,19 @@
#include "config.h"
#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "vtc.h"
#include "vtcp.h"
+#include "vus.h"
struct server {
unsigned magic;
@@ -114,6 +118,81 @@ server_delete(struct server *s)
* Server listen
*/
+struct helper {
+ int depth;
+ const char **errp;
+};
+
+/* cf. VTCP_listen_on() */
+static int v_matchproto_(vus_resolved_f)
+uds_listen(void *priv, const struct sockaddr_un *uds)
+{
+ int sock, e;
+ struct helper *hp = priv;
+
+ sock = VUS_bind(uds, hp->errp);
+ if (sock >= 0) {
+ if (listen(sock, hp->depth) != 0) {
+ e = errno;
+ closefd(&sock);
+ errno = e;
+ if (hp->errp != NULL)
+ *hp->errp = "listen(2)";
+ return (-1);
+ }
+ }
+ if (sock > 0) {
+ *hp->errp = NULL;
+ return (sock);
+ }
+ AN(*hp->errp);
+ return (0);
+}
+
+static void
+server_listen_uds(struct server *s, const char **errp)
+{
+ mode_t m;
+ struct helper h;
+
+ h.depth = s->depth;
+ h.errp = errp;
+
+ errno = 0;
+ if (unlink(s->listen) != 0 && errno != ENOENT)
+ vtc_fatal(s->vl, "Could not unlink %s before bind: %s",
+ s->listen, strerror(errno));
+ /*
+ * Temporarily set the umask to 0 to avoid issues with
+ * permissions.
+ */
+ m = umask(0);
+ s->sock = VUS_resolver(s->listen, uds_listen, &h, errp);
+ umask(m);
+ if (*errp != NULL)
+ return;
+ assert(s->sock > 0);
+ macro_def(s->vl, s->name, "addr", "0.0.0.0");
+ macro_def(s->vl, s->name, "port", "0");
+ macro_def(s->vl, s->name, "sock", "%s", s->listen);
+}
+
+static void
+server_listen_tcp(struct server *s, const char **errp)
+{
+ s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
+ if (*errp != NULL)
+ return;
+ assert(s->sock > 0);
+ VTCP_myname(s->sock, s->aaddr, sizeof s->aaddr,
+ s->aport, sizeof s->aport);
+ macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
+ macro_def(s->vl, s->name, "port", "%s", s->aport);
+ macro_def(s->vl, s->name, "sock", "%s %s", s->aaddr, s->aport);
+ /* Record the actual port, and reuse it on subsequent starts */
+ bprintf(s->listen, "%s %s", s->aaddr, s->aport);
+}
+
static void
server_listen(struct server *s)
{
@@ -123,19 +202,14 @@ server_listen(struct server *s)
if (s->sock >= 0)
VTCP_close(&s->sock);
- s->sock = VTCP_listen_on(s->listen, "0", s->depth, &err);
+ if (*s->listen != '/')
+ server_listen_tcp(s, &err);
+ else
+ server_listen_uds(s, &err);
if (err != NULL)
vtc_fatal(s->vl,
"Server listen address (%s) cannot be resolved: %s",
s->listen, err);
- assert(s->sock > 0);
- VTCP_myname(s->sock, s->aaddr, sizeof s->aaddr,
- s->aport, sizeof s->aport);
- macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
- macro_def(s->vl, s->name, "port", "%s", s->aport);
- macro_def(s->vl, s->name, "sock", "%s %s", s->aaddr, s->aport);
- /* Record the actual port, and reuse it on subsequent starts */
- bprintf(s->listen, "%s %s", s->aaddr, s->aport);
}
/**********************************************************************
@@ -170,7 +244,7 @@ server_thread(void *priv)
vtc_fatal(vl, "Accept failed: %s", strerror(errno));
VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf);
vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf);
- fd = http_process(vl, s->spec, fd, &s->sock);
+ fd = http_process(vl, s->spec, fd, &s->sock, s->listen);
vtc_log(vl, 3, "shutting fd %d", fd);
j = shutdown(fd, SHUT_WR);
if (!VTCP_Check(j))
@@ -215,7 +289,7 @@ server_dispatch_wrk(void *priv)
fd = s->fd;
vtc_log(vl, 3, "start with fd %d", fd);
- fd = http_process(vl, s->spec, fd, &s->sock);
+ fd = http_process(vl, s->spec, fd, &s->sock, s->listen);
vtc_log(vl, 3, "shutting fd %d", fd);
j = shutdown(fd, SHUT_WR);
if (!VTCP_Check(j))
diff --git a/include/Makefile.am b/include/Makefile.am
index b98f8d0..afa8864 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -96,7 +96,8 @@ nobase_noinst_HEADERS = \
vsub.h \
vss.h \
vtcp.h \
- vtree.h
+ vtree.h \
+ vus.h
## keep in sync with lib/libvcc/Makefile.am
vmod_abi.h: \
diff --git a/include/vus.h b/include/vus.h
new file mode 100644
index 0000000..3747d92
--- /dev/null
+++ b/include/vus.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2018 UPLEX - Nils Goroll Systemoptimierung
+ * All rights reserved.
+ *
+ * Author: Geoffrey Simmons <geoffrey.simmons at uplex.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct sockaddr_un;
+
+typedef int vus_resolved_f(void *priv, const struct sockaddr_un *);
+int VUS_resolver(const char *path, vus_resolved_f *func, void *priv,
+ const char **err);
+int VUS_bind(const struct sockaddr_un *uds, const char **errp);
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index 1616f0e..231827f 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -37,7 +37,8 @@ libvarnish_a_SOURCES = \
vss.c \
vsub.c \
vtcp.c \
- vtim.c
+ vtim.c \
+ vus.c
TESTS = vnum_c_test binheap
diff --git a/lib/libvarnish/vus.c b/lib/libvarnish/vus.c
new file mode 100644
index 0000000..ce0f0fd
--- /dev/null
+++ b/lib/libvarnish/vus.c
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2018 UPLEX - Nils Goroll Systemoptimierung
+ * All rights reserved.
+ *
+ * Author: Geoffrey Simmons <geoffrey.simmons at uplex.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "vdef.h"
+#include "vas.h"
+#include "vus.h"
+
+int
+VUS_resolver(const char *path, vus_resolved_f *func, void *priv,
+ const char **err)
+{
+ struct sockaddr_un uds;
+ int ret = 0;
+
+ AN(path);
+ assert(*path == '/');
+
+ AN(err);
+ *err = NULL;
+ if (strlen(path) + 1 > sizeof(uds.sun_path)) {
+ *err = "Path too long for a Unix domain socket";
+ return(-1);
+ }
+ strcpy(uds.sun_path, path);
+ uds.sun_family = PF_UNIX;
+ if (func != NULL)
+ ret = func(priv, &uds);
+ return(ret);
+}
+
+int
+VUS_bind(const struct sockaddr_un *uds, const char **errp)
+{
+ int sd, e;
+ socklen_t sl = sizeof(*uds);
+
+ if (errp != NULL)
+ *errp = NULL;
+
+ sd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (sd < 0) {
+ if (errp != NULL)
+ *errp = "socket(2)";
+ return (-1);
+ }
+
+ if (unlink(uds->sun_path) != 0 && errno != ENOENT) {
+ if (errp != NULL)
+ *errp = "unlink(2)";
+ e = errno;
+ closefd(&sd);
+ errno = e;
+ return (-1);
+ }
+
+ if (bind(sd, (const struct sockaddr *)uds, sl) != 0) {
+ if (errp != NULL)
+ *errp = "bind(2)";
+ e = errno;
+ closefd(&sd);
+ errno = e;
+ return (-1);
+ }
+ return (sd);
+}
More information about the varnish-commit
mailing list