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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
Advanced symlink handling.
18
This is used in MyISAM to let users symlinks tables to different disk.
19
The main idea with these functions is to automaticly create, delete and
20
rename files and symlinks like they would be one unit.
23
#include "mysys_priv.h"
24
#include "mysys_err.h"
27
File my_create_with_symlink(const char *linkname, const char *filename,
28
int createflags, int access_flags, myf MyFlags)
32
/* Test if we should create a link */
34
char abs_linkname[FN_REFLEN];
35
DBUG_ENTER("my_create_with_symlink");
36
DBUG_PRINT("enter", ("linkname: %s filename: %s",
37
linkname ? linkname : "(NULL)",
38
filename ? filename : "(NULL)"));
40
if (my_disable_symlinks)
42
DBUG_PRINT("info", ("Symlinks disabled"));
43
/* Create only the file, not the link and file */
51
my_realpath(abs_linkname, linkname, MYF(0));
52
create_link= (linkname && strcmp(abs_linkname,filename));
55
if (!(MyFlags & MY_DELETE_OLD))
57
if (!access(filename,F_OK))
59
my_errno= errno= EEXIST;
60
my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
63
if (create_link && !access(linkname,F_OK))
65
my_errno= errno= EEXIST;
66
my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
71
if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0)
75
/* Delete old link/file */
76
if (MyFlags & MY_DELETE_OLD)
77
my_delete(linkname, MYF(0));
79
if (my_symlink(filename, linkname, MyFlags))
81
/* Fail, remove everything we have done */
83
my_close(file,MYF(0));
84
my_delete(filename, MYF(0));
94
If the file was a symlink, delete both symlink and the file which the
98
int my_delete_with_symlink(const char *name, myf MyFlags)
100
char link_name[FN_REFLEN];
101
int was_symlink= (!my_disable_symlinks &&
102
!my_readlink(link_name, name, MYF(0)));
104
DBUG_ENTER("my_delete_with_symlink");
106
if (!(result=my_delete(name, MyFlags)))
109
result=my_delete(link_name, MyFlags);
115
If the file is a normal file, just rename it.
116
If the file is a symlink:
117
- Create a new file with the name 'to' that points at
118
symlink_dir/basename(to)
119
- Rename the symlinked file to symlink_dir/basename(to)
121
If something goes wrong, restore everything.
124
int my_rename_with_symlink(const char *from, const char *to, myf MyFlags)
126
#ifndef HAVE_READLINK
127
return my_rename(from, to, MyFlags);
129
char link_name[FN_REFLEN], tmp_name[FN_REFLEN];
130
int was_symlink= (!my_disable_symlinks &&
131
!my_readlink(link_name, from, MYF(0)));
133
int name_is_different;
134
DBUG_ENTER("my_rename_with_symlink");
137
DBUG_RETURN(my_rename(from, to, MyFlags));
139
/* Change filename that symlink pointed to */
140
strmov(tmp_name, to);
141
fn_same(tmp_name,link_name,1); /* Copy dir */
142
name_is_different= strcmp(link_name, tmp_name);
143
if (name_is_different && !access(tmp_name, F_OK))
146
if (MyFlags & MY_WME)
147
my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST);
151
/* Create new symlink */
152
if (my_symlink(tmp_name, to, MyFlags))
156
Rename symlinked file if the base name didn't change.
157
This can happen if you use this function where 'from' and 'to' has
158
the same basename and different directories.
161
if (name_is_different && my_rename(link_name, tmp_name, MyFlags))
163
int save_errno=my_errno;
164
my_delete(to, MyFlags); /* Remove created symlink */
169
/* Remove original symlink */
170
if (my_delete(from, MyFlags))
172
int save_errno=my_errno;
173
/* Remove created link */
174
my_delete(to, MyFlags);
175
/* Rename file back */
176
if (strcmp(link_name, tmp_name))
177
(void) my_rename(tmp_name, link_name, MyFlags);
182
#endif /* HAVE_READLINK */