mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
- ftruncate() ended up changing the current file position, contrary
to what it is supposed to do. Fixed. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14888 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
@ -91,6 +91,9 @@
|
||||
entire library constructor/destructor functionality to use the
|
||||
same approach as libnix.
|
||||
|
||||
- ftruncate() ended up changing the current file position, contrary
|
||||
to what it is supposed to do. Fixed.
|
||||
|
||||
|
||||
c.lib 1.189 (5.3.2005)
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_fdhookentry.c,v 1.21 2005-03-12 09:49:47 obarthel Exp $
|
||||
* $Id: stdio_fdhookentry.c,v 1.22 2005-03-14 10:03:06 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -151,17 +151,28 @@ __fd_hook_entry(
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_APPEND))
|
||||
{
|
||||
LONG position;
|
||||
|
||||
SHOWMSG("appending data");
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
if(Seek(file,0,OFFSET_END) >= 0)
|
||||
position = Seek(file,0,OFFSET_END);
|
||||
if(position >= 0)
|
||||
{
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
|
||||
fd->fd_Position = Seek(file,0,OFFSET_CURRENT);
|
||||
}
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
if(position < 0)
|
||||
{
|
||||
D(("seek to end of file failed; ioerr=%ld",IoErr()));
|
||||
|
||||
fam->fam_Error = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
D(("write %ld bytes to position %ld from 0x%08lx",fam->fam_Size,Seek(file,0,OFFSET_CURRENT),fam->fam_Data));
|
||||
@ -349,6 +360,8 @@ __fd_hook_entry(
|
||||
|
||||
old_dir = CurrentDir(parent_dir);
|
||||
|
||||
/* ZZZ we probably ought to observe the current umask settings. */
|
||||
|
||||
flags = fib->fib_Protection ^ (FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE);
|
||||
|
||||
CLEAR_FLAG(flags,FIBF_EXECUTE);
|
||||
@ -454,18 +467,14 @@ __fd_hook_entry(
|
||||
|
||||
#if defined(UNIX_PATH_SEMANTICS)
|
||||
{
|
||||
if(NOT fib_is_valid && CANNOT __safe_examine_file_handle(file,fib))
|
||||
{
|
||||
fam->fam_Error = __translate_io_error_to_errno(IoErr());
|
||||
/* Check if this operation failed because the file is shorter than
|
||||
the new file position. First, we need to find out if the file
|
||||
is really shorter than required. If not, then it must have
|
||||
been a different error. */
|
||||
if((NOT fib_is_valid && CANNOT __safe_examine_file_handle(file,fib)) || (new_position <= fib->fib_Size))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(new_position <= fib->fib_Size)
|
||||
{
|
||||
fam->fam_Error = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now try to make that file larger. */
|
||||
if(__grow_file_size(fd,new_position - fib->fib_Size) < 0)
|
||||
{
|
||||
fam->fam_Error = __translate_io_error_to_errno(IoErr());
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_grow_file.c,v 1.1 2005-02-18 18:53:16 obarthel Exp $
|
||||
* $Id: stdio_grow_file.c,v 1.2 2005-03-14 10:03:06 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -41,7 +41,8 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Seek to the end of a file, then add a certain number of 0 bytes. */
|
||||
/* Seek to the end of a file, then add a certain number of 0 bytes. Note that
|
||||
this function will change the current file position! */
|
||||
int
|
||||
__grow_file_size(struct fd * fd,int num_bytes)
|
||||
{
|
||||
@ -104,7 +105,7 @@ __grow_file_size(struct fd * fd,int num_bytes)
|
||||
position = Seek(fd->fd_DefaultFile,0,OFFSET_END);
|
||||
PROFILE_ON();
|
||||
|
||||
if(position == -1)
|
||||
if(position < 0)
|
||||
{
|
||||
SHOWMSG("could not move to the end of the file");
|
||||
goto out;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_ftruncate.c,v 1.7 2005-03-07 11:16:43 obarthel Exp $
|
||||
* $Id: unistd_ftruncate.c,v 1.8 2005-03-14 10:03:06 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -47,7 +47,9 @@ ftruncate(int file_descriptor, off_t length)
|
||||
D_S(struct FileInfoBlock,fib);
|
||||
int result = -1;
|
||||
struct fd * fd = NULL;
|
||||
long int position;
|
||||
BOOL restore_initial_position = FALSE;
|
||||
off_t current_file_size;
|
||||
off_t initial_position = -1;
|
||||
BOOL success;
|
||||
|
||||
ENTER();
|
||||
@ -62,6 +64,8 @@ ftruncate(int file_descriptor, off_t length)
|
||||
if(__check_abort_enabled)
|
||||
__check_abort();
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
fd = __get_file_descriptor(file_descriptor);
|
||||
if(fd == NULL)
|
||||
{
|
||||
@ -101,11 +105,7 @@ ftruncate(int file_descriptor, off_t length)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Remember where we started. */
|
||||
position = lseek(file_descriptor,0,SEEK_CUR);
|
||||
if(position < 0)
|
||||
goto out;
|
||||
|
||||
/* Figure out how large the file is right now. */
|
||||
if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib))
|
||||
{
|
||||
SHOWMSG("couldn't examine file");
|
||||
@ -114,47 +114,93 @@ ftruncate(int file_descriptor, off_t length)
|
||||
goto out;
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
current_file_size = fib->fib_Size;
|
||||
|
||||
if(length < fib->fib_Size)
|
||||
/* Is the file to be made shorter than it is right now? */
|
||||
if(length < current_file_size)
|
||||
{
|
||||
/* Remember where we started. */
|
||||
if(initial_position < 0)
|
||||
{
|
||||
initial_position = Seek(fd->fd_DefaultFile,0,OFFSET_CURRENT);
|
||||
if(initial_position < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Careful: seek to a position where the file can be safely truncated. */
|
||||
success = (Seek(fd->fd_DefaultFile,length,OFFSET_BEGINNING) != -1 && SetFileSize(fd->fd_DefaultFile,length,OFFSET_BEGINNING) != -1);
|
||||
if(Seek(fd->fd_DefaultFile,length,OFFSET_BEGINNING) < 0)
|
||||
{
|
||||
D(("could not move to file offset %ld",length));
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(SetFileSize(fd->fd_DefaultFile,length,OFFSET_BEGINNING) < 0)
|
||||
{
|
||||
D(("could not reduce file to size %ld",length));
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If the file is now shorter than the file position, which must
|
||||
not be changed by a call to ftruncate(), extend the file again,
|
||||
filling the extension with 0 bytes. */
|
||||
if(initial_position > length)
|
||||
{
|
||||
current_file_size = length;
|
||||
|
||||
length = initial_position;
|
||||
}
|
||||
|
||||
restore_initial_position = TRUE;
|
||||
}
|
||||
else if (length > fib->fib_Size)
|
||||
|
||||
/* Is the size of the file to grow? */
|
||||
if(length > current_file_size)
|
||||
{
|
||||
success = (Seek(fd->fd_DefaultFile,fib->fib_Size,OFFSET_BEGINNING) != -1 && __grow_file_size(fd,length - fib->fib_Size) == OK);
|
||||
/* Remember where we started. */
|
||||
if(initial_position < 0)
|
||||
{
|
||||
initial_position = Seek(fd->fd_DefaultFile,0,OFFSET_CURRENT);
|
||||
if(initial_position < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Move to what should be the end of the file. */
|
||||
if(Seek(fd->fd_DefaultFile,current_file_size,OFFSET_BEGINNING) < 0)
|
||||
{
|
||||
D(("could not move to file offset %ld",current_file_size));
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Add as many bytes to the end of the file as are required
|
||||
to make it as large as requested. */
|
||||
if(__grow_file_size(fd,length - current_file_size) != OK)
|
||||
{
|
||||
D(("could not extend file to size %ld",length));
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
restore_initial_position = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
if(NO success)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = __translate_io_error_to_errno(IoErr());
|
||||
|
||||
/* Return to the original file position. */
|
||||
lseek(file_descriptor,position,SEEK_SET);
|
||||
|
||||
__set_errno(error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Return to the original file position. */
|
||||
if(lseek(file_descriptor,position,SEEK_SET) < 0)
|
||||
goto out;
|
||||
|
||||
result = 0;
|
||||
|
||||
out:
|
||||
|
||||
if(restore_initial_position)
|
||||
Seek(fd->fd_DefaultFile,initial_position,OFFSET_CURRENT);
|
||||
|
||||
__fd_unlock(fd);
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user