starfix: HoR fix!!! wave+team check fix+2 bos jalan...kurang LK nya + PR:lootannya...
[st4rcore.git] / dep / mysqllite / mysys / my_open.c
blobfe7f65c450b07825457f172664d047e26aa3859e
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"
18 #include <my_dir.h>
19 #include <errno.h>
20 #if defined(__WIN__)
21 #include <share.h>
22 #endif
25 Open a file
27 SYNOPSIS
28 my_open()
29 FileName Fully qualified file name
30 Flags Read | write
31 MyFlags Special flags
33 RETURN VALUE
34 File descriptor
37 File my_open(const char *FileName, int Flags, myf MyFlags)
38 /* Path-name of file */
39 /* Read | write .. */
40 /* Special flags */
42 File fd;
43 DBUG_ENTER("my_open");
44 DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
45 FileName, Flags, MyFlags));
46 #if defined(__WIN__)
47 /*
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)
50 */
51 if (check_if_legal_filename(FileName))
53 errno= EACCES;
54 DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN,
55 EE_FILENOTFOUND, MyFlags));
57 #ifndef __WIN__
58 if (Flags & O_SHARE)
59 fd = sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
60 MY_S_IREAD | MY_S_IWRITE);
61 else
62 fd = open((char *) FileName, Flags | O_BINARY,
63 MY_S_IREAD | MY_S_IWRITE);
64 #else
65 fd= my_sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
66 MY_S_IREAD | MY_S_IWRITE);
67 #endif
69 #elif !defined(NO_OPEN_3)
70 fd = open(FileName, Flags, my_umask); /* Normal unix */
71 #else
72 fd = open((char *) FileName, Flags);
73 #endif
75 DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
76 EE_FILENOTFOUND, MyFlags));
77 } /* my_open */
81 Close a file
83 SYNOPSIS
84 my_close()
85 fd File sescriptor
86 myf Special Flags
90 int my_close(File fd, myf MyFlags)
92 int err;
93 DBUG_ENTER("my_close");
94 DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
96 pthread_mutex_lock(&THR_LOCK_open);
99 err= close(fd);
100 } while (err == -1 && errno == EINTR);
102 if (err)
104 DBUG_PRINT("error",("Got error %d on close",err));
105 my_errno=errno;
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);
114 #endif
115 my_file_info[fd].type = UNOPEN;
117 my_file_opened--;
118 pthread_mutex_unlock(&THR_LOCK_open);
119 DBUG_RETURN(err);
120 } /* my_close */
124 Register file in my_file_info[]
126 SYNOPSIS
127 my_register_filename()
128 fd File number opened, -1 if error on open
129 FileName File name
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()
134 RETURN
135 -1 error
136 # Filenumber
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");
144 if ((int) fd >= 0)
146 if ((uint) fd >= my_file_limit)
148 #if defined(THREAD) && !defined(HAVE_PREAD)
149 my_errno= EMFILE;
150 #else
151 thread_safe_increment(my_file_opened,&THR_LOCK_open);
152 DBUG_RETURN(fd); /* safeguard */
153 #endif
155 else
157 pthread_mutex_lock(&THR_LOCK_open);
158 if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
160 my_file_opened++;
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);
165 #endif
166 pthread_mutex_unlock(&THR_LOCK_open);
167 DBUG_PRINT("exit",("fd: %d",fd));
168 DBUG_RETURN(fd);
170 pthread_mutex_unlock(&THR_LOCK_open);
171 my_errno= ENOMEM;
173 (void) my_close(fd, MyFlags);
175 else
176 my_errno= errno;
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),
185 FileName, my_errno);
187 DBUG_RETURN(-1);
190 #ifdef __WIN__
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
198 SYNOPSIS
199 my_sopen()
200 path fully qualified file name
201 oflag operation flags
202 shflag share flag
203 pmode permission flags
205 RETURN VALUE
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 */
213 int mask;
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;
231 break;
232 case _O_WRONLY: /* write access */
233 fileaccess= GENERIC_WRITE;
234 break;
235 case _O_RDWR: /* read and write access */
236 fileaccess= GENERIC_READ | GENERIC_WRITE;
237 break;
238 default: /* error, bad oflag */
239 errno= EINVAL;
240 _doserrno= 0L; /* not an OS error */
241 return -1;
245 * decode sharing flags
247 switch (shflag) {
248 case _SH_DENYRW: /* exclusive access except delete */
249 fileshare= FILE_SHARE_DELETE;
250 break;
251 case _SH_DENYWR: /* share read and delete access */
252 fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
253 break;
254 case _SH_DENYRD: /* share write and delete access */
255 fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
256 break;
257 case _SH_DENYNO: /* share read, write and delete access */
258 fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
259 break;
260 case _SH_DENYRWD: /* exclusive access */
261 fileshare= 0L;
262 break;
263 case _SH_DENYWRD: /* share read access */
264 fileshare= FILE_SHARE_READ;
265 break;
266 case _SH_DENYRDD: /* share write access */
267 fileshare= FILE_SHARE_WRITE;
268 break;
269 case _SH_DENYDEL: /* share read and write access */
270 fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
271 break;
272 default: /* error, bad shflag */
273 errno= EINVAL;
274 _doserrno= 0L; /* not an OS error */
275 return -1;
279 * decode open/create method flags
281 switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
282 case 0:
283 case _O_EXCL: /* ignore EXCL w/o CREAT */
284 filecreate= OPEN_EXISTING;
285 break;
287 case _O_CREAT:
288 filecreate= OPEN_ALWAYS;
289 break;
291 case _O_CREAT | _O_EXCL:
292 case _O_CREAT | _O_TRUNC | _O_EXCL:
293 filecreate= CREATE_NEW;
294 break;
296 case _O_TRUNC:
297 case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
298 filecreate= TRUNCATE_EXISTING;
299 break;
301 case _O_CREAT | _O_TRUNC:
302 filecreate= CREATE_ALWAYS;
303 break;
305 default:
306 /* this can't happen ... all cases are covered */
307 errno= EINVAL;
308 _doserrno= 0L;
309 return -1;
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;
330 fileaccess|= DELETE;
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 */
366 CloseHandle(osfh);
369 return fh; /* return handle */
371 #endif /* __WIN__ */
374 #ifdef EXTRA_DEBUG
376 void my_print_open_files(void)
378 if (my_file_opened | my_stream_opened)
380 uint i;
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);
386 fputc('\n', stderr);
392 #endif