~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to mysys/mf_tempfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
#include "mysys_priv.h"
 
17
#include <m_string.h>
 
18
#include "my_static.h"
 
19
#include "mysys_err.h"
 
20
#include <errno.h>
 
21
#ifdef HAVE_PATHS_H
 
22
#include <paths.h>
 
23
#endif
 
24
 
 
25
 
 
26
 
 
27
/*
 
28
  @brief
 
29
  Create a temporary file with unique name in a given directory
 
30
 
 
31
  @details
 
32
  create_temp_file
 
33
    to             pointer to buffer where temporary filename will be stored
 
34
    dir            directory where to create the file
 
35
    prefix         prefix the filename with this
 
36
    mode           Flags to use for my_create/my_open
 
37
    MyFlags        Magic flags
 
38
 
 
39
  @return
 
40
    File descriptor of opened file if success
 
41
    -1 and sets errno if fails.
 
42
 
 
43
  @note
 
44
    The behaviour of this function differs a lot between
 
45
    implementation, it's main use is to generate a file with
 
46
    a name that does not already exist.
 
47
 
 
48
    When passing O_TEMPORARY flag in "mode" the file should
 
49
    be automatically deleted
 
50
 
 
51
    The implementation using mkstemp should be considered the
 
52
    reference implementation when adding a new or modifying an
 
53
    existing one
 
54
 
 
55
*/
 
56
 
 
57
File create_temp_file(char *to, const char *dir, const char *prefix,
 
58
                      int mode __attribute__((unused)),
 
59
                      myf MyFlags __attribute__((unused)))
 
60
{
 
61
  File file= -1;
 
62
#ifdef __WIN__
 
63
  TCHAR path_buf[MAX_PATH-14];
 
64
#endif
 
65
 
 
66
  DBUG_ENTER("create_temp_file");
 
67
  DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix));
 
68
#if defined (__WIN__)
 
69
 
 
70
   /*
 
71
     Use GetTempPath to determine path for temporary files.
 
72
     This is because the documentation for GetTempFileName 
 
73
     has the following to say about this parameter:
 
74
     "If this parameter is NULL, the function fails."
 
75
   */
 
76
   if (!dir)
 
77
   {
 
78
     if(GetTempPath(sizeof(path_buf), path_buf) > 0) 
 
79
       dir = path_buf;
 
80
   }
 
81
   /*
 
82
     Use GetTempFileName to generate a unique filename, create
 
83
     the file and release it's handle
 
84
      - uses up to the first three letters from prefix
 
85
   */
 
86
  if (GetTempFileName(dir, prefix, 0, to) == 0)
 
87
    DBUG_RETURN(-1);
 
88
 
 
89
  DBUG_PRINT("info", ("name: %s", to));
 
90
 
 
91
  /*
 
92
    Open the file without the "open only if file doesn't already exist"
 
93
    since the file has already been created by GetTempFileName
 
94
  */
 
95
  if ((file= my_open(to,  (mode & ~O_EXCL), MyFlags)) < 0)
 
96
  {
 
97
    /* Open failed, remove the file created by GetTempFileName */
 
98
    int tmp= my_errno;
 
99
    (void) my_delete(to, MYF(0));
 
100
    my_errno= tmp;
 
101
  }
 
102
 
 
103
#elif defined(_ZTC__)
 
104
  if (!dir)
 
105
    dir=getenv("TMPDIR");
 
106
  if ((res=tempnam((char*) dir,(char *) prefix)))
 
107
  {
 
108
    strmake(to,res,FN_REFLEN-1);
 
109
    (*free)(res);
 
110
    file=my_create(to, 0, mode | O_EXCL | O_NOFOLLOW, MyFlags);
 
111
  }
 
112
#elif defined(HAVE_MKSTEMP) && !defined(__NETWARE__)
 
113
  {
 
114
    char prefix_buff[30];
 
115
    uint pfx_len;
 
116
    File org_file;
 
117
 
 
118
    pfx_len= (uint) (strmov(strnmov(prefix_buff,
 
119
                                    prefix ? prefix : "tmp.",
 
120
                                    sizeof(prefix_buff)-7),"XXXXXX") -
 
121
                     prefix_buff);
 
122
    if (!dir && ! (dir =getenv("TMPDIR")))
 
123
      dir=P_tmpdir;
 
124
    if (strlen(dir)+ pfx_len > FN_REFLEN-2)
 
125
    {
 
126
      errno=my_errno= ENAMETOOLONG;
 
127
      DBUG_RETURN(file);
 
128
    }
 
129
    strmov(convert_dirname(to,dir,NullS),prefix_buff);
 
130
    org_file=mkstemp(to);
 
131
    if (mode & O_TEMPORARY)
 
132
      (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
 
133
    file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
 
134
                              EE_CANTCREATEFILE, MyFlags);
 
135
    /* If we didn't manage to register the name, remove the temp file */
 
136
    if (org_file >= 0 && file < 0)
 
137
    {
 
138
      int tmp=my_errno;
 
139
      close(org_file);
 
140
      (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
 
141
      my_errno=tmp;
 
142
    }
 
143
  }
 
144
#elif defined(HAVE_TEMPNAM)
 
145
  {
 
146
#if !defined(__NETWARE__)
 
147
    extern char **environ;
 
148
#endif
 
149
 
 
150
    char *res,**old_env,*temp_env[1];
 
151
    if (dir && !dir[0])
 
152
    {                           /* Change empty string to current dir */
 
153
      to[0]= FN_CURLIB;
 
154
      to[1]= 0;
 
155
      dir=to;
 
156
    }
 
157
#if !defined(__NETWARE__)
 
158
    old_env= (char**) environ;
 
159
    if (dir)
 
160
    {                           /* Don't use TMPDIR if dir is given */
 
161
      environ=(const char**) temp_env;
 
162
      temp_env[0]=0;
 
163
    }
 
164
#endif
 
165
    if ((res=tempnam((char*) dir, (char*) prefix)))
 
166
    {
 
167
      strmake(to,res,FN_REFLEN-1);
 
168
      (*free)(res);
 
169
      file=my_create(to,0,
 
170
                     (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW |
 
171
                            O_TEMPORARY | O_SHORT_LIVED),
 
172
                     MYF(MY_WME));
 
173
 
 
174
    }
 
175
    else
 
176
    {
 
177
      DBUG_PRINT("error",("Got error: %d from tempnam",errno));
 
178
    }
 
179
#if !defined(__NETWARE__)
 
180
    environ=(const char**) old_env;
 
181
#endif
 
182
  }
 
183
#else
 
184
#error No implementation found for create_temp_file
 
185
#endif
 
186
  if (file >= 0)
 
187
    thread_safe_increment(my_tmp_file_created,&THR_LOCK_open);
 
188
  DBUG_RETURN(file);
 
189
}