diff options
author | Keith Packard <keithp@keithp.com> | 2013-01-18 16:47:55 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-01-18 20:54:24 -0800 |
commit | e6672f23f2776522330970857d6cb45ff148690b (patch) | |
tree | f5aa971e785ff752eb929a16e4df24f7fc69ab91 | |
parent | 3fbbff5d0285858d78828a2d578a2d32c79cdd3b (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.c | 4 | ||||
-rw-r--r-- | Xtrans.h | 2 | ||||
-rw-r--r-- | Xtransint.h | 4 | ||||
-rw-r--r-- | Xtranssock.c | 32 |
4 files changed, 31 insertions, 11 deletions
@@ -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 @@ -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; |