add WITH_SENDFILE profiling data (from Pierre Belanger)
[Samba.git] / source / smbd / close.c
blob38270fbfe31b0ec0100632690b5cbacce0f694a8
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 file closing
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /****************************************************************************
25 run a file if it is a magic script
26 ****************************************************************************/
27 static void check_magic(files_struct *fsp,connection_struct *conn)
29 if (!*lp_magicscript(SNUM(conn)))
30 return;
32 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
35 char *p;
36 if (!(p = strrchr(fsp->fsp_name,'/')))
37 p = fsp->fsp_name;
38 else
39 p++;
41 if (!strequal(lp_magicscript(SNUM(conn)),p))
42 return;
46 int ret;
47 pstring magic_output;
48 pstring fname;
49 SMB_STRUCT_STAT st;
50 int tmp_fd, outfd;
52 pstrcpy(fname,fsp->fsp_name);
53 if (*lp_magicoutput(SNUM(conn)))
54 pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
55 else
56 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
58 chmod(fname,0755);
59 ret = smbrun(fname,&tmp_fd);
60 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
61 unlink(fname);
62 if (ret != 0 || tmp_fd == -1) {
63 if (tmp_fd != -1)
64 close(tmp_fd);
65 return;
67 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
68 if (outfd == -1) {
69 close(tmp_fd);
70 return;
73 if (sys_fstat(tmp_fd,&st) == -1) {
74 close(tmp_fd);
75 close(outfd);
76 return;
79 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
80 close(tmp_fd);
81 close(outfd);
85 /****************************************************************************
86 Common code to close a file or a directory.
87 ****************************************************************************/
89 static int close_filestruct(files_struct *fsp)
91 connection_struct *conn = fsp->conn;
92 int ret = 0;
94 if (fsp->fd != -1) {
95 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
96 ret = -1;
98 delete_write_cache(fsp);
101 fsp->is_directory = False;
103 conn->num_files_open--;
104 SAFE_FREE(fsp->wbmpx_ptr);
106 return ret;
109 /****************************************************************************
110 Close a file.
112 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
113 operation otherwise it came as the result of some other operation such as
114 the closing of the connection. In the latter case printing and
115 magic scripts are not run.
116 ****************************************************************************/
118 static int close_normal_file(files_struct *fsp, BOOL normal_close)
120 share_mode_entry *share_entry = NULL;
121 size_t share_entry_count = 0;
122 BOOL delete_on_close = False;
123 connection_struct *conn = fsp->conn;
124 int err = 0;
125 int err1 = 0;
127 remove_pending_lock_requests_by_fid(fsp);
130 * If we're flushing on a close we can get a write
131 * error here, we must remember this.
134 if (close_filestruct(fsp) == -1)
135 err1 = -1;
137 if (fsp->print_file) {
138 print_fsp_end(fsp, normal_close);
139 file_free(fsp);
140 return 0;
144 * Lock the share entries, and determine if we should delete
145 * on close. If so delete whilst the lock is still in effect.
146 * This prevents race conditions with the file being created. JRA.
149 lock_share_entry_fsp(fsp);
150 share_entry_count = del_share_mode(fsp, &share_entry);
152 DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
153 share_entry_count, fsp->fsp_name ));
156 * We delete on close if it's the last open, and the
157 * delete on close flag was set in the entry we just deleted.
160 if ((share_entry_count == 0) && share_entry &&
161 GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
162 delete_on_close = True;
164 SAFE_FREE(share_entry);
167 * NT can set delete_on_close of the last open
168 * reference to a file.
171 if (normal_close && delete_on_close) {
172 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
173 fsp->fsp_name));
174 if(fsp->conn->vfs_ops.unlink(conn,dos_to_unix_static(fsp->fsp_name)) != 0) {
176 * This call can potentially fail as another smbd may have
177 * had the file open with delete on close set and deleted
178 * it when its last reference to this file went away. Hence
179 * we log this but not at debug level zero.
182 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
183 with error %s\n", fsp->fsp_name, strerror(errno) ));
187 unlock_share_entry_fsp(fsp);
189 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
190 release_file_oplock(fsp);
192 locking_close_file(fsp);
194 err = fd_close(conn, fsp);
196 /* check for magic scripts */
197 if (normal_close) {
198 check_magic(fsp,conn);
202 * Ensure pending modtime is set after close.
205 if(fsp->pending_modtime) {
206 int saved_errno = errno;
207 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
208 errno = saved_errno;
211 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
212 conn->user,fsp->fsp_name,
213 conn->num_files_open, err ? strerror(err) : ""));
215 if (fsp->fsp_name)
216 string_free(&fsp->fsp_name);
218 file_free(fsp);
220 if (err == -1 || err1 == -1)
221 return -1;
222 else
223 return 0;
226 /****************************************************************************
227 Close a directory opened by an NT SMB call.
228 ****************************************************************************/
230 static int close_directory(files_struct *fsp, BOOL normal_close)
232 remove_pending_change_notify_requests_by_fid(fsp);
235 * NT can set delete_on_close of the last open
236 * reference to a directory also.
239 if (normal_close && fsp->directory_delete_on_close) {
240 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
241 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
242 fsp->fsp_name, ok ? "succeeded" : "failed" ));
245 * Ensure we remove any change notify requests that would
246 * now fail as the directory has been deleted.
249 if(ok)
250 remove_pending_change_notify_requests_by_filename(fsp);
254 * Do the code common to files and directories.
256 close_filestruct(fsp);
258 if (fsp->fsp_name)
259 string_free(&fsp->fsp_name);
261 file_free(fsp);
263 return 0;
266 /****************************************************************************
267 Close a directory opened by an NT SMB call.
268 ****************************************************************************/
270 int close_file(files_struct *fsp, BOOL normal_close)
272 if(fsp->is_directory)
273 return close_directory(fsp, normal_close);
274 return close_normal_file(fsp, normal_close);