my_fopen.c 4.69 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8
/* 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,
unknown's avatar
unknown committed
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
unknown's avatar
unknown committed
10 11 12 13 14 15
   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 */
unknown's avatar
unknown committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

#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 */

FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
					/* Path-name of file */
					/* Read | write .. */
					/* Special flags */
{
  FILE *fd;
  char type[5];
  DBUG_ENTER("my_fopen");
  DBUG_PRINT("my",("Name: '%s'  Flags: %d  MyFlags: %d",
		   FileName, Flags, MyFlags));

  make_ftype(type,Flags);
  if ((fd = fopen(FileName, type)) != 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.
    */
45
    if ((uint) fileno(fd) >= my_file_limit)
46 47
    {
      thread_safe_increment(my_stream_opened,&THR_LOCK_open);
unknown's avatar
unknown committed
48
      DBUG_RETURN(fd);				/* safeguard */
49
    }
unknown's avatar
unknown committed
50 51 52 53 54 55 56
    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);
57
      DBUG_PRINT("exit",("stream: 0x%lx",fd));
unknown's avatar
unknown committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
      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");
81
  DBUG_PRINT("my",("stream: 0x%lx  MyFlags: %d",fd, MyFlags));
unknown's avatar
unknown committed
82 83 84 85 86 87 88 89 90 91

  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);
  }
92 93
  else
    my_stream_opened--;
94
  if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
unknown's avatar
unknown committed
95 96
  {
    my_file_info[file].type = UNOPEN;
97
    my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
unknown's avatar
unknown committed
98 99 100 101 102 103 104
  }
  pthread_mutex_unlock(&THR_LOCK_open);
  DBUG_RETURN(err);
} /* my_fclose */


	/* Make a stream out of a file handle */
105
	/* Name may be 0 */
unknown's avatar
unknown committed
106

107
FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
unknown's avatar
unknown committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
{
  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);
125
    my_stream_opened++;
126
    if ((uint) Filedes < (uint) my_file_limit)
unknown's avatar
unknown committed
127
    {
128 129
      if (my_file_info[Filedes].type != UNOPEN)
      {
130
        my_file_opened--;		/* File is opened with my_open ! */
131 132 133 134 135
      }
      else
      {
        my_file_info[Filedes].name=  my_strdup(name,MyFlags);
      }
unknown's avatar
unknown committed
136 137 138 139 140
      my_file_info[Filedes].type = STREAM_BY_FDOPEN;
    }
    pthread_mutex_unlock(&THR_LOCK_open);
  }

141
  DBUG_PRINT("exit",("stream: 0x%lx",fd));
unknown's avatar
unknown committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  DBUG_RETURN(fd);
} /* my_fdopen */


	/* Make a filehandler-open-typestring from ordinary inputflags */

static void make_ftype(register my_string to, register int flag)
{
#if FILE_BINARY					/* If we have binary-files */
  reg3 int org_flag=flag;
#endif
  flag&= ~FILE_BINARY;				/* remove binary bit */
  if (flag == O_RDONLY)
    *to++= 'r';
  else if (flag == O_WRONLY)
    *to++= 'w';
  else
  {						/* Add '+' after theese */
    if (flag == O_RDWR)
      *to++= 'r';
    else if (flag & O_APPEND)
      *to++= 'a';
    else
      *to++= 'w';				/* Create file */
    *to++= '+';
  }
#if FILE_BINARY					/* If we have binary-files */
  if (org_flag & FILE_BINARY)
    *to++='b';
#endif
  *to='\0';
} /* make_ftype */