Drizzled Public API Documentation

my_copy.cc

00001 /* Copyright (C) 2000 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include <config.h>
00017 
00018 #include <drizzled/internal/my_sys.h>
00019 
00020 #include <fcntl.h>
00021 
00022 #include <drizzled/internal/m_string.h>
00023 #if defined(HAVE_UTIME_H)
00024 #include <utime.h>
00025 #elif defined(HAVE_SYS_UTIME_H)
00026 #include <sys/utime.h>
00027 #elif !defined(HPUX10)
00028 #include <time.h>
00029 struct utimbuf {
00030   time_t actime;
00031   time_t modtime;
00032 };
00033 #endif
00034 
00035 #ifdef HAVE_SYS_STAT_H
00036 # include <sys/stat.h>
00037 #endif
00038 
00039 #include <drizzled/util/test.h>
00040 
00041 namespace drizzled
00042 {
00043 namespace internal
00044 {
00045 
00046 /*
00047   int my_copy(const char *from, const char *to, myf MyFlags)
00048 
00049   NOTES
00050     Ordinary ownership and accesstimes are copied from 'from-file'
00051     If MyFlags & MY_HOLD_ORIGINAL_MODES is set and to-file exists then
00052     the modes of to-file isn't changed
00053     If MyFlags & MY_DONT_OVERWRITE_FILE is set, we will give an error
00054     if the file existed.
00055 
00056   WARNING
00057     Don't set MY_FNABP or MY_NABP bits on when calling this function !
00058 
00059   RETURN
00060     0 ok
00061     # Error
00062 
00063 */
00064 
00065 int my_copy(const char *from, const char *to, myf MyFlags)
00066 {
00067   uint32_t Count;
00068   bool new_file_stat= 0; /* 1 if we could stat "to" */
00069   int create_flag;
00070   int from_file,to_file;
00071   unsigned char buff[IO_SIZE];
00072   struct stat stat_buff,new_stat_buff;
00073 
00074   from_file=to_file= -1;
00075   assert(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
00076   if (MyFlags & MY_HOLD_ORIGINAL_MODES)   /* Copy stat if possible */
00077     new_file_stat= test(!stat((char*) to, &new_stat_buff));
00078 
00079   if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0)
00080   {
00081     if (stat(from, &stat_buff))
00082     {
00083       errno=errno;
00084       goto err;
00085     }
00086     if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
00087       stat_buff=new_stat_buff;
00088     create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;
00089 
00090     if ((to_file=  my_create(to,(int) stat_buff.st_mode,
00091            O_WRONLY | create_flag,
00092            MyFlags)) < 0)
00093       goto err;
00094 
00095     while ((Count= static_cast<uint32_t>(my_read(from_file, buff,
00096             sizeof(buff), MyFlags))) != 0)
00097     {
00098   if (Count == (uint32_t) -1 ||
00099       my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
00100   goto err;
00101     }
00102 
00103     if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
00104       return(-1);       /* Error on close */
00105 
00106     /* Copy modes if possible */
00107 
00108     if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
00109   return(0);      /* File copyed but not stat */
00110     chmod(to, stat_buff.st_mode & 07777); /* Copy modes */
00111     if(chown(to, stat_buff.st_uid,stat_buff.st_gid)!=0)
00112         return 0;
00113     if (MyFlags & MY_COPYTIME)
00114     {
00115       struct utimbuf timep;
00116       timep.actime  = stat_buff.st_atime;
00117       timep.modtime = stat_buff.st_mtime;
00118       utime((char*) to, &timep); /* last accessed and modified times */
00119     }
00120     return(0);
00121   }
00122 
00123 err:
00124   if (from_file >= 0) my_close(from_file,MyFlags);
00125   if (to_file >= 0)
00126   {
00127     my_close(to_file, MyFlags);
00128     /* attempt to delete the to-file we've partially written */
00129     my_delete(to, MyFlags);
00130   }
00131   return(-1);
00132 } /* my_copy */
00133 
00134 } /* namespace internal */
00135 } /* namespace drizzled */