diff options
author | unknown <monty@hundin.mysql.fi> | 2001-06-01 03:53:14 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2001-06-01 03:53:14 +0300 |
commit | b4773dc2fb1ff3bbc88c44cdce5ffdcdf893433d (patch) | |
tree | 18a56f1559667b7d6f2f77918362b9fca42865a5 /mysys | |
parent | 8c8244918fc37bb25656a5f8b451a362e4b16577 (diff) | |
download | mariadb-git-b4773dc2fb1ff3bbc88c44cdce5ffdcdf893433d.tar.gz |
Added symlink support to mysys library.
Docs/manual.texi:
Link info change
include/my_sys.h:
Added functions for symlink support
libmysql/Makefile.shared:
Added mf_symlink.c to library.
mysys/Makefile.am:
Added functions for symlink support
mysys/mf_same.c:
cleanup
mysys/my_symlink.c:
Added functions for symlink support
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/Makefile.am | 2 | ||||
-rw-r--r-- | mysys/mf_same.c | 15 | ||||
-rw-r--r-- | mysys/my_symlink.c | 47 | ||||
-rw-r--r-- | mysys/my_symlink2.c | 131 |
4 files changed, 148 insertions, 47 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 827367ac755..6dd9bb06fe9 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -33,7 +33,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ my_alloc.c safemalloc.c my_fopen.c my_fstream.c \ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ - my_symlink.c \ + my_symlink.c my_symlink2.c \ mf_pack.c mf_pack2.c mf_unixpath.c mf_stripp.c \ mf_casecnv.c mf_soundex.c mf_wcomp.c mf_wfile.c \ mf_qsort.c mf_qsort2.c mf_sort.c \ diff --git a/mysys/mf_same.c b/mysys/mf_same.c index 5b8c5ecf970..c1a5cae11cb 100644 --- a/mysys/mf_same.c +++ b/mysys/mf_same.c @@ -20,19 +20,22 @@ #include "mysys_priv.h" #include <m_string.h> - /* Formaterar ett filnamn i avsende p} ett annat namn */ - /* Klarar {ven to = name */ - /* Denna funktion r|r inte p} utg}ngsnamnet */ + /* + Copy directory and/or extension between filenames. + (For the meaning of 'flag', check mf_format.c) + 'to' may be equal to 'name'. + Returns 'to'. + */ -my_string fn_same(my_string toname, const char *name, int flag) +my_string fn_same(char *to, const char *name, int flag) { char dev[FN_REFLEN]; const char *ext; DBUG_ENTER("fn_same"); - DBUG_PRINT("mfunkt",("to: %s name: %s flag: %d",toname,name,flag)); + DBUG_PRINT("enter",("to: %s name: %s flag: %d",to,name,flag)); if ((ext=strrchr(name+dirname_part(dev,name),FN_EXTCHAR)) == 0) ext=""; - DBUG_RETURN(fn_format(toname,toname,dev,ext,flag)); + DBUG_RETURN(fn_format(to,to,dev,ext,flag)); } /* fn_same */ diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index e195adcd4c5..65d165fc026 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -18,6 +18,7 @@ #include "mysys_priv.h" #include "mysys_err.h" #include <m_string.h> +#include <errno.h> #ifdef HAVE_REALPATH #include <sys/param.h> #include <sys/stat.h> @@ -26,13 +27,16 @@ /* Reads the content of a symbolic link If the file is not a symbolic link, return the original file name in to. + Returns: 0 if table was a symlink, + 1 if table was a normal file + -1 on error. */ int my_readlink(char *to, const char *filename, myf MyFlags) { #ifndef HAVE_READLINK strmov(to,filename); - return 0; + return 1; #else int result=0; int length; @@ -43,6 +47,7 @@ int my_readlink(char *to, const char *filename, myf MyFlags) /* Don't give an error if this wasn't a symlink */ if ((my_errno=errno) == EINVAL) { + result= 1; strmov(to,filename); } else @@ -81,44 +86,6 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) #endif /* HAVE_READLINK */ } - -/* - Create a file and a symbolic link that points to this file - If linkname is a null pointer or equal to filename, we don't - create a link. - */ - - -File my_create_with_symlink(const char *linkname, const char *filename, - int createflags, int access_flags, myf MyFlags) -{ - File file; - int tmp_errno; - DBUG_ENTER("my_create_with_symlink"); - if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0) - { - /* Test if we should create a link */ - if (linkname && strcmp(linkname,filename)) - { - /* Delete old link/file */ - if (MyFlags & MY_DELETE_OLD) - my_delete(linkname, MYF(0)); - /* Create link */ - if (my_symlink(filename, linkname, MyFlags)) - { - /* Fail, remove everything we have done */ - tmp_errno=my_errno; - my_close(file,MYF(0)); - my_delete(filename, MYF(0)); - file= -1; - my_errno=tmp_errno; - } - } - } - DBUG_RETURN(file); -} - - /* Resolve all symbolic links in path 'to' may be equal to 'filename' @@ -162,7 +129,7 @@ int my_realpath(char *to, const char *filename, myf MyFlags) result= -1; } } - return result; + DBUG_RETURN(result); #else if (to != filename) strmov(to,filename); diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c new file mode 100644 index 00000000000..671531393f7 --- /dev/null +++ b/mysys/my_symlink2.c @@ -0,0 +1,131 @@ +/* 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 */ + +/* + Advanced symlink handling. + This is used in MyISAM to let users symlinks tables to different disk. + The main idea with these functions is to automaticly create, delete and + rename files and symlinks like they would be one unit. +*/ + +#include "mysys_priv.h" +#include <m_string.h> + +File my_create_with_symlink(const char *linkname, const char *filename, + int createflags, int access_flags, myf MyFlags) +{ + File file; + int tmp_errno; + DBUG_ENTER("my_create_with_symlink"); + if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0) + { + /* Test if we should create a link */ + if (linkname && strcmp(linkname,filename)) + { + /* Delete old link/file */ + if (MyFlags & MY_DELETE_OLD) + my_delete(linkname, MYF(0)); + /* Create link */ + if (my_symlink(filename, linkname, MyFlags)) + { + /* Fail, remove everything we have done */ + tmp_errno=my_errno; + my_close(file,MYF(0)); + my_delete(filename, MYF(0)); + file= -1; + my_errno=tmp_errno; + } + } + } + DBUG_RETURN(file); +} + +/* + If the file was a symlink, delete both symlink and the file which the + symlink pointed to. +*/ + +int my_delete_with_symlink(const char *name, myf MyFlags) +{ + char link_name[FN_REFLEN]; + int was_symlink= !my_readlink(link_name, name, MYF(0)); + int result; + DBUG_ENTER("my_delete_with_symlink"); + + if (!(result=my_delete(name, MyFlags))) + { + if (was_symlink) + result=my_delete(link_name, MyFlags); + } + DBUG_RETURN(result); +} + +/* + If the file is a normal file, just rename it. + If the file is a symlink: + - Create a new file with the name 'to' that points at + symlink_dir/basename(to) + - Rename the symlinked file to symlink_dir/basename(to) + - Delete 'from' + If something goes wrong, restore everything. +*/ + +int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) +{ +#ifdef HAVE_READLINK + return my_rename(from, to, MyFlags); +#else + char link_name[FN_REFLEN], tmp_name[FN_REFLEN]; + int was_symlink= !my_readlink(link_name, name, MYF(0)); + int result; + DBUG_ENTER("my_rename_with_symlink"); + + if (!was_symlink) + DBUG_RETURN(my_rename(from, to, MyFlags)); + + /* Change filename that symlink pointed to */ + strmov(tmp_name, to); + fn_same(tmp_name,link_name,1); /* Copy dir */ + + /* Create new symlink */ + if (my_symlink(tmp_name, to, MyFlags)) + DBUG_RETURN(-1); + + /* + Rename symlinked file if the base name didn't change. + This can happen if you use this function where 'from' and 'to' has + the same basename and different directories. + */ + + if (strcmp(link_name, tmp_name) && my_rename(link_name, tmp_name, MyFlags)) + { + my_delete(to, MyFlags); /* Remove created symlink */ + DBUG_RETURN(-1); + } + + /* Remove original symlink */ + if (my_delete(from, MyFlags)) + { + /* Remove created link */ + my_delete(to, MyFlags); + /* Rename file back */ + if (strcmp(link_name, tmp_name)) + (void) my_rename(tmp_name, link_name, MyFlags); + } + DBUG_RETURN(result); +#endif /* HAVE_READLINK */ +} |