From 99e9ebfc15595b44ac213fce16c36b4dea1e672c Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Thu, 20 Oct 2005 07:19:16 +0000 Subject: [PATCH] - Moved the code which rebinds the standard I/O streams to the server socket into a separate function which can be overridden by user code. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15051 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 3 +- library/GNUmakefile.os4 | 3 +- library/changes | 3 + library/smakefile | 3 +- library/socket_headers.h | 3 +- library/socket_init_exit.c | 105 +------------------ library/socket_obtain_daemon.c | 179 +++++++++++++++++++++++++++++++++ 7 files changed, 193 insertions(+), 106 deletions(-) create mode 100644 library/socket_obtain_daemon.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 7476998..93fc2ef 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.72 2005-10-20 06:50:32 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.73 2005-10-20 07:19:15 obarthel Exp $ # # :ts=8 # @@ -755,6 +755,7 @@ NET_LIB = \ socket_ioctl.o \ socket_isdaemon.o \ socket_listen.o \ + socket_obtain_daemon.o \ socket_recv.o \ socket_recvfrom.o \ socket_recvmsg.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 73d237b..0a2b14c 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.81 2005-10-20 06:50:32 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.82 2005-10-20 07:19:15 obarthel Exp $ # # :ts=8 # @@ -726,6 +726,7 @@ NET_LIB = \ socket_ioctl.o \ socket_isdaemon.o \ socket_listen.o \ + socket_obtain_daemon.o \ socket_recv.o \ socket_recvfrom.o \ socket_recvmsg.o \ diff --git a/library/changes b/library/changes index a15b5fe..da5eab1 100644 --- a/library/changes +++ b/library/changes @@ -32,6 +32,9 @@ by declaring a global variable called "__check_daemon_startup" which is described in . +- Moved the code which rebinds the standard I/O streams to the server + socket into a separate function which can be overridden by user code. + c.lib 1.196 (11.10.2005) diff --git a/library/smakefile b/library/smakefile index 384ba4a..36d010c 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.54 2005-10-20 06:50:32 obarthel Exp $ +# $Id: smakefile,v 1.55 2005-10-20 07:19:15 obarthel Exp $ # # :ts=8 # @@ -343,6 +343,7 @@ SOCKET_OBJ = \ socket_ioctl.o \ socket_isdaemon.o \ socket_listen.o \ + socket_obtain_daemon.o \ socket_recv.o \ socket_recvfrom.o \ socket_recvmsg.o \ diff --git a/library/socket_headers.h b/library/socket_headers.h index b6110ec..154adf4 100644 --- a/library/socket_headers.h +++ b/library/socket_headers.h @@ -1,5 +1,5 @@ /* - * $Id: socket_headers.h,v 1.10 2005-10-17 13:54:25 obarthel Exp $ + * $Id: socket_headers.h,v 1.11 2005-10-20 07:19:15 obarthel Exp $ * * :ts=4 * @@ -96,6 +96,7 @@ extern struct fd * __get_file_descriptor_socket(int socket_descriptor); extern int __socket_hook_entry(struct fd * fd,struct file_action_message * fam); extern int __get_h_errno(void); extern void __set_h_errno(int new_h_errno); +extern BOOL __obtain_daemon_message(VOID); /****************************************************************************/ diff --git a/library/socket_init_exit.c b/library/socket_init_exit.c index a6175a0..2e91b78 100644 --- a/library/socket_init_exit.c +++ b/library/socket_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: socket_init_exit.c,v 1.22 2005-10-20 06:50:32 obarthel Exp $ + * $Id: socket_init_exit.c,v 1.23 2005-10-20 07:19:15 obarthel Exp $ * * :ts=4 * @@ -317,107 +317,8 @@ SOCKET_CONSTRUCTOR(socket_init) /* Check if this program was launched as a server by the Internet superserver. */ - if(Cli() != NULL && NOT __detach && __check_daemon_startup) - { - struct DaemonMessage * dm; - - /* The socket the superserver may have launched this program - with is attached to the exit data entry of the process. */ - #if defined(__amigaos4__) - { - dm = (struct DaemonMessage *)GetExitData(); - } - #else - { - struct Process * this_process = (struct Process *)FindTask(NULL); - - dm = (struct DaemonMessage *)this_process->pr_ExitData; - } - #endif /* __amigaos4__ */ - - if(TypeOfMem(dm) != 0 && TypeOfMem(((char *)dm) + sizeof(*dm)-1) != 0) - { - struct SignalSemaphore * lock; - int daemon_socket; - struct fd * fd; - int sockfd; - int i; - - SHOWMSG("we have a daemon message; this is a server"); - - /* Try to grab that socket and attach is to the three - standard I/O streams. */ - - PROFILE_OFF(); - daemon_socket = __ObtainSocket(dm->dm_ID,dm->dm_Family,dm->dm_Type,0); - PROFILE_ON(); - - if(daemon_socket == -1) - { - __show_error("Network server streams could not be initialized."); - goto out; - } - - SHOWVALUE(daemon_socket); - - /* Shut down the three standard I/O streams. */ - for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) - close(i); - - /* The standard I/O streams are no longer attached to a console. */ - __no_standard_io = TRUE; - - /* Put the socket into the three standard I/O streams. */ - for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) - { - #if defined(__THREAD_SAFE) - { - lock = __create_semaphore(); - if(lock == NULL) - goto out; - } - #else - { - lock = NULL; - } - #endif /* __THREAD_SAFE */ - - fd = __fd[i]; - - assert( fd != NULL && FLAG_IS_CLEAR(fd->fd_Flags,FDF_IN_USE) ); - - if(i == STDIN_FILENO) - { - sockfd = daemon_socket; - } - else - { - PROFILE_OFF(); - sockfd = __Dup2Socket(daemon_socket,-1); - PROFILE_ON(); - - if(sockfd == -1) - { - SHOWMSG("could not duplicate daemon socket"); - - #if defined(__THREAD_SAFE) - { - __delete_semaphore(lock); - } - #endif /* __THREAD_SAFE */ - - __show_error("Network server streams could not be initialized."); - goto out; - } - } - - __initialize_fd(fd,__socket_hook_entry,(BPTR)sockfd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE,lock); - } - - /* This program now runs as an internet superserver client (daemon). */ - __is_daemon = TRUE; - } - } + if(CANNOT __obtain_daemon_message()) + goto out; success = TRUE; diff --git a/library/socket_obtain_daemon.c b/library/socket_obtain_daemon.c new file mode 100644 index 0000000..69d51a5 --- /dev/null +++ b/library/socket_obtain_daemon.c @@ -0,0 +1,179 @@ +/* + * $Id: socket_obtain_daemon.c,v 1.1 2005-10-20 07:19:16 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * 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. + */ + +#if defined(SOCKET_SUPPORT) + +/****************************************************************************/ + +#ifndef _SOCKET_HEADERS_H +#include "socket_headers.h" +#endif /* _SOCKET_HEADERS_H */ + +/****************************************************************************/ + +struct DaemonMessage +{ + struct Message dm_Message; + ULONG dm_Pad1; + ULONG dm_Pad2; + LONG dm_ID; + ULONG dm_Pad3; + UBYTE dm_Family; + UBYTE dm_Type; +}; + +/****************************************************************************/ + +/* Check if this program was launched as a server by the Internet + superserver. If this is so, obtain the 'daemon message' associated + with this server process and map the standard I/O streams to the + server socket. This function must return FALSE if it fails to + allocate the necessary resources for rebinding the standard I/O + streams. */ +BOOL +__obtain_daemon_message(VOID) +{ + BOOL success = FALSE; + + if(Cli() != NULL && NOT __detach && __check_daemon_startup) + { + struct DaemonMessage * dm; + + /* The socket the superserver may have launched this program + with is attached to the exit data entry of the process. */ + #if defined(__amigaos4__) + { + dm = (struct DaemonMessage *)GetExitData(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + dm = (struct DaemonMessage *)this_process->pr_ExitData; + } + #endif /* __amigaos4__ */ + + if(TypeOfMem(dm) != 0 && TypeOfMem(((char *)dm) + sizeof(*dm)-1) != 0) + { + struct SignalSemaphore * lock; + int daemon_socket; + struct fd * fd; + int sockfd; + int i; + + SHOWMSG("we have a daemon message; this is a server"); + + /* Try to grab that socket and attach is to the three + standard I/O streams. */ + + PROFILE_OFF(); + daemon_socket = __ObtainSocket(dm->dm_ID,dm->dm_Family,dm->dm_Type,0); + PROFILE_ON(); + + if(daemon_socket == -1) + { + __show_error("Network server streams could not be initialized."); + goto out; + } + + SHOWVALUE(daemon_socket); + + /* Shut down the three standard I/O streams. */ + for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) + close(i); + + /* The standard I/O streams are no longer attached to a console. */ + __no_standard_io = TRUE; + + /* Put the socket into the three standard I/O streams. */ + for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) + { + #if defined(__THREAD_SAFE) + { + lock = __create_semaphore(); + if(lock == NULL) + goto out; + } + #else + { + lock = NULL; + } + #endif /* __THREAD_SAFE */ + + fd = __fd[i]; + + assert( fd != NULL && FLAG_IS_CLEAR(fd->fd_Flags,FDF_IN_USE) ); + + if(i == STDIN_FILENO) + { + sockfd = daemon_socket; + } + else + { + PROFILE_OFF(); + sockfd = __Dup2Socket(daemon_socket,-1); + PROFILE_ON(); + + if(sockfd == -1) + { + SHOWMSG("could not duplicate daemon socket"); + + #if defined(__THREAD_SAFE) + { + __delete_semaphore(lock); + } + #endif /* __THREAD_SAFE */ + + __show_error("Network server streams could not be initialized."); + goto out; + } + } + + __initialize_fd(fd,__socket_hook_entry,(BPTR)sockfd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE,lock); + } + + /* This program now runs as an internet superserver client (daemon). */ + __is_daemon = TRUE; + } + } + + success = TRUE; + + out: + + return(success); +} + +/****************************************************************************/ + +#endif /* SOCKET_SUPPORT */