summaryrefslogtreecommitdiff
path: root/mysys/mf_cache.c
blob: 9017bf4f18c84e8a34b08f3044c21c1a06b4cf4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA */

/* Open a temporary file and cache it with io_cache. Delete it on close */

#include "mysys_priv.h"
#include <m_string.h>
#include "my_static.h"
#include "mysys_err.h"
#include <paths.h>

#define TMP_EXT ".tmp"				/* Extension of tempfile  */
#if ! defined(P_tmpdir)
#define P_tmpdir ""
#endif

#ifdef HAVE_TEMPNAM
#ifndef MSDOS
extern char **environ;
#endif
#endif

	/*
	  Remove an open tempfile so that it doesn't survive
	  if we crash;	If the operating system doesn't support
	  this, just remember the file name for later removal
	*/

static my_bool cache_remove_open_tmp(IO_CACHE *cache, const char *name)
{
#if O_TEMPORARY == 0
#if !defined(CANT_DELETE_OPEN_FILES)
  /* The following should always succeed */
  (void) my_delete(name,MYF(MY_WME | ME_NOINPUT));
#else
  int length;
  if (!(cache->file_name=
	(char*) my_malloc((length=strlen(name)+1),MYF(MY_WME)))
  {
    my_close(cache->file,MYF(0));
    cache->file = -1;
    errno=my_error=ENOMEM;
    return 1;
  }
  memcpy(cache->file_name,name,length);
#endif
#endif /* O_TEMPORARY == 0 */
  return 0;
}

	/*
	** Open tempfile cached by IO_CACHE
	** Should be used when no seeks are done (only reinit_io_buff)
	** Return 0 if cache is inited ok
	** The actual file is created when the IO_CACHE buffer gets filled
	** If dir is not given, use TMPDIR.
	*/

my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
			  uint cache_size, myf cache_myflags)
{
  DBUG_ENTER("open_cached_file");
  cache->dir=	 dir ? my_strdup(dir,MYF(cache_myflags & MY_WME)) : (char*) 0;
  cache->prefix= (prefix ? my_strdup(prefix,MYF(cache_myflags & MY_WME)) :
		 (char*) 0);
  cache->file_name=0;
  cache->buffer=0;				/* Mark that not open */
  if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
		     MYF(cache_myflags | MY_NABP)))
  {
    DBUG_RETURN(0);
  }
  my_free(cache->dir,	MYF(MY_ALLOW_ZERO_PTR));
  my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
  DBUG_RETURN(0);
}

	/* Create the temporary file */

my_bool real_open_cached_file(IO_CACHE *cache)
{
  char name_buff[FN_REFLEN];
  int error=1;
  DBUG_ENTER("real_open_cached_file");
  if ((cache->file=create_temp_file(name_buff, cache->dir, cache->prefix,
				    (O_RDWR | O_BINARY | O_TRUNC |
				     O_TEMPORARY | O_SHORT_LIVED),
				    MYF(MY_WME))) >= 0)
  {
    error=0;
    cache_remove_open_tmp(cache, name_buff);
  }
  DBUG_RETURN(error);
}


void close_cached_file(IO_CACHE *cache)
{
  DBUG_ENTER("close_cached_file");
  if (my_b_inited(cache))
  {
    (void) end_io_cache(cache);
    if (cache->file >= 0)
    {
      (void) my_close(cache->file,MYF(0));
#ifdef CANT_DELETE_OPEN_FILES
      if (cache->file_name)
      {
	(void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
	my_free(cache->file_name,MYF(0));
      }
#endif
    }
    my_free(cache->dir,MYF(MY_ALLOW_ZERO_PTR));
    my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR));
  }
  DBUG_VOID_RETURN;
}