1
0
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:
Olaf Barthel
2005-02-18 18:53:17 +00:00
parent ea638f0970
commit 99547756fe
40 changed files with 2058 additions and 2101 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
/****************************************************************************/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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
View 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);
}

View File

@ -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 */

View 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);
}

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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);
}
}
}