1 /* Copyright (C) 2000 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16 #include "mysys_priv.h"
17 #include "mysys_err.h"
29 FileName Fully qualified file name
37 File
my_open(const char *FileName
, int Flags
, myf MyFlags
)
38 /* Path-name of file */
43 DBUG_ENTER("my_open");
44 DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
45 FileName
, Flags
, MyFlags
));
48 Check that we don't try to open or create a file name that may
49 cause problems for us in the future (like PRN)
51 if (check_if_legal_filename(FileName
))
54 DBUG_RETURN(my_register_filename(-1, FileName
, FILE_BY_OPEN
,
55 EE_FILENOTFOUND
, MyFlags
));
59 fd
= sopen((char *) FileName
, (Flags
& ~O_SHARE
) | O_BINARY
, SH_DENYNO
,
60 MY_S_IREAD
| MY_S_IWRITE
);
62 fd
= open((char *) FileName
, Flags
| O_BINARY
,
63 MY_S_IREAD
| MY_S_IWRITE
);
65 fd
= my_sopen((char *) FileName
, (Flags
& ~O_SHARE
) | O_BINARY
, SH_DENYNO
,
66 MY_S_IREAD
| MY_S_IWRITE
);
69 #elif !defined(NO_OPEN_3)
70 fd
= open(FileName
, Flags
, my_umask
); /* Normal unix */
72 fd
= open((char *) FileName
, Flags
);
75 DBUG_RETURN(my_register_filename(fd
, FileName
, FILE_BY_OPEN
,
76 EE_FILENOTFOUND
, MyFlags
));
90 int my_close(File fd
, myf MyFlags
)
93 DBUG_ENTER("my_close");
94 DBUG_PRINT("my",("fd: %d MyFlags: %d",fd
, MyFlags
));
96 pthread_mutex_lock(&THR_LOCK_open
);
100 } while (err
== -1 && errno
== EINTR
);
104 DBUG_PRINT("error",("Got error %d on close",err
));
106 if (MyFlags
& (MY_FAE
| MY_WME
))
107 my_error(EE_BADCLOSE
, MYF(ME_BELL
+ME_WAITTANG
),my_filename(fd
),errno
);
109 if ((uint
) fd
< my_file_limit
&& my_file_info
[fd
].type
!= UNOPEN
)
111 my_free(my_file_info
[fd
].name
, MYF(0));
112 #if defined(THREAD) && !defined(HAVE_PREAD)
113 pthread_mutex_destroy(&my_file_info
[fd
].mutex
);
115 my_file_info
[fd
].type
= UNOPEN
;
118 pthread_mutex_unlock(&THR_LOCK_open
);
124 Register file in my_file_info[]
127 my_register_filename()
128 fd File number opened, -1 if error on open
130 type_file_type How file was created
131 error_message_number Error message number if caller got error (fd == -1)
132 MyFlags Flags for my_close()
140 File
my_register_filename(File fd
, const char *FileName
, enum file_type
141 type_of_file
, uint error_message_number
, myf MyFlags
)
143 DBUG_ENTER("my_register_filename");
146 if ((uint
) fd
>= my_file_limit
)
148 #if defined(THREAD) && !defined(HAVE_PREAD)
151 thread_safe_increment(my_file_opened
,&THR_LOCK_open
);
152 DBUG_RETURN(fd
); /* safeguard */
157 pthread_mutex_lock(&THR_LOCK_open
);
158 if ((my_file_info
[fd
].name
= (char*) my_strdup(FileName
,MyFlags
)))
161 my_file_total_opened
++;
162 my_file_info
[fd
].type
= type_of_file
;
163 #if defined(THREAD) && !defined(HAVE_PREAD)
164 pthread_mutex_init(&my_file_info
[fd
].mutex
,MY_MUTEX_INIT_FAST
);
166 pthread_mutex_unlock(&THR_LOCK_open
);
167 DBUG_PRINT("exit",("fd: %d",fd
));
170 pthread_mutex_unlock(&THR_LOCK_open
);
173 (void) my_close(fd
, MyFlags
);
178 DBUG_PRINT("error",("Got error %d on open", my_errno
));
179 if (MyFlags
& (MY_FFNF
| MY_FAE
| MY_WME
))
181 if (my_errno
== EMFILE
)
182 error_message_number
= EE_OUT_OF_FILERESOURCES
;
183 DBUG_PRINT("error",("print err: %d",error_message_number
));
184 my_error(error_message_number
, MYF(ME_BELL
+ME_WAITTANG
),
192 extern void __cdecl
_dosmaperr(unsigned long);
195 Open a file with sharing. Similar to _sopen() from libc, but allows managing
196 share delete on win32
200 path fully qualified file name
201 oflag operation flags
203 pmode permission flags
206 File descriptor of opened file if success
207 -1 and sets errno if fails.
210 File
my_sopen(const char *path
, int oflag
, int shflag
, int pmode
)
212 int fh
; /* handle of opened file */
214 HANDLE osfh
; /* OS handle of opened file */
215 DWORD fileaccess
; /* OS file access (requested) */
216 DWORD fileshare
; /* OS file sharing mode */
217 DWORD filecreate
; /* OS method of opening/creating */
218 DWORD fileattrib
; /* OS file attribute flags */
219 SECURITY_ATTRIBUTES SecurityAttributes
;
221 SecurityAttributes
.nLength
= sizeof(SecurityAttributes
);
222 SecurityAttributes
.lpSecurityDescriptor
= NULL
;
223 SecurityAttributes
.bInheritHandle
= !(oflag
& _O_NOINHERIT
);
226 * decode the access flags
228 switch (oflag
& (_O_RDONLY
| _O_WRONLY
| _O_RDWR
)) {
229 case _O_RDONLY
: /* read access */
230 fileaccess
= GENERIC_READ
;
232 case _O_WRONLY
: /* write access */
233 fileaccess
= GENERIC_WRITE
;
235 case _O_RDWR
: /* read and write access */
236 fileaccess
= GENERIC_READ
| GENERIC_WRITE
;
238 default: /* error, bad oflag */
240 _doserrno
= 0L; /* not an OS error */
245 * decode sharing flags
248 case _SH_DENYRW
: /* exclusive access except delete */
249 fileshare
= FILE_SHARE_DELETE
;
251 case _SH_DENYWR
: /* share read and delete access */
252 fileshare
= FILE_SHARE_READ
| FILE_SHARE_DELETE
;
254 case _SH_DENYRD
: /* share write and delete access */
255 fileshare
= FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
257 case _SH_DENYNO
: /* share read, write and delete access */
258 fileshare
= FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
260 case _SH_DENYRWD
: /* exclusive access */
263 case _SH_DENYWRD
: /* share read access */
264 fileshare
= FILE_SHARE_READ
;
266 case _SH_DENYRDD
: /* share write access */
267 fileshare
= FILE_SHARE_WRITE
;
269 case _SH_DENYDEL
: /* share read and write access */
270 fileshare
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
272 default: /* error, bad shflag */
274 _doserrno
= 0L; /* not an OS error */
279 * decode open/create method flags
281 switch (oflag
& (_O_CREAT
| _O_EXCL
| _O_TRUNC
)) {
283 case _O_EXCL
: /* ignore EXCL w/o CREAT */
284 filecreate
= OPEN_EXISTING
;
288 filecreate
= OPEN_ALWAYS
;
291 case _O_CREAT
| _O_EXCL
:
292 case _O_CREAT
| _O_TRUNC
| _O_EXCL
:
293 filecreate
= CREATE_NEW
;
297 case _O_TRUNC
| _O_EXCL
: /* ignore EXCL w/o CREAT */
298 filecreate
= TRUNCATE_EXISTING
;
301 case _O_CREAT
| _O_TRUNC
:
302 filecreate
= CREATE_ALWAYS
;
306 /* this can't happen ... all cases are covered */
313 * decode file attribute flags if _O_CREAT was specified
315 fileattrib
= FILE_ATTRIBUTE_NORMAL
; /* default */
316 if (oflag
& _O_CREAT
)
318 _umask((mask
= _umask(0)));
320 if (!((pmode
& ~mask
) & _S_IWRITE
))
321 fileattrib
= FILE_ATTRIBUTE_READONLY
;
325 * Set temporary file (delete-on-close) attribute if requested.
327 if (oflag
& _O_TEMPORARY
)
329 fileattrib
|= FILE_FLAG_DELETE_ON_CLOSE
;
334 * Set temporary file (delay-flush-to-disk) attribute if requested.
336 if (oflag
& _O_SHORT_LIVED
)
337 fileattrib
|= FILE_ATTRIBUTE_TEMPORARY
;
340 * Set sequential or random access attribute if requested.
342 if (oflag
& _O_SEQUENTIAL
)
343 fileattrib
|= FILE_FLAG_SEQUENTIAL_SCAN
;
344 else if (oflag
& _O_RANDOM
)
345 fileattrib
|= FILE_FLAG_RANDOM_ACCESS
;
348 * try to open/create the file
350 if ((osfh
= CreateFile(path
, fileaccess
, fileshare
, &SecurityAttributes
,
351 filecreate
, fileattrib
, NULL
)) == INVALID_HANDLE_VALUE
)
354 * OS call to open/create file failed! map the error, release
355 * the lock, and return -1. note that it's not necessary to
356 * call _free_osfhnd (it hasn't been used yet).
358 _dosmaperr(GetLastError()); /* map error */
359 return -1; /* return error to caller */
362 if ((fh
= _open_osfhandle((intptr_t)osfh
,
363 oflag
& (_O_APPEND
| _O_RDONLY
| _O_TEXT
))) == -1)
365 _dosmaperr(GetLastError()); /* map error */
369 return fh
; /* return handle */
376 void my_print_open_files(void)
378 if (my_file_opened
| my_stream_opened
)
381 for (i
= 0 ; i
< my_file_limit
; i
++)
383 if (my_file_info
[i
].type
!= UNOPEN
)
385 fprintf(stderr
, EE(EE_FILE_NOT_CLOSED
), my_file_info
[i
].name
, i
);