MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
my_chsize.c
1 /* Copyright (c) 2000, 2011, 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 "mysys_err.h"
18 #include "m_string.h"
19 
20 /*
21  Change size of file.
22 
23  SYNOPSIS
24  my_chsize()
25  fd File descriptor
26  new_length New file size
27  filler If we don't have truncate, fill up all bytes after
28  new_length with this character
29  MyFlags Flags
30 
31  DESCRIPTION
32  my_chsize() truncates file if shorter else fill with the filler character.
33  The function also changes the file pointer. Usually it points to the end
34  of the file after execution.
35 
36  RETURN VALUE
37  0 Ok
38  1 Error
39 */
40 int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
41 {
42  my_off_t oldsize;
43  uchar buff[IO_SIZE];
44  DBUG_ENTER("my_chsize");
45  DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
46  MyFlags));
47 
48  if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
49  DBUG_RETURN(0);
50 
51  DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
52 
53  if (oldsize > newlength)
54  {
55 #ifdef _WIN32
56  if (my_win_chsize(fd, newlength))
57  {
58  my_errno= errno;
59  goto err;
60  }
61  DBUG_RETURN(0);
62 #elif defined(HAVE_FTRUNCATE)
63  if (ftruncate(fd, (off_t) newlength))
64  {
65  my_errno= errno;
66  goto err;
67  }
68  DBUG_RETURN(0);
69 #elif defined(HAVE_CHSIZE)
70  if (chsize(fd, (off_t) newlength))
71  {
72  my_errno=errno;
73  goto err;
74  }
75  DBUG_RETURN(0);
76 #else
77  /*
78  Fill space between requested length and true length with 'filler'
79  We should never come here on any modern machine
80  */
81  if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
82  == MY_FILEPOS_ERROR)
83  {
84  goto err;
85  }
86  swap_variables(my_off_t, newlength, oldsize);
87 #endif
88  }
89 
90  /* Full file with 'filler' until it's as big as requested */
91  memset(buff, filler, IO_SIZE);
92  while (newlength-oldsize > IO_SIZE)
93  {
94  if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP)))
95  goto err;
96  oldsize+= IO_SIZE;
97  }
98  if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP)))
99  goto err;
100  DBUG_RETURN(0);
101 
102 err:
103  DBUG_PRINT("error", ("errno: %d", errno));
104  if (MyFlags & MY_WME)
105  {
106  char errbuf[MYSYS_STRERROR_SIZE];
107  my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG),
108  my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
109  }
110  DBUG_RETURN(1);
111 } /* my_chsize */