1
0
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:
Olaf Barthel
2005-03-14 10:03:06 +00:00
parent a60623bbc6
commit 966851e8bd
4 changed files with 109 additions and 50 deletions

View File

@ -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)

View File

@ -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());

View File

@ -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;

View File

@ -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);
}
else if (length > fib->fib_Size)
if(Seek(fd->fd_DefaultFile,length,OFFSET_BEGINNING) < 0)
{
success = (Seek(fd->fd_DefaultFile,fib->fib_Size,OFFSET_BEGINNING) != -1 && __grow_file_size(fd,length - fib->fib_Size) == OK);
}
else
{
success = TRUE;
}
D(("could not move to file offset %ld",length));
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);
__set_errno(__translate_io_error_to_errno(IoErr()));
goto out;
}
/* Return to the original file position. */
if(lseek(file_descriptor,position,SEEK_SET) < 0)
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;
}
/* Is the size of the file to grow? */
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;
}
/* 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;
}
result = 0;
out:
if(restore_initial_position)
Seek(fd->fd_DefaultFile,initial_position,OFFSET_CURRENT);
__fd_unlock(fd);
PROFILE_ON();
RETURN(result);
return(result);
}