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 entire library constructor/destructor functionality to use the
same approach as libnix. 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) 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 * :ts=4
* *
@@ -151,17 +151,28 @@ __fd_hook_entry(
if(FLAG_IS_SET(fd->fd_Flags,FDF_APPEND)) if(FLAG_IS_SET(fd->fd_Flags,FDF_APPEND))
{ {
LONG position;
SHOWMSG("appending data"); SHOWMSG("appending data");
PROFILE_OFF(); 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)) if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
fd->fd_Position = Seek(file,0,OFFSET_CURRENT); fd->fd_Position = Seek(file,0,OFFSET_CURRENT);
} }
PROFILE_ON(); 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)); 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); 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); flags = fib->fib_Protection ^ (FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE);
CLEAR_FLAG(flags,FIBF_EXECUTE); CLEAR_FLAG(flags,FIBF_EXECUTE);
@@ -454,18 +467,14 @@ __fd_hook_entry(
#if defined(UNIX_PATH_SEMANTICS) #if defined(UNIX_PATH_SEMANTICS)
{ {
if(NOT fib_is_valid && CANNOT __safe_examine_file_handle(file,fib)) /* Check if this operation failed because the file is shorter than
{ the new file position. First, we need to find out if the file
fam->fam_Error = __translate_io_error_to_errno(IoErr()); 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; 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) if(__grow_file_size(fd,new_position - fib->fib_Size) < 0)
{ {
fam->fam_Error = __translate_io_error_to_errno(IoErr()); 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 * :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 int
__grow_file_size(struct fd * fd,int num_bytes) __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); position = Seek(fd->fd_DefaultFile,0,OFFSET_END);
PROFILE_ON(); PROFILE_ON();
if(position == -1) if(position < 0)
{ {
SHOWMSG("could not move to the end of the file"); SHOWMSG("could not move to the end of the file");
goto out; 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 * :ts=4
* *
@@ -47,7 +47,9 @@ ftruncate(int file_descriptor, off_t length)
D_S(struct FileInfoBlock,fib); D_S(struct FileInfoBlock,fib);
int result = -1; int result = -1;
struct fd * fd = NULL; struct fd * fd = NULL;
long int position; BOOL restore_initial_position = FALSE;
off_t current_file_size;
off_t initial_position = -1;
BOOL success; BOOL success;
ENTER(); ENTER();
@@ -62,6 +64,8 @@ ftruncate(int file_descriptor, off_t length)
if(__check_abort_enabled) if(__check_abort_enabled)
__check_abort(); __check_abort();
PROFILE_OFF();
fd = __get_file_descriptor(file_descriptor); fd = __get_file_descriptor(file_descriptor);
if(fd == NULL) if(fd == NULL)
{ {
@@ -101,11 +105,7 @@ ftruncate(int file_descriptor, off_t length)
goto out; goto out;
} }
/* Remember where we started. */ /* Figure out how large the file is right now. */
position = lseek(file_descriptor,0,SEEK_CUR);
if(position < 0)
goto out;
if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib)) if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib))
{ {
SHOWMSG("couldn't examine file"); SHOWMSG("couldn't examine file");
@@ -114,47 +114,93 @@ ftruncate(int file_descriptor, off_t length)
goto out; 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. */ /* 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; result = 0;
out: out:
if(restore_initial_position)
Seek(fd->fd_DefaultFile,initial_position,OFFSET_CURRENT);
__fd_unlock(fd); __fd_unlock(fd);
PROFILE_ON();
RETURN(result); RETURN(result);
return(result); return(result);
} }