summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-01-18 16:47:55 -0800
committerKeith Packard <keithp@keithp.com>2013-01-18 20:54:24 -0800
commite6672f23f2776522330970857d6cb45ff148690b (patch)
treef5aa971e785ff752eb929a16e4df24f7fc69ab91
parent3fbbff5d0285858d78828a2d578a2d32c79cdd3b (diff)
Automatically clean up passed file descriptorsfd-passing
Close unreported received file descriptors at socket close time. Allow applications to request that sent descriptors be closed after being passed. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--Xtrans.c4
-rw-r--r--Xtrans.h2
-rw-r--r--Xtransint.h4
-rw-r--r--Xtranssock.c32
4 files changed, 31 insertions, 11 deletions
diff --git a/Xtrans.c b/Xtrans.c
index 1d52435..8a398f2 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -887,9 +887,9 @@ TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
}
int
-TRANS(SendFd) (XtransConnInfo ciptr, int fd)
+TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close)
{
- return ciptr->transptr->SendFd(ciptr, fd);
+ return ciptr->transptr->SendFd(ciptr, fd, do_close);
}
int
diff --git a/Xtrans.h b/Xtrans.h
index ccc9c4d..36cfc1d 100644
--- a/Xtrans.h
+++ b/Xtrans.h
@@ -358,7 +358,7 @@ int TRANS(Writev)(
int /* size */
);
-int TRANS(SendFd) (XtransConnInfo ciptr, int fd);
+int TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close);
int TRANS(RecvFd) (XtransConnInfo ciptr);
diff --git a/Xtransint.h b/Xtransint.h
index ae1f1e0..dd886db 100644
--- a/Xtransint.h
+++ b/Xtransint.h
@@ -130,6 +130,7 @@ from The Open Group.
struct _XtransConnFd {
struct _XtransConnFd *next;
int fd;
+ int do_close;
};
#endif
@@ -290,7 +291,8 @@ typedef struct _Xtransport {
int (*SendFd)(
XtransConnInfo, /* connection */
- int /* fd */
+ int, /* fd */
+ int /* do_close */
);
int (*RecvFd)(
diff --git a/Xtranssock.c b/Xtranssock.c
index b8563bd..23150b2 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -2100,7 +2100,7 @@ TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
#if XTRANS_SEND_FDS
static void
-appendFd(struct _XtransConnFd **prev, int fd)
+appendFd(struct _XtransConnFd **prev, int fd, int do_close)
{
struct _XtransConnFd *cf, *new;
@@ -2112,6 +2112,7 @@ appendFd(struct _XtransConnFd **prev, int fd)
}
new->next = 0;
new->fd = fd;
+ new->do_close = do_close;
/* search to end of list */
for (; (cf = *prev); prev = &(cf->next));
*prev = new;
@@ -2133,17 +2134,28 @@ removeFd(struct _XtransConnFd **prev)
}
static void
-discardFd(struct _XtransConnFd **prev, struct _XtransConnFd *upto)
+discardFd(struct _XtransConnFd **prev, struct _XtransConnFd *upto, int do_close)
{
struct _XtransConnFd *cf, *next;
for (cf = *prev; cf != upto; cf = next) {
next = cf->next;
+ if (do_close || cf->do_close)
+ close(cf->fd);
free(cf);
}
*prev = upto;
}
+static void
+cleanupFds(XtransConnInfo ciptr)
+{
+ /* Clean up the send list but don't close the fds */
+ discardFd(&ciptr->send_fds, NULL, 0);
+ /* Clean up the recv list and *do* close the fds */
+ discardFd(&ciptr->recv_fds, NULL, 1);
+}
+
static int
nFd(struct _XtransConnFd **prev)
{
@@ -2163,9 +2175,9 @@ TRANS(SocketRecvFd) (XtransConnInfo ciptr)
}
static int
-TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd)
+TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd, int do_close)
{
- appendFd(&ciptr->send_fds, fd);
+ appendFd(&ciptr->send_fds, fd, do_close);
return 0;
}
@@ -2177,7 +2189,7 @@ TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr)
}
static int
-TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd)
+TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
{
errno = EINVAL;
return -1;
@@ -2244,7 +2256,7 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
int *fd = (int *) CMSG_DATA(&pass.cmsghdr);
int i;
for (i = 0; i < nfd; i++)
- appendFd(&ciptr->recv_fds, fd[i]);
+ appendFd(&ciptr->recv_fds, fd[i], 0);
}
}
return size;
@@ -2292,7 +2304,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
init_msg_send(&msg, buf, size, &pass, nfd);
i = sendmsg(ciptr->fd, &msg, 0);
if (i > 0)
- discardFd(&ciptr->send_fds, cf);
+ discardFd(&ciptr->send_fds, cf, 0);
return i;
}
#endif
@@ -2382,6 +2394,9 @@ TRANS(SocketUNIXClose) (XtransConnInfo ciptr)
prmsg (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd);
+#if XTRANS_SEND_FDS
+ cleanupFds(ciptr);
+#endif
ret = close(ciptr->fd);
if (ciptr->flags
@@ -2410,6 +2425,9 @@ TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr)
prmsg (2,"SocketUNIXCloseForCloning(%p,%d)\n",
ciptr, ciptr->fd);
+#if XTRANS_SEND_FDS
+ cleanupFds(ciptr);
+#endif
ret = close(ciptr->fd);
return ret;