From 4fa2904290e2c345eae76ad66fc284b76eccd5f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 04:45:52 +0000 Subject: r2613: use a talloc destructor to ensure that file descriptors are not leaked on abnormal termination of a connection. As long as the top level connection structure is freed then that should cascade down to the file structure, and call this destructor which will close the open file descriptor. In general I'd like to use this technique in any place in Samba4 where we hold operating system resources that we need to make sure are released on abnormal termination. (This used to be commit ed87b7fcbd9fedc155528ce6dd8ab5d5fce637b2) --- source4/ntvfs/posix/pvfs_open.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs/posix') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1c6ecc1eb2..a1c6dcdcfe 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -38,6 +38,21 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum) return NULL; } +/* + by using a destructor we make sure that abnormal cleanup will not + leak file descriptors (assuming at least the top level pointer is freed, which + will cascade down to here) +*/ +static int pvfs_fd_destructor(void *p) +{ + struct pvfs_file *f = p; + if (f->fd != -1) { + close(f->fd); + f->fd = -1; + } + return 0; +} + /* open a file TODO: this is a temporary implementation derived from the simple backend @@ -132,6 +147,10 @@ do_open: f->fd = fd; f->name = talloc_steal(f, name); + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_fd_destructor); + DLIST_ADD(pvfs->open_files, f); ZERO_STRUCT(io->generic.out); @@ -157,6 +176,7 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) { NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_file *f; + NTSTATUS status; if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ @@ -169,12 +189,16 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) } if (close(f->fd) != 0) { - return pvfs_map_errno(pvfs, errno); + status = pvfs_map_errno(pvfs, errno); + } else { + status = NT_STATUS_OK; } + talloc_set_destructor(f, NULL); + DLIST_REMOVE(pvfs->open_files, f); talloc_free(f); - return NT_STATUS_OK; + return status; } -- cgit