1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- File descriptors produced by dup() or dup2() now work exactly like

the original file descriptors they are duplicates of. I modified the
  function which maps file descriptor numbers to file descriptor
  table entries to return the table entries of the original files.

- In the thread-safe library, duplicated stdin/stdout/stderr
  descriptors now work like the "real" ones. This is true even if
  the "real" ones were closed and only their former aliases remain.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14909 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2005-04-01 18:46:37 +00:00
parent 09b52e077f
commit 6f010ddf87
19 changed files with 155 additions and 95 deletions

View File

@ -20,6 +20,15 @@
- Simplified the library/open close code in "stdlib_main.c".
- File descriptors produced by dup() or dup2() now work exactly like
the original file descriptors they are duplicates of. I modified the
function which maps file descriptor numbers to file descriptor
table entries to return the table entries of the original files.
- In the thread-safe library, duplicated stdin/stdout/stderr
descriptors now work like the "real" ones. This is true even if
the "real" ones were closed and only their former aliases remain.
c.lib 1.190 (25.3.2005)

View File

@ -1,5 +1,5 @@
/*
* $Id: fcntl_close.c,v 1.10 2005-02-20 15:46:52 obarthel Exp $
* $Id: fcntl_close.c,v 1.11 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -59,7 +59,9 @@ close(int file_descriptor)
if(__check_abort_enabled)
__check_abort();
fd = __get_file_descriptor(file_descriptor);
/* We want to affect this very file descriptor and not the
original one associated with an alias of it. */
fd = __get_file_descriptor_dont_resolve(file_descriptor);
if(fd == NULL)
{
__set_errno(EBADF);

View File

@ -1,5 +1,5 @@
/*
* $Id: fcntl_lock.c,v 1.2 2005-03-12 09:43:47 obarthel Exp $
* $Id: fcntl_lock.c,v 1.3 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -44,11 +44,6 @@
void
__fd_lock(struct fd * fd)
{
/* If this descriptor is really an alias, use the semaphore
associated with the original instead. */
if(fd != NULL && fd->fd_Original != NULL)
fd = fd->fd_Original;
if(fd != NULL && fd->fd_Lock != NULL)
ObtainSemaphore(fd->fd_Lock);
}
@ -58,11 +53,6 @@ __fd_lock(struct fd * fd)
void
__fd_unlock(struct fd * fd)
{
/* If this descriptor is really an alias, use the semaphore
associated with the original instead. */
if(fd != NULL && fd->fd_Original != NULL)
fd = fd->fd_Original;
if(fd != NULL && fd->fd_Lock != NULL)
ReleaseSemaphore(fd->fd_Lock);
}

View File

@ -1,5 +1,5 @@
/*
* $Id: mount_fstatfs.c,v 1.9 2005-03-07 11:16:43 obarthel Exp $
* $Id: mount_fstatfs.c,v 1.10 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -97,7 +97,7 @@ fstatfs(int file_descriptor, struct statfs *buf)
goto out;
}
if(fd->fd_DefaultFile == ZERO)
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
__set_errno(EBADF);
goto out;

View File

@ -1,5 +1,5 @@
/*
* $Id: signal_raise.c,v 1.6 2005-03-27 10:02:50 obarthel Exp $
* $Id: signal_raise.c,v 1.7 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -112,10 +112,6 @@ raise(int sig)
__print_termination_message(break_string);
SHOWMSG("bye, bye...");
/* Note that we drop into the exit() function which
does not trigger the exit trap. */
_exit(EXIT_FAILURE);
}
/* Drop straight into abort(), which might call signal()

View File

@ -1,5 +1,5 @@
/*
* $Id: socket_select.c,v 1.9 2005-03-25 08:50:59 obarthel Exp $
* $Id: socket_select.c,v 1.10 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -309,9 +309,9 @@ map_descriptor_sets(
else
{
/* We only watch files bound to console streams. */
if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE) || fd->fd_DefaultFile == ZERO)
if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE) || FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
SHOWMSG("this is a file");
SHOWMSG("this is a file, or otherwise unsuitable");
continue;
}
@ -761,7 +761,7 @@ select(int num_fds,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct
{
if(FLAG_IS_SET(fd->fd_Flags,FDF_READ))
{
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET) && fd->fd_DefaultFile != ZERO );
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET) && FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO) );
/* Does this one have input? */
PROFILE_OFF();
@ -921,7 +921,7 @@ select(int num_fds,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct
{
if(FLAG_IS_SET(fd->fd_Flags,FDF_READ))
{
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET) && fd->fd_DefaultFile != ZERO );
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET) && FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO) );
PROFILE_OFF();

