1 /* Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc.
2    Use is subject to license terms.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
16 
17 #include "mysys_priv.h"
18 #include "mysys_err.h"
19 #include "m_string.h"
20 
21 /*
22   Change size of file.
23 
24   SYNOPSIS
25     my_chsize()
26       fd		File descriptor
27       new_length	New file size
28       filler		If we don't have truncate, fill up all bytes after
29 			new_length with this character
30       MyFlags		Flags
31 
32   DESCRIPTION
33     my_chsize() truncates file if shorter else fill with the filler character.
34     The function also changes the file pointer. Usually it points to the end
35     of the file after execution.
36 
37   RETURN VALUE
38     0	Ok
39     1	Error
40 */
my_chsize(File fd,my_off_t newlength,int filler,myf MyFlags)41 int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
42 {
43   my_off_t oldsize;
44   uchar buff[IO_SIZE];
45   DBUG_ENTER("my_chsize");
46   DBUG_PRINT("my",("fd: %d  length: %lu  MyFlags: %lu",fd,(ulong) newlength,
47 		   MyFlags));
48 
49   if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
50     DBUG_RETURN(0);
51 
52   DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
53 
54   if (oldsize > newlength)
55   {
56 #ifdef _WIN32
57     if (my_win_chsize(fd, newlength))
58     {
59       my_errno= errno;
60       goto err;
61     }
62     DBUG_RETURN(0);
63 #elif defined(HAVE_FTRUNCATE)
64     if (ftruncate(fd, (off_t) newlength))
65     {
66       my_errno= errno;
67       goto err;
68     }
69     DBUG_RETURN(0);
70 #else
71     /*
72       Fill space between requested length and true length with 'filler'
73       We should never come here on any modern machine
74     */
75     if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
76         == MY_FILEPOS_ERROR)
77     {
78       goto err;
79     }
80     swap_variables(my_off_t, newlength, oldsize);
81 #endif
82   }
83 
84   /* Full file with 'filler' until it's as big as requested */
85   bfill(buff, IO_SIZE, filler);
86   while (newlength-oldsize > IO_SIZE)
87   {
88     if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP)))
89       goto err;
90     oldsize+= IO_SIZE;
91   }
92   if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP)))
93     goto err;
94   DBUG_RETURN(0);
95 
96 err:
97   DBUG_PRINT("error", ("errno: %d", errno));
98   if (MyFlags & MY_WME)
99     my_error(EE_CANT_CHSIZE, MYF(ME_BELL), my_errno);
100   DBUG_RETURN(1);
101 } /* my_chsize */
102