~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_chsize.c

  • Committer: Brian Aker
  • Date: 2008-07-01 08:15:04 UTC
  • Revision ID: brian@tangent.org-20080701081504-qn3jzgsbb2twnchs
Large file and ftruncate() support

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
 
#if defined(HAVE_SETFILEPOINTER)
56
 
  /* This is for the moment only true on windows */
57
 
    long is_success;
58
 
    HANDLE win_file= (HANDLE) _get_osfhandle(fd);
59
 
    long length_low, length_high;
60
 
    length_low= (long) (ulong) newlength;
61
 
    length_high= (long) ((ulonglong) newlength >> 32);
62
 
    is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
63
 
    if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
64
 
      goto err;
65
 
    if (SetEndOfFile(win_file))
66
 
      DBUG_RETURN(0);
67
 
    my_errno= GetLastError();
68
 
    goto err;
69
 
#elif defined(HAVE_FTRUNCATE)
70
 
    if (ftruncate(fd, (off_t) newlength))
71
 
    {
72
 
      my_errno= errno;
73
 
      goto err;
74
 
    }
75
 
    DBUG_RETURN(0);
76
 
#elif defined(HAVE_CHSIZE)
77
 
    if (chsize(fd, (off_t) newlength))
78
 
    {
79
 
      my_errno=errno;
80
 
      goto err;
81
 
    }
82
 
    DBUG_RETURN(0);
83
 
#else
84
 
    /*
85
 
      Fill space between requested length and true length with 'filler'
86
 
      We should never come here on any modern machine
87
 
    */
88
 
    if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
89
 
        == MY_FILEPOS_ERROR)
90
 
    {
91
 
      goto err;
92
 
    }
93
 
    swap_variables(my_off_t, newlength, oldsize);
94
 
#endif
95
 
  }
96
 
 
97
 
  /* Full file with 'filler' until it's as big as requested */
98
 
  bfill(buff, IO_SIZE, filler);
99
 
  while (newlength-oldsize > IO_SIZE)
100
 
  {
101
 
    if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP)))
102
 
      goto err;
103
 
    oldsize+= IO_SIZE;
104
 
  }
105
 
  if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP)))
106
 
    goto err;
107
 
  DBUG_RETURN(0);
108
 
 
109
 
err:
110
 
  DBUG_PRINT("error", ("errno: %d", errno));
111
 
  if (MyFlags & MY_WME)
112
 
    my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
113
 
  DBUG_RETURN(1);
114
 
} /* my_chsize */