~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_chsize.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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 */