mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
- Major, major changes! Moved most of the monolithic code out of
the file descriptor hook and into the respective functions, such as dup2(), fchmod(), fchown(), fcntl(), fdatasync(), fstatfs(), fsync(), ftruncate() and lseek(). Code which is not strictly required will no longer find its way into your programs if you link with the updated library. NOTE: these changes require that the entire library is rebuilt! git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14833 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: GNUmakefile.68k,v 1.26 2005-02-07 10:52:16 obarthel Exp $
|
||||
# $Id: GNUmakefile.68k,v 1.27 2005-02-18 18:53:16 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@ -181,6 +181,7 @@ C_LIB = \
|
||||
stdio_data.o \
|
||||
stdio_dropiobreadbuffer.o \
|
||||
stdio_duplicate_fd.o \
|
||||
stdio_examine_fh.o \
|
||||
stdio_fclose.o \
|
||||
stdio_fdhookentry.o \
|
||||
stdio_feof.o \
|
||||
@ -211,6 +212,7 @@ C_LIB = \
|
||||
stdio_gets.o \
|
||||
stdio_growfdtable.o \
|
||||
stdio_growiobtable.o \
|
||||
stdio_grow_file.o \
|
||||
stdio_initializefd.o \
|
||||
stdio_initializeiob.o \
|
||||
stdio_init_exit.o \
|
||||
@ -218,6 +220,7 @@ C_LIB = \
|
||||
stdio_locksemaphorename.o \
|
||||
stdio_nostdio.o \
|
||||
stdio_openiob.o \
|
||||
stdio_parent_of_fh.o \
|
||||
stdio_perror.o \
|
||||
stdio_popen.o \
|
||||
stdio_printf.o \
|
||||
@ -405,6 +408,7 @@ C_LIB = \
|
||||
unistd_realpath.o \
|
||||
unistd_sleep.o \
|
||||
unistd_symlink.o \
|
||||
unistd_sync_fd.o \
|
||||
unistd_timer.o \
|
||||
unistd_time_delay.o \
|
||||
unistd_truncate.o \
|
||||
@ -438,6 +442,7 @@ UNIX_LIB = \
|
||||
stdio_locksemaphorename.o \
|
||||
stdio_openiob.o \
|
||||
stdio_popen.o \
|
||||
stdio_record_locking.o \
|
||||
stdio_remove.o \
|
||||
stdio_rename.o \
|
||||
stdlib_mkdtemp.o \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: GNUmakefile.os4,v 1.26 2005-02-07 10:52:16 obarthel Exp $
|
||||
# $Id: GNUmakefile.os4,v 1.27 2005-02-18 18:53:16 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@ -185,6 +185,7 @@ C_LIB = \
|
||||
stdio_data.o \
|
||||
stdio_dropiobreadbuffer.o \
|
||||
stdio_duplicate_fd.o \
|
||||
stdio_examine_fh.o \
|
||||
stdio_fclose.o \
|
||||
stdio_fdhookentry.o \
|
||||
stdio_feof.o \
|
||||
@ -215,6 +216,7 @@ C_LIB = \
|
||||
stdio_gets.o \
|
||||
stdio_growfdtable.o \
|
||||
stdio_growiobtable.o \
|
||||
stdio_grow_file.o \
|
||||
stdio_initializefd.o \
|
||||
stdio_initializeiob.o \
|
||||
stdio_init_exit.o \
|
||||
@ -222,6 +224,7 @@ C_LIB = \
|
||||
stdio_locksemaphorename.o \
|
||||
stdio_nostdio.o \
|
||||
stdio_openiob.o \
|
||||
stdio_parent_of_fh.o \
|
||||
stdio_perror.o \
|
||||
stdio_popen.o \
|
||||
stdio_printf.o \
|
||||
@ -409,6 +412,7 @@ C_LIB = \
|
||||
unistd_realpath.o \
|
||||
unistd_sleep.o \
|
||||
unistd_symlink.o \
|
||||
unistd_sync_fd.o \
|
||||
unistd_timer.o \
|
||||
unistd_time_delay.o \
|
||||
unistd_truncate.o \
|
||||
@ -443,6 +447,7 @@ UNIX_LIB = \
|
||||
stdio_locksemaphorename.o \
|
||||
stdio_openiob.o \
|
||||
stdio_popen.o \
|
||||
stdio_record_locking.o \
|
||||
stdio_remove.o \
|
||||
stdio_rename.o \
|
||||
stdlib_mkdtemp.o \
|
||||
|
||||
@ -2,6 +2,15 @@
|
||||
translate patterns such as "foo/bar/../../baz" properly, and to
|
||||
use strlen() less.
|
||||
|
||||
- Major, major changes! Moved most of the monolithic code out of
|
||||
the file descriptor hook and into the respective functions,
|
||||
such as dup2(), fchmod(), fchown(), fcntl(), fdatasync(), fstatfs(),
|
||||
fsync(), ftruncate() and lseek(). Code which is not strictly
|
||||
required will no longer find its way into your programs if you
|
||||
link with the updated library.
|
||||
|
||||
NOTE: these changes require that the entire library is rebuilt!
|
||||
|
||||
|
||||
c.lib 1.188 (7.2.2005)
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fcntl_fcntl.c,v 1.6 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: fcntl_fcntl.c,v 1.7 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -50,6 +50,7 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
int result = -1;
|
||||
struct fd * fd;
|
||||
va_list arg;
|
||||
int error;
|
||||
int flags;
|
||||
int fdbase;
|
||||
int i;
|
||||
@ -83,6 +84,12 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
|
||||
SHOWMSG("cmd=F_GETLK/F_SETLK/F_SETLKW");
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
va_start(arg,cmd);
|
||||
|
||||
l = va_arg(arg,struct flock *);
|
||||
@ -107,16 +114,9 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
break;
|
||||
}
|
||||
|
||||
message.action = file_hook_action_lock_record;
|
||||
message.lock = l;
|
||||
message.command = cmd;
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
result = message.result;
|
||||
__set_errno(message.error);
|
||||
result = __handle_record_locking(cmd,l,fd,&error);
|
||||
if(result < 0)
|
||||
__set_errno(error);
|
||||
|
||||
va_end(arg);
|
||||
|
||||
@ -126,6 +126,12 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
|
||||
SHOWMSG("cmd=F_GETFL");
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_NON_BLOCKING))
|
||||
@ -140,6 +146,12 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
|
||||
SHOWMSG("cmd=F_SETFL");
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
va_start(arg,cmd);
|
||||
@ -236,19 +248,10 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ )
|
||||
if(FLAG_IS_CLEAR(__fd[i]->fd_Flags,FDF_IN_USE))
|
||||
{
|
||||
/* Got a file descriptor, duplicate it */
|
||||
message.action = file_hook_action_duplicate_fd;
|
||||
message.duplicate_fd = __fd[i];
|
||||
__duplicate_fd(__fd[i],fd);
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
/* If it worked, leave */
|
||||
if (message.result == 0)
|
||||
{
|
||||
result = i;
|
||||
goto out;
|
||||
}
|
||||
result = i;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fcntl_lseek.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: fcntl_lseek.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -44,10 +44,13 @@
|
||||
off_t
|
||||
__lseek(int file_descriptor, off_t offset, int mode, int * error_ptr)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
struct file_hook_message message;
|
||||
D_S(struct FileInfoBlock,fib);
|
||||
off_t result = -1;
|
||||
struct fd * fd;
|
||||
BOOL fib_is_valid = FALSE;
|
||||
LONG current_position;
|
||||
LONG new_position;
|
||||
LONG new_mode;
|
||||
|
||||
ENTER();
|
||||
|
||||
@ -55,8 +58,6 @@ __lseek(int file_descriptor, off_t offset, int mode, int * error_ptr)
|
||||
SHOWVALUE(offset);
|
||||
SHOWVALUE(mode);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
assert( error_ptr != NULL );
|
||||
assert( file_descriptor >= 0 && file_descriptor < __num_fd );
|
||||
assert( __fd[file_descriptor] != NULL );
|
||||
@ -72,6 +73,14 @@ __lseek(int file_descriptor, off_t offset, int mode, int * error_ptr)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
SHOWMSG("can't seek on a socket");
|
||||
|
||||
(*error_ptr) = ESPIPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(mode < SEEK_SET || mode > SEEK_END)
|
||||
{
|
||||
SHOWMSG("seek mode is invalid");
|
||||
@ -80,28 +89,105 @@ __lseek(int file_descriptor, off_t offset, int mode, int * error_ptr)
|
||||
goto out;
|
||||
}
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
if(mode == SEEK_CUR)
|
||||
new_mode = OFFSET_CURRENT;
|
||||
else if (mode == SEEK_SET)
|
||||
new_mode = OFFSET_BEGINNING;
|
||||
else
|
||||
new_mode = OFFSET_END;
|
||||
|
||||
#if defined(UNIX_PATH_SEMANTICS)
|
||||
D(("seek&extended to offset %ld, mode %ld; current position = %ld",offset,new_mode,Seek(fd->fd_DefaultFile,0,OFFSET_CURRENT)));
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
|
||||
{
|
||||
message.action = file_hook_action_seek_and_extend;
|
||||
current_position = fd->fd_Position;
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
message.action = file_hook_action_seek;
|
||||
PROFILE_OFF();
|
||||
current_position = Seek(fd->fd_DefaultFile,0,OFFSET_CURRENT);
|
||||
PROFILE_ON();
|
||||
|
||||
if(current_position < 0)
|
||||
{
|
||||
(*error_ptr) = EBADF;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif /* UNIX_PATH_SEMANTICS */
|
||||
|
||||
message.position = offset;
|
||||
message.mode = mode;
|
||||
new_position = current_position;
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
switch(new_mode)
|
||||
{
|
||||
case OFFSET_CURRENT:
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
new_position += offset;
|
||||
break;
|
||||
|
||||
(*error_ptr) = message.error;
|
||||
case OFFSET_BEGINNING:
|
||||
|
||||
result = message.result;
|
||||
new_position = offset;
|
||||
break;
|
||||
|
||||
case OFFSET_END:
|
||||
|
||||
if(__safe_examine_file_handle(fd->fd_DefaultFile,fib))
|
||||
{
|
||||
new_position = fib->fib_Size + offset;
|
||||
|
||||
fib_is_valid = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(new_position != current_position)
|
||||
{
|
||||
LONG position;
|
||||
|
||||
PROFILE_OFF();
|
||||
position = Seek(fd->fd_DefaultFile,offset,new_mode);
|
||||
PROFILE_ON();
|
||||
|
||||
if(position < 0)
|
||||
{
|
||||
D(("seek failed, mode=%ld (%ld), offset=%ld, ioerr=%ld",new_mode,message->mode,offset,IoErr()));
|
||||
|
||||
(*error_ptr) = __translate_io_error_to_errno(IoErr());
|
||||
|
||||
#if defined(UNIX_PATH_SEMANTICS)
|
||||
{
|
||||
if(NOT fib_is_valid && CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib))
|
||||
{
|
||||
(*error_ptr) = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(new_position <= fib->fib_Size)
|
||||
{
|
||||
(*error_ptr) = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(__grow_file_size(fd,new_position - fib->fib_Size) != OK)
|
||||
{
|
||||
(*error_ptr) = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
(*error_ptr) = __translate_io_error_to_errno(IoErr());
|
||||
goto out;
|
||||
}
|
||||
#endif /* UNIX_PATH_SEMANTICS */
|
||||
}
|
||||
}
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
|
||||
fd->fd_Position = new_position;
|
||||
|
||||
result = new_position;
|
||||
|
||||
out:
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: mount_fstatfs.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: mount_fstatfs.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -50,11 +50,11 @@
|
||||
int
|
||||
fstatfs(int file_descriptor, struct statfs *buf)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
struct file_hook_message message;
|
||||
D_S(struct InfoData,id);
|
||||
BPTR parent_dir = ZERO;
|
||||
int result = -1;
|
||||
struct fd * fd;
|
||||
LONG success;
|
||||
|
||||
ENTER();
|
||||
|
||||
@ -62,7 +62,6 @@ fstatfs(int file_descriptor, struct statfs *buf)
|
||||
SHOWPOINTER(buf);
|
||||
|
||||
assert( buf != NULL );
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
#if defined(CHECK_FOR_NULL_POINTERS)
|
||||
{
|
||||
@ -90,26 +89,44 @@ fstatfs(int file_descriptor, struct statfs *buf)
|
||||
goto out;
|
||||
}
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
|
||||
message.action = file_hook_action_info;
|
||||
message.info_data = id;
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
result = message.result;
|
||||
if(result != 0)
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(message.error);
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile);
|
||||
PROFILE_ON();
|
||||
|
||||
if(parent_dir == ZERO)
|
||||
{
|
||||
SHOWMSG("couldn't find parent directory");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
success = Info(parent_dir,id);
|
||||
PROFILE_ON();
|
||||
|
||||
if(NO success)
|
||||
{
|
||||
SHOWMSG("couldn't get info on drive");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
__convert_info_to_statfs(id,buf);
|
||||
|
||||
result = OK;
|
||||
|
||||
out:
|
||||
|
||||
UnLock(parent_dir);
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
_#
|
||||
# $Id: smakefile,v 1.20 2005-02-04 15:03:10 obarthel Exp $
|
||||
# $Id: smakefile,v 1.21 2005-02-18 18:53:16 obarthel Exp $
|
||||
#
|
||||
# :ts=8
|
||||
#
|
||||
@ -288,8 +288,10 @@ STDIO_OBJ = \
|
||||
stdio_data.o \
|
||||
stdio_dropiobreadbuffer.o \
|
||||
stdio_duplicate_fd.o \
|
||||
stdio_examine_fh.o \
|
||||
stdio_fclose.o \
|
||||
stdio_fdhookentry.o \
|
||||
stdio_record_locking.o \
|
||||
stdio_feof.o \
|
||||
stdio_ferror.o \
|
||||
stdio_fflush.o \
|
||||
@ -318,6 +320,7 @@ STDIO_OBJ = \
|
||||
stdio_gets.o \
|
||||
stdio_growfdtable.o \
|
||||
stdio_growiobtable.o \
|
||||
stdio_grow_file.o \
|
||||
stdio_initializefd.o \
|
||||
stdio_initializeiob.o \
|
||||
stdio_init_exit.o \
|
||||
@ -325,6 +328,7 @@ STDIO_OBJ = \
|
||||
stdio_locksemaphorename.o \
|
||||
stdio_nostdio.o \
|
||||
stdio_openiob.o \
|
||||
stdio_parent_of_fh.o \
|
||||
stdio_perror.o \
|
||||
stdio_popen.o \
|
||||
stdio_printf.o \
|
||||
@ -520,6 +524,7 @@ UNISTD_OBJ = \
|
||||
unistd_sleep.o \
|
||||
unistd_strip_double_slash.o \
|
||||
unistd_symlink.o \
|
||||
unistd_sync_fd.o \
|
||||
unistd_time_delay.o \
|
||||
unistd_timer.o \
|
||||
unistd_translatea2u.o \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_accept.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_accept.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -82,7 +82,7 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_bind.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_bind.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ bind(int sockfd,struct sockaddr *name,int namelen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_connect.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_connect.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ connect(int sockfd,struct sockaddr *name,int namelen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_get_descriptor.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_get_descriptor.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -42,7 +42,7 @@
|
||||
/****************************************************************************/
|
||||
|
||||
struct fd *
|
||||
__get_socket_descriptor(int socket_descriptor)
|
||||
__get_file_descriptor_socket(int socket_descriptor)
|
||||
{
|
||||
struct fd * result = NULL;
|
||||
struct fd * fd;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_getpeername.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_getpeername.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ getpeername(int sockfd,struct sockaddr *name,int *namelen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_getsockname.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_getsockname.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ getsockname(int sockfd,struct sockaddr *name,int *namelen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_getsockopt.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_getsockopt.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -81,7 +81,7 @@ getsockopt(int sockfd,int level,int optname,void *optval,int *optlen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_headers.h,v 1.5 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_headers.h,v 1.6 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -70,7 +70,7 @@ extern int NOCOMMON h_errno;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern struct fd * __get_socket_descriptor(int socket_descriptor);
|
||||
extern struct fd * __get_file_descriptor_socket(int socket_descriptor);
|
||||
extern void __socket_hook_entry(struct Hook * hook,struct fd * fd,struct file_hook_message * message);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_hook_entry.c,v 1.6 2005-02-04 15:03:10 obarthel Exp $
|
||||
* $Id: socket_hook_entry.c,v 1.7 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -114,26 +114,6 @@ __socket_hook_entry(
|
||||
|
||||
break;
|
||||
|
||||
case file_hook_action_duplicate_fd:
|
||||
|
||||
SHOWMSG("file_hook_action_duplicate_fd");
|
||||
|
||||
__duplicate_fd(message->duplicate_fd,fd);
|
||||
|
||||
result = 0;
|
||||
|
||||
break;
|
||||
|
||||
case file_hook_action_seek:
|
||||
case file_hook_action_seek_and_extend:
|
||||
|
||||
SHOWMSG("file_hook_action_seek");
|
||||
|
||||
result = -1;
|
||||
error = ESPIPE;
|
||||
|
||||
break;
|
||||
|
||||
case file_hook_action_set_blocking:
|
||||
|
||||
SHOWMSG("file_hook_action_set_blocking");
|
||||
@ -174,15 +154,6 @@ __socket_hook_entry(
|
||||
|
||||
break;
|
||||
|
||||
case file_hook_action_flush:
|
||||
|
||||
SHOWMSG("file_hook_action_flush attempted on socket");
|
||||
|
||||
result = -1;
|
||||
error = EINVAL;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
SHOWVALUE(message->action);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_ioctl.c,v 1.4 2005-01-02 09:07:08 obarthel Exp $
|
||||
* $Id: socket_ioctl.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -71,7 +71,7 @@ ioctl(int sockfd,unsigned long request, ... /* char *arg */)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_listen.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $
|
||||
* $Id: socket_listen.c,v 1.3 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -59,7 +59,7 @@ listen(int sockfd,int backlog)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_recv.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_recv.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -81,7 +81,7 @@ recv(int sockfd,void *buff,size_t nbytes,int flags)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_recvfrom.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_recvfrom.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -82,7 +82,7 @@ recvfrom(int sockfd,void *buff,int len,int flags,struct sockaddr *from,int *from
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_recvmsg.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_recvmsg.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ recvmsg(int sockfd,struct msghdr *msg,int flags)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_send.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_send.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -81,7 +81,7 @@ send(int sockfd,const void *buff,size_t nbytes,int flags)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_sendmsg.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_sendmsg.c,v 1.4 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -79,7 +79,7 @@ sendmsg(int sockfd,struct msghdr *msg,int flags)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_sendto.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_sendto.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -82,7 +82,7 @@ sendto(int sockfd,const void *buff,int len,int flags,struct sockaddr *to,int tol
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_setsockopt.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: socket_setsockopt.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -81,7 +81,7 @@ setsockopt(int sockfd,int level,int optname,const void *optval,int optlen)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: socket_shutdown.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $
|
||||
* $Id: socket_shutdown.c,v 1.3 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -59,7 +59,7 @@ shutdown(int sockfd, int how)
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IN_USE) );
|
||||
assert( FLAG_IS_SET(__fd[sockfd]->fd_Flags,FDF_IS_SOCKET) );
|
||||
|
||||
fd = __get_socket_descriptor(sockfd);
|
||||
fd = __get_file_descriptor_socket(sockfd);
|
||||
if(fd == NULL)
|
||||
goto out;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stat_fchmod.c,v 1.4 2005-02-03 16:56:15 obarthel Exp $
|
||||
* $Id: stat_fchmod.c,v 1.5 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -44,19 +44,20 @@
|
||||
int
|
||||
fchmod(int file_descriptor, mode_t mode)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
struct file_hook_message message;
|
||||
D_S(struct FileInfoBlock,fib);
|
||||
ULONG protection;
|
||||
BPTR parent_dir = ZERO;
|
||||
BPTR old_current_dir = ZERO;
|
||||
BOOL current_dir_changed = FALSE;
|
||||
int result = -1;
|
||||
struct fd * fd;
|
||||
LONG success;
|
||||
|
||||
ENTER();
|
||||
|
||||
SHOWVALUE(file_descriptor);
|
||||
SHOWVALUE(mode);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
assert( file_descriptor >= 0 && file_descriptor < __num_fd );
|
||||
assert( __fd[file_descriptor] != NULL );
|
||||
assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) );
|
||||
@ -71,6 +72,12 @@ fchmod(int file_descriptor, mode_t mode)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
protection = 0;
|
||||
|
||||
if(FLAG_IS_SET(mode,S_IRUSR))
|
||||
@ -109,21 +116,54 @@ fchmod(int file_descriptor, mode_t mode)
|
||||
if(FLAG_IS_SET(mode,S_IXOTH))
|
||||
SET_FLAG(protection,FIBF_OTR_EXECUTE);
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
PROFILE_OFF();
|
||||
parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile);
|
||||
PROFILE_ON();
|
||||
|
||||
message.action = file_hook_action_change_attributes;
|
||||
message.attributes = protection ^ (FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE);
|
||||
if(parent_dir == ZERO)
|
||||
{
|
||||
SHOWMSG("couldn't find parent directory");
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
PROFILE_OFF();
|
||||
success = __safe_examine_file_handle(fd->fd_DefaultFile,fib);
|
||||
PROFILE_ON();
|
||||
|
||||
result = message.result;
|
||||
if(NO success)
|
||||
{
|
||||
SHOWMSG("could not obtain file name");
|
||||
|
||||
__set_errno(message.error);
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_current_dir = CurrentDir(parent_dir);
|
||||
current_dir_changed = TRUE;
|
||||
|
||||
PROFILE_OFF();
|
||||
success = SetProtection(fib->fib_FileName,protection ^ (FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE));
|
||||
PROFILE_ON();
|
||||
|
||||
if(NO success)
|
||||
{
|
||||
SHOWMSG("could not change protection bits");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = OK;
|
||||
|
||||
out:
|
||||
|
||||
if(current_dir_changed)
|
||||
CurrentDir(old_current_dir);
|
||||
|
||||
UnLock(parent_dir);
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
70
library/stdio_examine_fh.c
Normal file
70
library/stdio_examine_fh.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id: stdio_examine_fh.c,v 1.1 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _STDIO_HEADERS_H
|
||||
#include "stdio_headers.h"
|
||||
#endif /* _STDIO_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* This is used in place of ExamineFH() in order to work around a bug in
|
||||
* dos.library V40 and below: a "NIL:" file handle will crash the
|
||||
* ExamineFH() function.
|
||||
*/
|
||||
LONG
|
||||
__safe_examine_file_handle(BPTR file_handle,struct FileInfoBlock *fib)
|
||||
{
|
||||
LONG result = DOSFALSE;
|
||||
|
||||
assert( fib != NULL );
|
||||
|
||||
#ifndef __amigaos4__
|
||||
{
|
||||
struct FileHandle * fh = (struct FileHandle *)BADDR(file_handle);
|
||||
|
||||
if(fh == NULL || fh->fh_Type == NULL)
|
||||
{
|
||||
SetIoErr(ERROR_OBJECT_WRONG_TYPE);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
PROFILE_OFF();
|
||||
result = ExamineFH(file_handle,fib);
|
||||
PROFILE_ON();
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
161
library/stdio_grow_file.c
Normal file
161
library/stdio_grow_file.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* $Id: stdio_grow_file.c,v 1.1 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _STDIO_HEADERS_H
|
||||
#include "stdio_headers.h"
|
||||
#endif /* _STDIO_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following is not part of the ISO 'C' (1994) standard. */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Seek to the end of a file, then add a certain number of 0 bytes. */
|
||||
int
|
||||
__grow_file_size(struct fd * fd,int num_bytes)
|
||||
{
|
||||
unsigned char * aligned_buffer;
|
||||
unsigned char * buffer;
|
||||
struct FileHandle * fh;
|
||||
D_S(struct InfoData,id);
|
||||
LONG block_size;
|
||||
int bytes_written;
|
||||
int buffer_size;
|
||||
int size;
|
||||
int position;
|
||||
int current_position;
|
||||
int alignment_skip;
|
||||
int result = -1;
|
||||
|
||||
assert( fd != NULL );
|
||||
|
||||
D(("we have to grow the file by %ld bytes",num_bytes));
|
||||
|
||||
block_size = 0;
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
fh = BADDR(fd->fd_DefaultFile);
|
||||
if(fh != NULL && fh->fh_Type != NULL && DoPkt(fh->fh_Type,ACTION_DISK_INFO,MKBADDR(id),0,0,0,0))
|
||||
block_size = id->id_BytesPerBlock;
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
if(block_size < 512)
|
||||
block_size = 512;
|
||||
|
||||
/* We have to fill up the file with zero bytes.
|
||||
* That data comes from a local buffer. How
|
||||
* large can we make it?
|
||||
*/
|
||||
buffer_size = 8 * block_size;
|
||||
if(buffer_size > num_bytes)
|
||||
buffer_size = num_bytes;
|
||||
|
||||
/* Allocate a little more memory than required to allow for
|
||||
* the buffer to be aligned to a cache line boundary.
|
||||
*/
|
||||
buffer = malloc((size_t)buffer_size + (CACHE_LINE_SIZE-1));
|
||||
if(buffer == NULL)
|
||||
{
|
||||
SHOWMSG("not enough memory for write buffer");
|
||||
|
||||
SetIoErr(ERROR_NO_FREE_STORE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Align the buffer to a cache line boundary. */
|
||||
aligned_buffer = (unsigned char *)(((ULONG)(buffer + (CACHE_LINE_SIZE-1))) & ~(CACHE_LINE_SIZE-1));
|
||||
|
||||
memset(aligned_buffer,0,(size_t)buffer_size);
|
||||
|
||||
PROFILE_OFF();
|
||||
position = Seek(fd->fd_DefaultFile,0,OFFSET_END);
|
||||
PROFILE_ON();
|
||||
|
||||
if(position == -1)
|
||||
{
|
||||
SHOWMSG("could not move to the end of the file");
|
||||
goto out;
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
current_position = Seek(fd->fd_DefaultFile,0,OFFSET_CURRENT);
|
||||
PROFILE_ON();
|
||||
|
||||
/* Try to make the first write access align the file position
|
||||
* to a block offset. Subsequent writes will then access the
|
||||
* file at positions that are multiples of the block size.
|
||||
*/
|
||||
if(num_bytes > block_size && (current_position % block_size) != 0)
|
||||
alignment_skip = block_size - (current_position % block_size);
|
||||
else
|
||||
alignment_skip = 0;
|
||||
|
||||
while(num_bytes > 0)
|
||||
{
|
||||
if(__check_abort_enabled)
|
||||
__check_abort();
|
||||
|
||||
size = buffer_size;
|
||||
if(size > num_bytes)
|
||||
size = num_bytes;
|
||||
|
||||
/* If possible, even out the block offset. */
|
||||
if(alignment_skip > 0 && size > alignment_skip)
|
||||
size = alignment_skip;
|
||||
|
||||
alignment_skip = 0;
|
||||
|
||||
PROFILE_OFF();
|
||||
bytes_written = Write(fd->fd_DefaultFile,aligned_buffer,size);
|
||||
PROFILE_ON();
|
||||
|
||||
if(bytes_written != size)
|
||||
goto out;
|
||||
|
||||
num_bytes -= size;
|
||||
}
|
||||
|
||||
SHOWMSG("all done.");
|
||||
|
||||
result = 0;
|
||||
|
||||
out:
|
||||
|
||||
if(buffer != NULL)
|
||||
free(buffer);
|
||||
|
||||
return(result);
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_headers.h,v 1.12 2005-02-04 15:03:11 obarthel Exp $
|
||||
* $Id: stdio_headers.h,v 1.13 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -271,6 +271,15 @@ struct iob
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Forward declaration... */
|
||||
struct fd;
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
typedef void (*fd_cleanup_t)(struct fd * fd);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
struct fd
|
||||
{
|
||||
struct Hook * fd_Hook; /* Hook to invoke to perform actions */
|
||||
@ -283,6 +292,8 @@ struct fd
|
||||
struct Hook fd_DefaultHook; /* Static hook */
|
||||
BPTR fd_DefaultFile; /* A dos.library file handle */
|
||||
LONG fd_Position; /* Cached file position (seek offset). */
|
||||
|
||||
fd_cleanup_t fd_Cleanup; /* Cleanup function, if any. */
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
@ -313,18 +324,9 @@ enum file_hook_action_t
|
||||
file_hook_action_write,
|
||||
file_hook_action_seek,
|
||||
file_hook_action_close,
|
||||
file_hook_action_lock_record,
|
||||
file_hook_action_set_blocking,
|
||||
file_hook_action_change_owner,
|
||||
file_hook_action_truncate,
|
||||
file_hook_action_examine,
|
||||
file_hook_action_change_attributes,
|
||||
file_hook_action_info,
|
||||
file_hook_action_duplicate_fd,
|
||||
file_hook_action_seek_and_extend,
|
||||
file_hook_action_is_interactive,
|
||||
file_hook_action_set_async,
|
||||
file_hook_action_flush
|
||||
file_hook_action_examine
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
@ -339,24 +341,13 @@ struct file_hook_message
|
||||
long position; /* The seek position */
|
||||
long mode; /* The seek mode */
|
||||
|
||||
struct flock * lock; /* Record locking request */
|
||||
int command; /* What kind of locking command was sent */
|
||||
|
||||
int arg; /* Whether or not this file should
|
||||
be set non-blocking */
|
||||
|
||||
uid_t owner;
|
||||
gid_t group;
|
||||
be set non-blocking or use
|
||||
asynchronous I/O */
|
||||
|
||||
struct FileInfoBlock * file_info;
|
||||
struct MsgPort * file_system;
|
||||
|
||||
struct InfoData * info_data;
|
||||
|
||||
struct fd * duplicate_fd;
|
||||
|
||||
ULONG attributes;
|
||||
|
||||
int error; /* Error code, if any... */
|
||||
|
||||
long result; /* Whatever this produced */
|
||||
|
||||
68
library/stdio_parent_of_fh.c
Normal file
68
library/stdio_parent_of_fh.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* $Id: stdio_parent_of_fh.c,v 1.1 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _STDIO_HEADERS_H
|
||||
#include "stdio_headers.h"
|
||||
#endif /* _STDIO_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* This is used in place of ParentOfFH() in order to work around a bug in
|
||||
* dos.library V40 and below: a "NIL:" file handle will crash the
|
||||
* ParentOfFH() function.
|
||||
*/
|
||||
BPTR
|
||||
__safe_parent_of_file_handle(BPTR file_handle)
|
||||
{
|
||||
BPTR result = ZERO;
|
||||
|
||||
#ifndef __amigaos4__
|
||||
{
|
||||
struct FileHandle * fh = (struct FileHandle *)BADDR(file_handle);
|
||||
|
||||
if(fh == NULL || fh->fh_Type == NULL)
|
||||
{
|
||||
SetIoErr(ERROR_OBJECT_WRONG_TYPE);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
PROFILE_OFF();
|
||||
result = ParentOfFH(file_handle);
|
||||
PROFILE_ON();
|
||||
|
||||
out:
|
||||
|
||||
return(result);
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdio_protos.h,v 1.5 2005-02-03 16:56:16 obarthel Exp $
|
||||
* $Id: stdio_protos.h,v 1.6 2005-02-18 18:53:16 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -205,4 +205,29 @@ extern void __duplicate_fd(struct fd * duplicate_fd,struct fd * original_fd);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdio_examine_fh.c */
|
||||
extern LONG __safe_examine_file_handle(BPTR file_handle,struct FileInfoBlock *fib);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdio_parent_of_fh.c */
|
||||
extern BPTR __safe_parent_of_file_handle(BPTR file_handle);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdio_grow_file.c */
|
||||
extern int __grow_file_size(struct fd * fd,int num_bytes);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* unistd_sync_fd.c */
|
||||
extern void __sync_fd(struct fd * fd,int mode);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* stdio_record_locking.c */
|
||||
extern int __handle_record_locking(int cmd,struct flock * l,struct fd * fd,int * error_ptr);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#endif /* _STDIO_PROTOS_H */
|
||||
|
||||
1202
library/stdio_record_locking.c
Normal file
1202
library/stdio_record_locking.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_dup2.c,v 1.4 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: unistd_dup2.c,v 1.5 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -104,7 +104,6 @@ dup2(int file_descriptor1, int file_descriptor2)
|
||||
|
||||
if(file_descriptor1 != file_descriptor2)
|
||||
{
|
||||
struct file_hook_message message;
|
||||
struct fd * fd2;
|
||||
|
||||
/* Have a look at the requested file descriptor. */
|
||||
@ -123,21 +122,7 @@ dup2(int file_descriptor1, int file_descriptor2)
|
||||
goto out;
|
||||
}
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
|
||||
message.action = file_hook_action_duplicate_fd;
|
||||
message.duplicate_fd = fd2;
|
||||
|
||||
assert( fd1->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd1->fd_Hook,fd1,&message);
|
||||
|
||||
result = message.result;
|
||||
if(result != 0)
|
||||
{
|
||||
__set_errno(message.error);
|
||||
goto out;
|
||||
}
|
||||
__duplicate_fd(fd2,fd1);
|
||||
}
|
||||
|
||||
result = file_descriptor2;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_fchown.c,v 1.4 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: unistd_fchown.c,v 1.5 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -44,10 +44,13 @@
|
||||
int
|
||||
fchown(int file_descriptor, uid_t owner, gid_t group)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
struct file_hook_message message;
|
||||
D_S(struct FileInfoBlock,fib);
|
||||
BPTR parent_dir = ZERO;
|
||||
BPTR old_current_dir = ZERO;
|
||||
BOOL current_dir_changed = FALSE;
|
||||
int result = -1;
|
||||
struct fd * fd;
|
||||
LONG success;
|
||||
|
||||
ENTER();
|
||||
|
||||
@ -55,8 +58,6 @@ fchown(int file_descriptor, uid_t owner, gid_t group)
|
||||
SHOWVALUE(owner);
|
||||
SHOWVALUE(group);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
assert( file_descriptor >= 0 && file_descriptor < __num_fd );
|
||||
assert( __fd[file_descriptor] != NULL );
|
||||
assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) );
|
||||
@ -71,22 +72,106 @@ fchown(int file_descriptor, uid_t owner, gid_t group)
|
||||
goto out;
|
||||
}
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
message.action = file_hook_action_change_owner;
|
||||
message.owner = owner;
|
||||
message.group = group;
|
||||
if(owner > 65535 || group > 65535)
|
||||
{
|
||||
SHOWMSG("owner or group not OK");
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
SHOWVALUE(owner);
|
||||
SHOWVALUE(group);
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = message.result;
|
||||
PROFILE_OFF();
|
||||
success = (__safe_examine_file_handle(fd->fd_DefaultFile,fib) && (parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile)) != ZERO);
|
||||
PROFILE_ON();
|
||||
|
||||
__set_errno(message.error);
|
||||
if(NO success)
|
||||
{
|
||||
SHOWMSG("couldn't find parent directory");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_current_dir = CurrentDir(parent_dir);
|
||||
current_dir_changed = TRUE;
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
#if defined(__amigaos4__)
|
||||
{
|
||||
success = SetOwner(fib->fib_FileName,(LONG)((((ULONG)owner) << 16) | group));
|
||||
}
|
||||
#else
|
||||
{
|
||||
if(((struct Library *)DOSBase)->lib_Version >= 39)
|
||||
{
|
||||
success = SetOwner(fib->fib_FileName,(LONG)((((ULONG)owner) << 16) | group));
|
||||
}
|
||||
else
|
||||
{
|
||||
D_S(struct bcpl_name,new_name);
|
||||
struct DevProc * dvp;
|
||||
unsigned int len;
|
||||
|
||||
SHOWMSG("have to do this manually...");
|
||||
|
||||
success = DOSFALSE;
|
||||
|
||||
len = strlen(fib->fib_FileName);
|
||||
|
||||
assert( len < sizeof(new_name->name) );
|
||||
|
||||
dvp = GetDeviceProc(fib->fib_FileName,NULL);
|
||||
if(dvp != NULL)
|
||||
{
|
||||
LONG error;
|
||||
|
||||
new_name->name[0] = len;
|
||||
memmove(&new_name->name[1],fib->fib_FileName,len);
|
||||
|
||||
success = DoPkt(dvp->dvp_Port,ACTION_SET_OWNER,dvp->dvp_Lock,MKBADDR(new_name),(LONG)((((ULONG)owner) << 16) | group),0,0);
|
||||
error = IoErr();
|
||||
|
||||
FreeDeviceProc(dvp);
|
||||
|
||||
SetIoErr(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __amigaos4__ */
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
if(NO success)
|
||||
{
|
||||
SHOWMSG("couldn't change owner/group");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = OK;
|
||||
|
||||
out:
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
UnLock(parent_dir);
|
||||
|
||||
if(current_dir_changed)
|
||||
CurrentDir(old_current_dir);
|
||||
|
||||
PROFILE_ON();
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_fdatasync.c,v 1.1 2005-02-04 15:03:11 obarthel Exp $
|
||||
* $Id: unistd_fdatasync.c,v 1.2 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -50,9 +50,6 @@
|
||||
int
|
||||
fdatasync(int file_descriptor)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
|
||||
struct file_hook_message message;
|
||||
struct fd * fd;
|
||||
int result = -1;
|
||||
|
||||
@ -60,8 +57,6 @@ fdatasync(int file_descriptor)
|
||||
|
||||
SHOWVALUE(file_descriptor);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
if(__check_abort_enabled)
|
||||
__check_abort();
|
||||
|
||||
@ -76,20 +71,16 @@ fdatasync(int file_descriptor)
|
||||
goto out;
|
||||
}
|
||||
|
||||
message.action = file_hook_action_flush;
|
||||
message.arg = 0; /* flush just the data */
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
result = message.result;
|
||||
if(result != 0)
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(message.error);
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
__sync_fd(fd,0); /* flush just the data */
|
||||
|
||||
result = OK;
|
||||
|
||||
out:
|
||||
|
||||
RETURN(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_fsync.c,v 1.1 2005-02-04 15:03:11 obarthel Exp $
|
||||
* $Id: unistd_fsync.c,v 1.2 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -49,9 +49,6 @@
|
||||
int
|
||||
fsync(int file_descriptor)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
|
||||
struct file_hook_message message;
|
||||
struct fd * fd;
|
||||
int result = -1;
|
||||
|
||||
@ -59,8 +56,6 @@ fsync(int file_descriptor)
|
||||
|
||||
SHOWVALUE(file_descriptor);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
if(__check_abort_enabled)
|
||||
__check_abort();
|
||||
|
||||
@ -75,20 +70,16 @@ fsync(int file_descriptor)
|
||||
goto out;
|
||||
}
|
||||
|
||||
message.action = file_hook_action_flush;
|
||||
message.arg = 1; /* flush everything */
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
result = message.result;
|
||||
if(result != 0)
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(message.error);
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
__sync_fd(fd,1); /* flush everything */
|
||||
|
||||
result = OK;
|
||||
|
||||
out:
|
||||
|
||||
RETURN(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: unistd_ftruncate.c,v 1.4 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: unistd_ftruncate.c,v 1.5 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -44,19 +44,17 @@
|
||||
int
|
||||
ftruncate(int file_descriptor, off_t length)
|
||||
{
|
||||
DECLARE_UTILITYBASE();
|
||||
struct file_hook_message message;
|
||||
D_S(struct FileInfoBlock,fib);
|
||||
int result = -1;
|
||||
struct fd * fd;
|
||||
long int position;
|
||||
BOOL success;
|
||||
|
||||
ENTER();
|
||||
|
||||
SHOWVALUE(file_descriptor);
|
||||
SHOWVALUE(length);
|
||||
|
||||
assert( UtilityBase != NULL );
|
||||
|
||||
assert( file_descriptor >= 0 && file_descriptor < __num_fd );
|
||||
assert( __fd[file_descriptor] != NULL );
|
||||
assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) );
|
||||
@ -71,6 +69,12 @@ ftruncate(int file_descriptor, off_t length)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET))
|
||||
{
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(length < 0)
|
||||
{
|
||||
SHOWMSG("invalid length");
|
||||
@ -85,7 +89,7 @@ ftruncate(int file_descriptor, off_t length)
|
||||
{
|
||||
SHOWMSG("file descriptor is not write-enabled");
|
||||
|
||||
__set_errno(EBADF);
|
||||
__set_errno(EINVAL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -94,18 +98,42 @@ ftruncate(int file_descriptor, off_t length)
|
||||
if(position < 0)
|
||||
goto out;
|
||||
|
||||
SHOWMSG("calling the hook");
|
||||
|
||||
message.action = file_hook_action_truncate;
|
||||
message.size = length;
|
||||
|
||||
assert( fd->fd_Hook != NULL );
|
||||
|
||||
CallHookPkt(fd->fd_Hook,fd,&message);
|
||||
|
||||
if(message.result < 0)
|
||||
if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib))
|
||||
{
|
||||
__set_errno(message.error);
|
||||
SHOWMSG("couldn't examine file");
|
||||
|
||||
__set_errno(__translate_io_error_to_errno(IoErr()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
PROFILE_OFF();
|
||||
|
||||
if(length < fib->fib_Size)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
success = (Seek(fd->fd_DefaultFile,fib->fib_Size,OFFSET_BEGINNING) != -1 && __grow_file_size(fd,length - fib->fib_Size) == OK);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
70
library/unistd_sync_fd.c
Normal file
70
library/unistd_sync_fd.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id: unistd_sync_fd.c,v 1.1 2005-02-18 18:53:17 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
* Portable ISO 'C' (1994) runtime library for the Amiga computer
|
||||
* Copyright (c) 2002-2005 by Olaf Barthel <olsen@sourcery.han.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Neither the name of Olaf Barthel nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _UNISTD_HEADERS_H
|
||||
#include "unistd_headers.h"
|
||||
#endif /* _UNISTD_HEADERS_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#if defined(__amigaos4__) && !defined(Flush)
|
||||
#define Flush(fh) FFlush(fh)
|
||||
#endif /* __amigaos4__ && !Flush */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* The following is not part of the ISO 'C' (1994) standard. */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void
|
||||
__sync_fd(struct fd * fd,int mode)
|
||||
{
|
||||
assert( fd != NULL );
|
||||
|
||||
if(fd->fd_DefaultFile != ZERO)
|
||||
{
|
||||
/* The mode tells us what to flush. 0 means "flush just the data", and
|
||||
everything else means "flush everything. */
|
||||
Flush(fd->fd_DefaultFile);
|
||||
|
||||
if(mode != 0)
|
||||
{
|
||||
struct FileHandle * fh = BADDR(fd->fd_DefaultFile);
|
||||
|
||||
/* Verify that this file is not bound to "NIL:". */
|
||||
if(fh->fh_Type != NULL)
|
||||
DoPkt(fh->fh_Type,ACTION_FLUSH, 0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user