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 | */ |
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+ME_WAITTANG), my_errno); |
100 | DBUG_RETURN(1); |
101 | } /* my_chsize */ |
102 | |