First step to close all unnecessary open file descriptors before

starting a start script as reaction to a call.  The same applies to the
restart of isdnlog using SIGHUP.  Till now each restart increases the
number of used fds.
For now the modifications are inactive by default.  They can be enabled
by adding the line "DEFS += -DFD_AT_EXEC_MODE=1" to ../Makefile.in.
The next isdnlog (4.68) will have this enabled per default.
The upper limit for fd numbers is taken from NR_OPEN in <linux/limits.h>.
If there is a smarter way to access this limit, please let me know.
Another approach would be to set the close-on-exec flag on each fd
directly after it is opened.  This would require more extensive changes.
I'd like to thank Jan Bernhardt for discovering this problem.
This commit is contained in:
tobiasb 2004-01-26 15:20:07 +00:00
parent 2e4644ae32
commit 7aa7b660c2
3 changed files with 78 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/* $Id: isdnlog.c,v 1.70 2004/01/04 02:22:53 tobiasb Exp $
/* $Id: isdnlog.c,v 1.71 2004/01/26 15:20:08 tobiasb Exp $
*
* ISDN accounting for isdn4linux. (log-module)
*
@ -19,6 +19,20 @@
* along with this program; if not, write to the Free Software
*
* $Log: isdnlog.c,v $
* Revision 1.71 2004/01/26 15:20:08 tobiasb
* First step to close all unnecessary open file descriptors before
* starting a start script as reaction to a call. The same applies to the
* restart of isdnlog using SIGHUP. Till now each restart increases the
* number of used fds.
* For now the modifications are inactive by default. They can be enabled
* by adding the line "DEFS += -DFD_AT_EXEC_MODE=1" to ../Makefile.in.
* The next isdnlog (4.68) will have this enabled per default.
* The upper limit for fd numbers is taken from NR_OPEN in <linux/limits.h>.
* If there is a smarter way to access this limit, please let me know.
* Another approach would be to set the close-on-exec flag on each fd
* directly after it is opened. This would require more extensive changes.
* I'd like to thank Jan Bernhardt for discovering this problem.
*
* Revision 1.70 2004/01/04 02:22:53 tobiasb
* Show supported database(s) at startup.
*
@ -568,6 +582,7 @@ static void hup_handler(int isig)
{
print_msg(PRT_INFO, "restarting %s\n", myname);
Exit(-9);
Close_Fds(3); /* avoid duplicate fds after restart */
execv(myname, hup_argv);
print_msg(PRT_ERR,"Cannot restart %s: %s!\n", myname, strerror(errno));
} /* hup_handler */

View File

@ -1,4 +1,4 @@
/* $Id: isdnlog.h,v 1.26 2003/08/26 19:46:12 tobiasb Exp $
/* $Id: isdnlog.h,v 1.27 2004/01/26 15:20:08 tobiasb Exp $
*
* ISDN accounting for isdn4linux.
*
@ -20,6 +20,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdnlog.h,v $
* Revision 1.27 2004/01/26 15:20:08 tobiasb
* First step to close all unnecessary open file descriptors before
* starting a start script as reaction to a call. The same applies to the
* restart of isdnlog using SIGHUP. Till now each restart increases the
* number of used fds.
* For now the modifications are inactive by default. They can be enabled
* by adding the line "DEFS += -DFD_AT_EXEC_MODE=1" to ../Makefile.in.
* The next isdnlog (4.68) will have this enabled per default.
* The upper limit for fd numbers is taken from NR_OPEN in <linux/limits.h>.
* If there is a smarter way to access this limit, please let me know.
* Another approach would be to set the close-on-exec flag on each fd
* directly after it is opened. This would require more extensive changes.
* I'd like to thank Jan Bernhardt for discovering this problem.
*
* Revision 1.26 2003/08/26 19:46:12 tobiasb
* isdnlog-4.66:
* - Added support for AVM B1 (with layer 2 d-channel trace) in point-to-
@ -400,6 +414,14 @@
/****************************************************************************/
#ifndef FD_AT_EXEC_MODE
#define FD_AT_EXEC_MODE 0
#endif
#define FD_AT_EXEC_CLOSE (FD_AT_EXEC_MODE & 1)
#define FD_AT_EXEC_FLAG (FD_AT_EXEC_MODE & 2) /* not implemented yet */
/****************************************************************************/
typedef struct {
int current;
int shift;
@ -575,6 +597,12 @@ _EXTERN struct timeval *Get_Interval(int Sec);
_EXTERN int Change_Channel_Ring( int old_channel, int new_channel);
_EXTERN int Start_Interval(void);
#if FD_AT_EXEC_CLOSE
_EXTERN void Close_Fds( const int first );
#else
#define Close_Fds(a) ;
#endif
#undef _EXTERN
/****************************************************************************/

View File

@ -1,4 +1,4 @@
/* $Id: start_prog.c,v 1.16 2000/04/13 15:44:20 paul Exp $
/* $Id: start_prog.c,v 1.17 2004/01/26 15:20:07 tobiasb Exp $
*
* ISDN accounting for isdn4linux.
*
@ -20,6 +20,20 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: start_prog.c,v $
* Revision 1.17 2004/01/26 15:20:07 tobiasb
* First step to close all unnecessary open file descriptors before
* starting a start script as reaction to a call. The same applies to the
* restart of isdnlog using SIGHUP. Till now each restart increases the
* number of used fds.
* For now the modifications are inactive by default. They can be enabled
* by adding the line "DEFS += -DFD_AT_EXEC_MODE=1" to ../Makefile.in.
* The next isdnlog (4.68) will have this enabled per default.
* The upper limit for fd numbers is taken from NR_OPEN in <linux/limits.h>.
* If there is a smarter way to access this limit, please let me know.
* Another approach would be to set the close-on-exec flag on each fd
* directly after it is opened. This would require more extensive changes.
* I'd like to thank Jan Bernhardt for discovering this problem.
*
* Revision 1.16 2000/04/13 15:44:20 paul
* Fix for $5, $7, $8, $9, $10, always having same value as $11
*
@ -89,6 +103,7 @@
#define _START_PROG_C_
#include <linux/limits.h> /* for NR_OPEN, must precede isdnlog.h */
#include "isdnlog.h"
#include <pwd.h>
#include <grp.h>
@ -256,6 +271,8 @@ int Ring(info_args *Cmd, char *Opts[], int Die, int Async)
dup2(filedes[1],STDOUT_FILENO);
dup2(filedes[1],STDERR_FILENO);
Close_Fds(3); /* do not leave isdnlog's fds to script */
/* execvp(Pathfind(Args[0],NULL,NULL), Args);*/
execvp(Args[0], Args);
print_msg(PRT_ERR, "Can't start \"%s\" with execvp(): %s\n", Args[0],strerror(errno));
@ -1163,3 +1180,18 @@ int Change_Channel_Ring( int old_channel, int new_channel)
/****************************************************************************/
#if FD_AT_EXEC_CLOSE
void Close_Fds( const int first )
{
int i,r;
for (i = first; i < NR_OPEN; i++) {
r = close(i);
if (r == -1 && errno != EBADF)
print_msg(PRT_WARN, "close of fd %i prior to exec failed: %s",
i, strerror(errno));
}
}
#endif
/****************************************************************************/