MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
my_copy.c
1 /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "mysys_priv.h"
17 #include <my_dir.h> /* for stat */
18 #include <m_string.h>
19 #include "mysys_err.h"
20 #if defined(HAVE_UTIME_H)
21 #include <utime.h>
22 #elif defined(HAVE_SYS_UTIME_H)
23 #include <sys/utime.h>
24 #elif !defined(HPUX10)
25 #include <time.h>
26 struct utimbuf {
27  time_t actime;
28  time_t modtime;
29 };
30 #endif
31 
32 
33 /*
34  int my_copy(const char *from, const char *to, myf MyFlags)
35 
36  NOTES
37  Ordinary ownership and accesstimes are copied from 'from-file'
38  If MyFlags & MY_HOLD_ORIGINAL_MODES is set and to-file exists then
39  the modes of to-file isn't changed
40  If MyFlags & MY_DONT_OVERWRITE_FILE is set, we will give an error
41  if the file existed.
42 
43  WARNING
44  Don't set MY_FNABP or MY_NABP bits on when calling this function !
45 
46  RETURN
47  0 ok
48  # Error
49 
50 */
51 
52 int my_copy(const char *from, const char *to, myf MyFlags)
53 {
54  size_t Count;
55  my_bool new_file_stat= 0; /* 1 if we could stat "to" */
56  int create_flag;
57  File from_file,to_file;
58  uchar buff[IO_SIZE];
59  MY_STAT stat_buff,new_stat_buff;
60  DBUG_ENTER("my_copy");
61  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
62 
63  from_file=to_file= -1;
64  DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
65  if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */
66  new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0)));
67 
68  if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
69  {
70  if (!my_stat(from, &stat_buff, MyFlags))
71  {
72  my_errno=errno;
73  goto err;
74  }
75  if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
76  stat_buff=new_stat_buff;
77  create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;
78 
79  if ((to_file= my_create(to,(int) stat_buff.st_mode,
80  O_WRONLY | create_flag | O_BINARY | O_SHARE,
81  MyFlags)) < 0)
82  goto err;
83 
84  while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
85  {
86  if (Count == (uint) -1 ||
87  my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
88  goto err;
89  }
90 
91  /* sync the destination file */
92  if (MyFlags & MY_SYNC)
93  {
94  if (my_sync(to_file, MyFlags))
95  goto err;
96  }
97 
98  if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
99  DBUG_RETURN(-1); /* Error on close */
100 
101  /* Copy modes if possible */
102 
103  if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
104  DBUG_RETURN(0); /* File copyed but not stat */
105  /* Copy modes */
106  if (chmod(to, stat_buff.st_mode & 07777))
107  {
108  my_errno= errno;
109  if (MyFlags & (MY_FAE+MY_WME))
110  {
111  char errbuf[MYSYS_STRERROR_SIZE];
112  my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from,
113  errno, my_strerror(errbuf, sizeof(errbuf), errno));
114  }
115  goto err;
116  }
117 #if !defined(__WIN__)
118  /* Copy ownership */
119  if (chown(to, stat_buff.st_uid, stat_buff.st_gid))
120  {
121  my_errno= errno;
122  if (MyFlags & (MY_FAE+MY_WME))
123  {
124  char errbuf[MYSYS_STRERROR_SIZE];
125  my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from,
126  errno, my_strerror(errbuf, sizeof(errbuf), errno));
127  }
128  goto err;
129  }
130 #endif
131 
132  if (MyFlags & MY_COPYTIME)
133  {
134  struct utimbuf timep;
135  timep.actime = stat_buff.st_atime;
136  timep.modtime = stat_buff.st_mtime;
137  (void) utime((char*) to, &timep); /* last accessed and modified times */
138  }
139 
140  DBUG_RETURN(0);
141  }
142 
143 err:
144  if (from_file >= 0) (void) my_close(from_file,MyFlags);
145  if (to_file >= 0)
146  {
147  (void) my_close(to_file, MyFlags);
148  /* attempt to delete the to-file we've partially written */
149  (void) my_delete(to, MyFlags);
150  }
151  DBUG_RETURN(-1);
152 } /* my_copy */