my_fopen.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
- /* Copyright (C) 2000 MySQL AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- #include "mysys_priv.h"
- #include "my_static.h"
- #include <errno.h>
- #include "mysys_err.h"
- static void make_ftype(my_string to,int flag);
- /*
- Open a file as stream
- SYNOPSIS
- my_fopen()
- FileName Path-name of file
- Flags Read | write | append | trunc (like for open())
- MyFlags Flags for handling errors
- RETURN
- 0 Error
- # File handler
- */
- FILE *my_fopen(const char *filename, int flags, myf MyFlags)
- {
- FILE *fd;
- char type[5];
- DBUG_ENTER("my_fopen");
- DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
- filename, flags, MyFlags));
- /*
- if we are not creating, then we need to use my_access to make sure
- the file exists since Windows doesn't handle files like "com1.sym"
- very well
- */
- #ifdef __WIN__
- if (check_if_legal_filename(filename))
- {
- errno= EACCES;
- fd= 0;
- }
- else
- #endif
- {
- make_ftype(type,flags);
- fd = fopen(filename, type);
- }
-
- if (fd != 0)
- {
- /*
- The test works if MY_NFILE < 128. The problem is that fileno() is char
- on some OS (SUNOS). Actually the filename save isn't that important
- so we can ignore if this doesn't work.
- */
- if ((uint) fileno(fd) >= my_file_limit)
- {
- thread_safe_increment(my_stream_opened,&THR_LOCK_open);
- DBUG_RETURN(fd); /* safeguard */
- }
- pthread_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[fileno(fd)].name = (char*)
- my_strdup(filename,MyFlags)))
- {
- my_stream_opened++;
- my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
- pthread_mutex_unlock(&THR_LOCK_open);
- DBUG_PRINT("exit",("stream: 0x%lx",fd));
- DBUG_RETURN(fd);
- }
- pthread_mutex_unlock(&THR_LOCK_open);
- (void) my_fclose(fd,MyFlags);
- my_errno=ENOMEM;
- }
- else
- my_errno=errno;
- DBUG_PRINT("error",("Got error %d on open",my_errno));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error((flags & O_RDONLY) || (flags == O_RDONLY ) ? EE_FILENOTFOUND :
- EE_CANTCREATEFILE,
- MYF(ME_BELL+ME_WAITTANG), filename, my_errno);
- DBUG_RETURN((FILE*) 0);
- } /* my_fopen */
- /* Close a stream */
- int my_fclose(FILE *fd, myf MyFlags)
- {
- int err,file;
- DBUG_ENTER("my_fclose");
- DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d",fd, MyFlags));
- pthread_mutex_lock(&THR_LOCK_open);
- file=fileno(fd);
- if ((err = fclose(fd)) < 0)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(file),errno);
- }
- else
- my_stream_opened--;
- if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
- {
- my_file_info[file].type = UNOPEN;
- my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
- }
- pthread_mutex_unlock(&THR_LOCK_open);
- DBUG_RETURN(err);
- } /* my_fclose */
- /* Make a stream out of a file handle */
- /* Name may be 0 */
- FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
- {
- FILE *fd;
- char type[5];
- DBUG_ENTER("my_fdopen");
- DBUG_PRINT("my",("Fd: %d Flags: %d MyFlags: %d",
- Filedes, Flags, MyFlags));
- make_ftype(type,Flags);
- if ((fd = fdopen(Filedes, type)) == 0)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_CANT_OPEN_STREAM, MYF(ME_BELL+ME_WAITTANG),errno);
- }
- else
- {
- pthread_mutex_lock(&THR_LOCK_open);
- my_stream_opened++;
- if ((uint) Filedes < (uint) my_file_limit)
- {
- if (my_file_info[Filedes].type != UNOPEN)
- {
- my_file_opened--; /* File is opened with my_open ! */
- }
- else
- {
- my_file_info[Filedes].name= my_strdup(name,MyFlags);
- }
- my_file_info[Filedes].type = STREAM_BY_FDOPEN;
- }
- pthread_mutex_unlock(&THR_LOCK_open);
- }
- DBUG_PRINT("exit",("stream: 0x%lx",fd));
- DBUG_RETURN(fd);
- } /* my_fdopen */
- /*
- Make a fopen() typestring from a open() type bitmap
- SYNOPSIS
- make_ftype()
- to String for fopen() is stored here
- flag Flag used by open()
- IMPLEMENTATION
- This routine attempts to find the best possible match
- between a numeric option and a string option that could be
- fed to fopen. There is not a 1 to 1 mapping between the two.
-
- NOTE
- On Unix, O_RDONLY is usually 0
- MAPPING
- r == O_RDONLY
- w == O_WRONLY|O_TRUNC|O_CREAT
- a == O_WRONLY|O_APPEND|O_CREAT
- r+ == O_RDWR
- w+ == O_RDWR|O_TRUNC|O_CREAT
- a+ == O_RDWR|O_APPEND|O_CREAT
- */
- static void make_ftype(register my_string to, register int flag)
- {
- /* check some possible invalid combinations */
- DBUG_ASSERT((flag & (O_TRUNC | O_APPEND)) != (O_TRUNC | O_APPEND));
- DBUG_ASSERT((flag & (O_WRONLY | O_RDWR)) != (O_WRONLY | O_RDWR));
- if ((flag & (O_RDONLY|O_WRONLY)) == O_WRONLY)
- *to++= (flag & O_APPEND) ? 'a' : 'w';
- else if (flag & O_RDWR)
- {
- /* Add '+' after theese */
- if (flag & (O_TRUNC | O_CREAT))
- *to++= 'w';
- else if (flag & O_APPEND)
- *to++= 'a';
- else
- *to++= 'r';
- *to++= '+';
- }
- else
- *to++= 'r';
- #if FILE_BINARY /* If we have binary-files */
- if (flag & FILE_BINARY)
- *to++='b';
- #endif
- *to=' ';
- } /* make_ftype */