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-1301 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*/
41int 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
96err:
97 DBUG_PRINT("error", ("errno: %d", errno));
98 if (MyFlags & MY_WME)
99 my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
100 DBUG_RETURN(1);
101} /* my_chsize */
102