summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-25 04:45:52 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:12 -0500
commit4fa2904290e2c345eae76ad66fc284b76eccd5f8 (patch)
tree315b3102d991a2338fd3b3f20a50d683ba32c45c /source4/ntvfs/posix
parentcf938f14a20f0a5f9db1afbd51f7aa4fb7c26be8 (diff)
downloadsamba-4fa2904290e2c345eae76ad66fc284b76eccd5f8.tar.gz
samba-4fa2904290e2c345eae76ad66fc284b76eccd5f8.tar.bz2
samba-4fa2904290e2c345eae76ad66fc284b76eccd5f8.zip
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)
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r--source4/ntvfs/posix/pvfs_open.c28
1 files changed, 26 insertions, 2 deletions
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
@@ -39,6 +39,21 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum)
}
/*
+ 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
its purpose is to allow other tests to run
@@ -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;
}