my_chsize.c 3.26 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4
/* Copyright (C) 2000 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6 7

   This program is distributed in the hope that it will be useful,
unknown's avatar
unknown committed
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
unknown's avatar
unknown committed
9 10 11 12 13 14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
unknown's avatar
unknown committed
15 16 17 18 19

#include "mysys_priv.h"
#include "mysys_err.h"
#include "m_string.h"

unknown's avatar
unknown committed
20 21 22 23 24 25 26
/*
  Change size of file.

  SYNOPSIS
    my_chsize()
      fd		File descriptor
      new_length	New file size
27 28
      filler		If we don't have truncate, fill up all bytes after
			new_length with this character
unknown's avatar
unknown committed
29 30 31
      MyFlags		Flags

  DESCRIPTION
unknown's avatar
unknown committed
32 33 34
    my_chsize() truncates file if shorter else fill with the filler character.
    The function also changes the file pointer. Usually it points to the end
    of the file after execution.
unknown's avatar
unknown committed
35 36 37 38 39

  RETURN VALUE
    0	Ok
    1	Error 
*/
40
int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
unknown's avatar
unknown committed
41
{
unknown's avatar
unknown committed
42 43
  my_off_t oldsize;
  char buff[IO_SIZE];
unknown's avatar
unknown committed
44 45 46 47
  DBUG_ENTER("my_chsize");
  DBUG_PRINT("my",("fd: %d  length: %lu  MyFlags: %d",fd,(ulong) newlength,
		   MyFlags));

48 49 50
  if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
    DBUG_RETURN(0);

unknown's avatar
unknown committed
51
  DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
unknown's avatar
unknown committed
52

unknown's avatar
unknown committed
53
  if (oldsize > newlength)
54
  {
unknown's avatar
unknown committed
55 56
#if defined(HAVE_SETFILEPOINTER)
  /* This is for the moment only true on windows */
57
    long is_success;
unknown's avatar
unknown committed
58
    HANDLE win_file= (HANDLE) _get_osfhandle(fd);
59 60 61
    long length_low, length_high;
    length_low= (long) (ulong) newlength;
    length_high= (long) ((ulonglong) newlength >> 32);
62 63 64 65 66 67
    is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
    if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
      goto err;
    if (SetEndOfFile(win_file))
      DBUG_RETURN(0);
    my_errno= GetLastError();
unknown's avatar
unknown committed
68
    goto err;
unknown's avatar
BUG  
unknown committed
69
#elif defined(HAVE_FTRUNCATE)
unknown's avatar
unknown committed
70
    if (ftruncate(fd, (off_t) newlength))
unknown's avatar
unknown committed
71
    {
unknown's avatar
unknown committed
72 73
      my_errno= errno;
      goto err;
unknown's avatar
unknown committed
74
    }
unknown's avatar
unknown committed
75 76 77
    DBUG_RETURN(0);
#elif defined(HAVE_CHSIZE)
    if (chsize(fd, (off_t) newlength))
unknown's avatar
unknown committed
78
    {
unknown's avatar
unknown committed
79
      my_errno=errno;
unknown's avatar
unknown committed
80
      goto err;
unknown's avatar
unknown committed
81
    }
unknown's avatar
unknown committed
82
    DBUG_RETURN(0);
unknown's avatar
unknown committed
83 84 85 86 87
#else
    /*
      Fill space between requested length and true length with 'filler'
      We should never come here on any modern machine
    */
88 89 90 91 92
    if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
        == MY_FILEPOS_ERROR)
    {
      goto err;
    }
93
    swap_variables(my_off_t, newlength, oldsize);
unknown's avatar
unknown committed
94
#endif
95
  }
unknown's avatar
BUG  
unknown committed
96

unknown's avatar
unknown committed
97 98 99 100 101 102 103 104 105 106 107
  /* Full file with 'filler' until it's as big as requested */
  bfill(buff, IO_SIZE, filler);
  while (newlength-oldsize > IO_SIZE)
  {
    if (my_write(fd,(byte*) buff,IO_SIZE,MYF(MY_NABP)))
      goto err;
    oldsize+= IO_SIZE;
  }
  if (my_write(fd,(byte*) buff,(uint) (newlength-oldsize),MYF(MY_NABP)))
    goto err;
  DBUG_RETURN(0);
unknown's avatar
BUG  
unknown committed
108

unknown's avatar
unknown committed
109 110 111 112 113 114
err:
  DBUG_PRINT("error", ("errno: %d", errno));
  if (MyFlags & MY_WME)
    my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
  DBUG_RETURN(1);
} /* my_chsize */