View File

@ -1,5 +1,5 @@
/*
* $Id: stat_fchmod.c,v 1.8 2005-03-07 11:16:43 obarthel Exp $
* $Id: stat_fchmod.c,v 1.9 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -80,7 +80,7 @@ fchmod(int file_descriptor, mode_t mode)
goto out;
}
if(fd->fd_DefaultFile == ZERO)
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
__set_errno(EBADF);
goto out;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_fdhookentry.c,v 1.24 2005-03-24 16:40:16 obarthel Exp $
* $Id: stdio_fdhookentry.c,v 1.25 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -65,6 +65,7 @@ __fd_hook_entry(
int new_mode;
char * buffer = NULL;
int result = -1;
BOOL is_aliased;
BPTR file;
ENTER();
@ -74,52 +75,61 @@ __fd_hook_entry(
__fd_lock(fd);
file = fd->fd_DefaultFile;
#if defined(__THREAD_SAFE)
{
/* Check if this file should be dynamically bound to one of the
three standard I/O streams. */
if(file == ZERO && FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
/* We assume that the file descriptors are organized in the
default layout, i.e. 0 = stdin, 1 = stdout, 2 = stderr.
It might be that the table does not hold more than one
entry, though, hence the __num_fd checks prior to
accessing the table entries. The first test is really
redundant since there has to be at least one file
descriptor table entry around or this function would
not have been invoked in the first place. */
if (/*__num_fd > STDIN_FILENO &&*/ fd == __fd[STDIN_FILENO])
switch(fd->fd_DefaultFile)
{
file = Input();
}
else if (__num_fd > STDOUT_FILENO && fd == __fd[STDOUT_FILENO])
{
file = Output();
}
else if (__num_fd > STDERR_FILENO && fd == __fd[STDERR_FILENO])
{
#if defined(__amigaos4__)
{
file = ErrorOutput();
}
#else
{
struct Process * this_process = (struct Process *)FindTask(NULL);
case STDIN_FILENO:
file = this_process->pr_CES;
}
#endif /* __amigaos4__ */
file = Input();
break;
case STDOUT_FILENO:
/* The following is rather controversial; if the standard error stream
is unavailable, we default to reuse the standard output stream. This
is problematic if the standard output stream was redirected and should
not be the same as the standard error output stream. */
if(file == ZERO)
file = Output();
break;
case STDERR_FILENO:
#if defined(__amigaos4__)
{
file = ErrorOutput();
}
#else
{
struct Process * this_process = (struct Process *)FindTask(NULL);
file = this_process->pr_CES;
}
#endif /* __amigaos4__ */
/* The following is rather controversial; if the standard error stream
is unavailable, we default to reuse the standard output stream. This
is problematic if the standard output stream was redirected and should
not be the same as the standard error output stream. */
if(file == ZERO)
file = Output();
break;
default:
file = ZERO;
break;
}
}
else
{
file = fd->fd_DefaultFile;
}
}
#else
{
file = fd->fd_DefaultFile;
}
#endif /* __THREAD_SAFE */
@ -223,11 +233,12 @@ __fd_hook_entry(
result = 0;
/* If this is an alias, just remove it. */
if(__fd_is_aliased(fd))
is_aliased = __fd_is_aliased(fd);
if(is_aliased)
{
__remove_fd_alias(fd);
}
else if (fd->fd_DefaultFile != ZERO)
else if (FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO))
{
/* Are we disallowed to close this file? */
if(FLAG_IS_SET(fd->fd_Flags,FDF_NO_CLOSE))
@ -405,7 +416,8 @@ __fd_hook_entry(
#if defined(__THREAD_SAFE)
{
/* Free the lock semaphore now. */
__delete_semaphore(fd->fd_Lock);
if(NOT is_aliased)
__delete_semaphore(fd->fd_Lock);
}
#endif /* __THREAD_SAFE */

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_file_init.c,v 1.7 2005-03-24 16:40:16 obarthel Exp $
* $Id: stdio_file_init.c,v 1.8 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -274,10 +274,10 @@ FILE_CONSTRUCTOR(stdio_file_init)
goto out;
}
/* We ignore the file handle and let the file I/O code
in the fd hook pick up the appropriate Input/Output/ErrorOutput
handle. */
default_file = ZERO;
/* We ignore the file handle and let the file I/O
code in the fd hook pick up the appropriate
Input/Output/ErrorOutput handle. */
default_file = i;
fd_flags |= FDF_NO_CLOSE | FDF_STDIO;
}
@ -364,7 +364,7 @@ FILE_CONSTRUCTOR(stdio_file_init)
PROFILE_OFF();
/* Figure out if the standard error stream is bound to a console. */
if(__fd[STDERR_FILENO]->fd_DefaultFile != ZERO)
if(FLAG_IS_CLEAR(__fd[STDERR_FILENO]->fd_Flags,FDF_STDIO))
{
if(IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile))
SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_IS_INTERACTIVE);

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_get_file_descriptor.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $
* $Id: stdio_get_file_descriptor.c,v 1.4 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -37,8 +37,16 @@
/****************************************************************************/
struct fd *
__get_file_descriptor(int file_descriptor)
enum resolution_mode_t
{
resolution_mode_exact, /* Return the descriptor exactly as it is. */
resolution_mode_alias /* Resolve the descriptor's alias, if necessary. */
};
/****************************************************************************/
STATIC struct fd *
get_file_descriptor(int file_descriptor,enum resolution_mode_t resolution_mode)
{
struct fd * result = NULL;
struct fd * fd;
@ -64,6 +72,10 @@ __get_file_descriptor(int file_descriptor)
goto out;
}
/* Move up to the original file, if this is an alias. */
if(resolution_mode == resolution_mode_alias && fd->fd_Original != NULL)
fd = fd->fd_Original;
result = fd;
out:
@ -72,3 +84,27 @@ __get_file_descriptor(int file_descriptor)
return(result);
}
/****************************************************************************/
struct fd *
__get_file_descriptor(int file_descriptor)
{
struct fd * result;
result = get_file_descriptor(file_descriptor,resolution_mode_alias);
return(result);
}
/****************************************************************************/
struct fd *
__get_file_descriptor_dont_resolve(int file_descriptor)
{
struct fd * result;
result = get_file_descriptor(file_descriptor,resolution_mode_exact);
return(result);
}

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_grow_file.c,v 1.2 2005-03-14 10:03:06 obarthel Exp $
* $Id: stdio_grow_file.c,v 1.3 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -67,6 +67,8 @@ __grow_file_size(struct fd * fd,int num_bytes)
PROFILE_OFF();
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO) );
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;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_iobhookentry.c,v 1.4 2005-02-21 16:09:41 obarthel Exp $
* $Id: stdio_iobhookentry.c,v 1.5 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -58,7 +58,13 @@ __iob_hook_entry(
assert( __fd[file_iob->iob_Descriptor] != NULL );
assert( FLAG_IS_SET(__fd[file_iob->iob_Descriptor]->fd_Flags,FDF_IN_USE) );
fd = __get_file_descriptor(file_iob->iob_Descriptor);
/* When closing, we want to affect this very file descriptor
and not the original one associated with an alias of it. */
if(fam->fam_Action == file_action_close)
fd = __get_file_descriptor_dont_resolve(file_iob->iob_Descriptor);
else
fd = __get_file_descriptor(file_iob->iob_Descriptor);
if(fd == NULL)
{
fam->fam_Error = EBADF;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_protos.h,v 1.16 2005-03-20 11:18:06 obarthel Exp $
* $Id: stdio_protos.h,v 1.17 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -84,6 +84,7 @@ extern int __translate_access_io_error_to_errno(LONG io_error);
/* stdio_get_file_descriptor.c */
extern struct fd * __get_file_descriptor(int file_descriptor);
extern struct fd * __get_file_descriptor_dont_resolve(int file_descriptor);
/****************************************************************************/

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_record_locking.c,v 1.8 2005-03-26 10:53:35 obarthel Exp $
* $Id: stdio_record_locking.c,v 1.9 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -772,6 +772,7 @@ __handle_record_locking(int cmd,struct flock * l,struct fd * fd,int * error_ptr)
assert( F_RDLCK <= l->l_type && l->l_type <= F_WRLCK );
assert( SEEK_SET <= l->l_whence && l->l_whence <= SEEK_END );
assert( error_ptr != NULL );
assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO) );
/* Remember to unlock any records before closing the file. */
fd->fd_Cleanup = cleanup_locked_records;

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_remove_fd_alias.c,v 1.2 2005-02-28 13:22:53 obarthel Exp $
* $Id: stdio_remove_fd_alias.c,v 1.3 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -66,14 +66,22 @@ __remove_fd_alias(struct fd * fd)
else if (fd->fd_NextLink != NULL) /* this one has aliases attached; it is the 'original' resource */
{
struct fd * first_alias;
struct fd * next_alias;
struct fd * list_fd;
/* The first link now becomes the original resource */
first_alias = fd->fd_NextLink;
next_alias = first_alias->fd_NextLink;
/* Structure copy... */
(*first_alias) = (*fd);
/* Fix up the linkage. */
first_alias->fd_NextLink = next_alias;
first_alias->fd_Original = NULL;
/* The resources are migrated to the first link. */
for(list_fd = first_alias->fd_NextLink ;
for(list_fd = next_alias ;
list_fd != NULL ;
list_fd = list_fd->fd_NextLink)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: stdlib_main.c,v 1.21 2005-03-30 19:37:43 obarthel Exp $
* $Id: stdlib_main.c,v 1.22 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -98,6 +98,9 @@ call_main(void)
/* Switch off function name printing, if it was enabled. */
__hide_profile_names();
/* From this point on, don't worry about ^C checking any more. */
__check_abort_enabled = FALSE;
/* If we end up here with the __stack_overflow variable
set then the stack overflow handler dropped into
longjmp() and _exit() did not get called. This
@ -107,12 +110,6 @@ call_main(void)
{
SHOWMSG("we have a stack overflow");
/* Dump whatever is waiting to be written to the
standard I/O streams, and make sure that no
break signal is about to make things any more
complicated than they already are. */
__check_abort_enabled = FALSE;
/* Dump all currently unwritten data, especially to the console. */
__flush_all_files(-1);

View File

@ -1,5 +1,5 @@
/*
* $Id: unistd_fchown.c,v 1.8 2005-03-07 11:16:43 obarthel Exp $
* $Id: unistd_fchown.c,v 1.9 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -80,7 +80,7 @@ fchown(int file_descriptor, uid_t owner, gid_t group)
goto out;
}
if(fd->fd_DefaultFile == ZERO)
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
__set_errno(EBADF);
goto out;

View File

@ -1,5 +1,5 @@
/*
* $Id: unistd_ftruncate.c,v 1.9 2005-03-16 09:28:37 obarthel Exp $
* $Id: unistd_ftruncate.c,v 1.10 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -80,7 +80,7 @@ ftruncate(int file_descriptor, off_t length)
goto out;
}
if(fd->fd_DefaultFile == ZERO)
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
__set_errno(EBADF);
goto out;

View File

@ -1,5 +1,5 @@
/*
* $Id: unistd_sync_fd.c,v 1.4 2005-03-07 11:58:50 obarthel Exp $
* $Id: unistd_sync_fd.c,v 1.5 2005-04-01 18:46:37 obarthel Exp $
*
* :ts=4
*
@ -62,7 +62,7 @@ __sync_fd(struct fd * fd,int mode)
goto out;
}
if(fd->fd_DefaultFile == ZERO)
if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO))
{
__set_errno(EBADF);
goto out;