summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--configure.ac16
-rw-r--r--doc/rsyslog_conf_modules.html63
-rw-r--r--gss-misc.c25
-rw-r--r--plugins/imgssapi/imgssapi.c16
-rw-r--r--plugins/imudp/imudp.c7
-rw-r--r--plugins/imuxsock/imuxsock.c20
-rw-r--r--runtime/Makefile.am1
-rw-r--r--runtime/glbl.c12
-rw-r--r--runtime/glbl.h13
-rw-r--r--runtime/net.c3
-rw-r--r--runtime/net.h4
-rw-r--r--runtime/nsdsel_ptcp.c51
-rw-r--r--runtime/nsdsel_ptcp.h5
-rw-r--r--runtime/unlimited_select.h45
-rw-r--r--tools/syslogd.c7
16 files changed, 234 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index fe495779..8e4d1f0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+- added option to use unlimited-size select() calls
+ Thanks to varmjofekoj for the patch
---------------------------------------------------------------------------
Version 5.5.0 [DEVEL] (rgerhards), 2009-11-??
- moved DNS resolution code out of imudp and into the backend processing
diff --git a/configure.ac b/configure.ac
index 2ce99b94..4061b620 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,6 +346,21 @@ AC_ARG_ENABLE([fsstnd],
])
+# support for unlimited select() syscall
+AC_ARG_ENABLE(unlimited_select,
+ [AS_HELP_STRING([--enable-unlimited-select],[Enable unlimited select() syscall @<:@default=no@:>@])],
+ [case "${enableval}" in
+ yes) enable_unlimited_select="yes" ;;
+ no) enable_unlimited_select="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-unlimited-select) ;;
+ esac],
+ [enable_unlimited_select="no"]
+)
+if test "$enable_unlimited_select" = "yes"; then
+ AC_DEFINE(USE_UNLIMITED_SELECT, 1, [If defined, the select() syscall won't be limited to a particular number of file descriptors.])
+fi
+
+
# debug
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug],[Enable debug mode @<:@default=no@:>@])],
@@ -940,6 +955,7 @@ echo " rsyslog runtime will be built: $enable_rsyslogrt"
echo " rsyslogd will be built: $enable_rsyslogd"
echo " GUI components will be built: $enable_gui"
echo " custom module 1 will be built: $enable_cust1"
+echo " Unlimited select() support enabled: $enable_unlimited_select"
echo
echo "---{ input plugins }---"
echo " Klog functionality enabled: $enable_klog ($os_type)"
diff --git a/doc/rsyslog_conf_modules.html b/doc/rsyslog_conf_modules.html
index a4c8c423..99f37747 100644
--- a/doc/rsyslog_conf_modules.html
+++ b/doc/rsyslog_conf_modules.html
@@ -2,11 +2,42 @@
<html><head><title>Modules - rsyslog.conf</title></head>
<body>
<p>This is a part of the rsyslog.conf documentation.</p>
-<a href="rsyslog_conf.html">back</a>
-<h2>Modules</h2>
-<p>Rsyslog has a modular design. Consequently, there is a growing
+<a href="rsyslog_conf.html">Back to rsyslog.conf manual</a>
+<h1>Modules</h1>
+<p>Rsyslog has a modular design. This enables functionality to be
+dynamically loaded from modules, which may also be written by any
+third party. Rsyslog itself offers all non-core functionality as
+modules. Consequently, there is a growing
number of modules. Here is the entry point to their documentation and
what they do (list is currently not complete)</p>
+<p>Please note that each module provides configuration
+directives, which are NOT necessarily being listed below. Also
+remember, that a modules configuration directive (and functionality) is
+only available if it has been loaded (using $ModLoad).</p>
+<p>It is relatively easy to write a rsyslog module. <b>If none of the provided
+modules solve your need, you may consider writing one or have one written
+for you by
+<a href="http://www.rsyslog.com/professional-services">Adiscon's professional services for rsyslog</a>
+</b>(this often is a very cost-effective and efficient way of getting what you need).
+
+<h2>Input Modules</h2>
+<p>Input modules are used to gather messages from various sources. They interface
+to message generators.
+<ul>
+<li><a href="imfile.html">imfile</a> -&nbsp; input module for text files</li>
+<li><a href="imrelp.html">imrelp</a> - RELP input module</li>
+<li>imudp - udp syslog message input</li>
+<li><a href="imtcp.html">imtcp</a> - input plugin for plain tcp syslog</li>
+<li><a href="imgssapi.html">imgssapi</a> - input plugin for plain tcp and GSS-enabled syslog</li>
+<li>immark - support for mark messages</li>
+<li><a href="imklog.html">imklog</a> - kernel logging</li>
+<li><a href="imuxsock.html">imuxsock</a> - unix sockets, including the system log socket</li>
+<li><a href="im3195.html">im3195</a> - accepts syslog messages via RFC 3195</li>
+</ul>
+
+<h2>Output Modules</h2>
+<p>Output modules process messages. With them, message formats can be transformed
+and messages be transmitted to various different targets.
<ul>
<li><a href="omsnmp.html">omsnmp</a> - SNMP trap output module</li>
<li><a href="omstdout.html">omtdout</a> - stdout output module (mainly a test tool)</li>
@@ -22,26 +53,14 @@ SQLLite, Ingres, Oracle, mSQL)</li>
permits rsyslog to alert folks by mail if something important happens</li>
<li><a href="omoracle.html">omoracle</a> - output module for Oracle (native OCI interface)</li>
<li><a href="omudpspoof.html">omudpspoof</a> - output module sending UDP syslog messages with a spoofed address</li>
-<li><a href="imfile.html">imfile</a>
--&nbsp; input module for text files</li>
-<li><a href="imrelp.html">imrelp</a> - RELP
-input module</li>
-<li><a href="imudp.html">imudp</a> - udp syslog message input</li>
-<li><a href="imtcp.html">imtcp</a> - input
-plugin for plain tcp syslog</li>
-<li><a href="imgssapi.html">imgssapi</a> -
-input plugin for plain tcp and GSS-enabled syslog</li>
-<li>immark - support for mark messages</li>
-<li><a href="imklog.html">imklog</a> - kernel logging</li>
-<li><a href="imuxsock.html">imuxsock</a> -
-unix sockets, including the system log socket</li>
-<li><a href="im3195.html">im3195</a> -
-accepts syslog messages via RFC 3195</li>
</ul>
-<p>Please note that each module provides configuration
-directives, which are NOT necessarily being listed below. Also
-remember, that a modules configuration directive (and functionality) is
-only available if it has been loaded (using $ModLoad).</p>
+
+<h2>Library Modules</h2>
+<p>Library modules provide dynamically loadable functionality for parts of rsyslog,
+most often for other loadable modules. They can not be user-configured and are loaded
+automatically by some components. They are just mentioned so that error messages that
+point to library moduls can be understood. No module list is provided.
+
<p>[<a href="manual.html">manual index</a>]
[<a href="rsyslog_conf.html">rsyslog.conf</a>]
[<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
diff --git a/gss-misc.c b/gss-misc.c
index d67c344d..a5e161de 100644
--- a/gss-misc.c
+++ b/gss-misc.c
@@ -52,11 +52,14 @@
#include "errmsg.h"
#include "gss-misc.h"
#include "debug.h"
+#include "glbl.h"
+#include "unlimited_select.h"
MODULE_TYPE_LIB
/* static data */
DEFobjStaticHelpers
+DEFobjCurrIf(glbl)
DEFobjCurrIf(errmsg)
static void display_status_(char *m, OM_uint32 code, int type)
@@ -109,28 +112,38 @@ static int read_all(int fd, char *buf, unsigned int nbyte)
{
int ret;
char *ptr;
- fd_set rfds;
struct timeval tv;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pRfds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set rfds;
+ fd_set *pRfds = &rfds;
+#endif
for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
+ FD_ZERO(pRfds);
+ FD_SET(fd, pRfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
- if ((ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) <= 0
- || !FD_ISSET(fd, &rfds))
+ if ((ret = select(FD_SETSIZE, pRfds, NULL, NULL, &tv)) <= 0
+ || !FD_ISSET(fd, pRfds)) {
+ freeFdSet(pRfds);
return ret;
+ }
ret = recv(fd, ptr, nbyte, 0);
if (ret < 0) {
if (errno == EINTR)
continue;
+ freeFdSet(pRfds);
return (ret);
} else if (ret == 0) {
+ freeFdSet(pRfds);
return (ptr - buf);
}
}
+ freeFdSet(pRfds);
return (ptr - buf);
}
@@ -265,6 +278,7 @@ BEGINObjClassExit(gssutil, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END M
CODESTARTObjClassExit(gssutil)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
ENDObjClassExit(gssutil)
@@ -275,6 +289,7 @@ ENDObjClassExit(gssutil)
BEGINAbstractObjClassInit(gssutil, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
ENDObjClassInit(gssutil)
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index 14830ce2..fb3c3536 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -57,6 +57,7 @@
#include "netstrm.h"
#include "glbl.h"
#include "debug.h"
+#include "unlimited_select.h"
MODULE_TYPE_INPUT
@@ -415,15 +416,20 @@ OnSessAcceptGSS(tcpsrv_t *pThis, tcps_sess_t *pSess)
CHKiRet(netstrm.GetSock(pSess->pStrm, &fdSess)); // TODO: method access!
if (allowedMethods & ALLOWEDMETHOD_TCP) {
int len;
- fd_set fds;
struct timeval tv;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pFds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set fds;
+ fd_set *pFds = &fds;
+#endif
do {
- FD_ZERO(&fds);
- FD_SET(fdSess, &fds);
+ FD_ZERO(pFds);
+ FD_SET(fdSess, pFds);
tv.tv_sec = 1;
tv.tv_usec = 0;
- ret = select(fdSess + 1, &fds, NULL, NULL, &tv);
+ ret = select(fdSess + 1, pFds, NULL, NULL, &tv);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
errmsg.LogError(0, RS_RET_ERR, "TCP session %p will be closed, error ignored\n", pSess);
@@ -476,6 +482,8 @@ OnSessAcceptGSS(tcpsrv_t *pThis, tcps_sess_t *pSess)
pGSess->allowedMethods = ALLOWEDMETHOD_TCP;
ABORT_FINALIZE(RS_RET_OK); // TODO: define good error codes
}
+
+ freeFdSet(pFds);
}
context = &pGSess->gss_context;
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 1c798ac3..07a07d74 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -377,7 +377,6 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
int maxfds;
int nfds;
int i;
- fd_set readfds;
struct sockaddr_storage frominetPrev;
int bIsPermitted;
uchar fromHost[NI_MAXHOST];
@@ -399,21 +398,21 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
* is given without -a, we do not need to listen at all..
*/
maxfds = 0;
- FD_ZERO (&readfds);
+ FD_ZERO (pReadfds);
/* Add the UDP listen sockets to the list of read descriptors. */
for (i = 0; i < *udpLstnSocks; i++) {
if (udpLstnSocks[i+1] != -1) {
if(Debug)
net.debugListenInfo(udpLstnSocks[i+1], "UDP");
- FD_SET(udpLstnSocks[i+1], &readfds);
+ FD_SET(udpLstnSocks[i+1], pReadfds);
if(udpLstnSocks[i+1]>maxfds) maxfds=udpLstnSocks[i+1];
}
}
if(Debug) {
dbgprintf("--------imUDP calling select, active file descriptors (max %d): ", maxfds);
for (nfds = 0; nfds <= maxfds; ++nfds)
- if ( FD_ISSET(nfds, &readfds) )
+ if ( FD_ISSET(nfds, pReadfds) )
dbgprintf("%d ", nfds);
dbgprintf("\n");
}
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index cf6df56c..06f9caad 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -46,6 +46,7 @@
#include "msg.h"
#include "prop.h"
#include "debug.h"
+#include "unlimited_select.h"
MODULE_TYPE_INPUT
@@ -294,7 +295,13 @@ BEGINrunInput
int nfds;
int i;
int fd;
- fd_set readfds;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set readfds;
+ fd_set *pReadfds = &readfds;
+#endif
+
CODESTARTrunInput
/* this is an endless loop - it is terminated when the thread is
* signalled to do so. This, however, is handled by the framework,
@@ -308,11 +315,11 @@ CODESTARTrunInput
* is given without -a, we do not need to listen at all..
*/
maxfds = 0;
- FD_ZERO (&readfds);
+ FD_ZERO (pReadfds);
/* Copy master connections */
for (i = startIndexUxLocalSockets; i < nfunix; i++) {
if (funix[i] != -1) {
- FD_SET(funix[i], &readfds);
+ FD_SET(funix[i], pReadfds);
if (funix[i]>maxfds) maxfds=funix[i];
}
}
@@ -320,20 +327,20 @@ CODESTARTrunInput
if(Debug) {
dbgprintf("--------imuxsock calling select, active file descriptors (max %d): ", maxfds);
for (nfds= 0; nfds <= maxfds; ++nfds)
- if ( FD_ISSET(nfds, &readfds) )
+ if ( FD_ISSET(nfds, pReadfds) )
dbgprintf("%d ", nfds);
dbgprintf("\n");
}
/* wait for io to become ready */
- nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL);
+ nfds = select(maxfds+1, (fd_set *) pReadfds, NULL, NULL, NULL);
if(glbl.GetGlobalInputTermState() == 1)
break; /* terminate input! */
for (i = 0; i < nfunix && nfds > 0; i++) {
if(glbl.GetGlobalInputTermState() == 1)
ABORT_FINALIZE(RS_RET_FORCE_TERM); /* terminate input! */
- if ((fd = funix[i]) != -1 && FD_ISSET(fd, &readfds)) {
+ if ((fd = funix[i]) != -1 && FD_ISSET(fd, pReadfds)) {
readSocket(fd, i);
--nfds; /* indicate we have processed one */
}
@@ -341,6 +348,7 @@ CODESTARTrunInput
}
finalize_it:
+ freeFdSet(pReadfds);
RETiRet;
ENDrunInput
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index caf7c5ca..7896e71d 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -16,6 +16,7 @@ librsyslog_la_SOURCES = \
nsd.h \
glbl.h \
glbl.c \
+ unlimited_select.h \
conf.c \
conf.h \
parser.h \
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 71c2ed0d..ac08791f 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -74,6 +74,9 @@ static uchar *pszDfltNetstrmDrvrCAF = NULL; /* default CA file for the netstrm d
static uchar *pszDfltNetstrmDrvrKeyFile = NULL; /* default key file for the netstrm driver (server) */
static uchar *pszDfltNetstrmDrvrCertFile = NULL; /* default cert file for the netstrm driver (server) */
static int bTerminateInputs = 0; /* global switch that inputs shall terminate ASAP (1=> terminate) */
+#ifdef USE_UNLIMITED_SELECT
+static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* size of select() bitmask in bytes */
+#endif
/* define a macro for the simple properties' set and get functions
@@ -106,6 +109,9 @@ SIMP_PROP(DisableDNS, bDisableDNS, int)
SIMP_PROP(LocalDomain, LocalDomain, uchar*)
SIMP_PROP(StripDomains, StripDomains, char**)
SIMP_PROP(LocalHosts, LocalHosts, char**)
+#ifdef USE_UNLIMITED_SELECT
+SIMP_PROP(FdSetSize, iFdSetSize, int)
+#endif
SIMP_PROP_SET(LocalFQDNName, LocalFQDNName, uchar*)
SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*)
@@ -284,6 +290,9 @@ CODESTARTobjQueryInterface(glbl)
SIMP_PROP(DfltNetstrmDrvrCAF)
SIMP_PROP(DfltNetstrmDrvrKeyFile)
SIMP_PROP(DfltNetstrmDrvrCertFile)
+#ifdef USE_UNLIMITED_SELECT
+ SIMP_PROP(FdSetSize)
+#endif
#undef SIMP_PROP
finalize_it:
ENDobjQueryInterface(glbl)
@@ -317,6 +326,9 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
bDropMalPTRMsgs = 0;
bOptimizeUniProc = 1;
bPreserveFQDN = 0;
+#ifdef USE_UNLIMITED_SELECT
+ iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask);
+#endif
return RS_RET_OK;
}
diff --git a/runtime/glbl.h b/runtime/glbl.h
index 7506f16b..4b4bdf83 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -66,9 +66,20 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
void (*SetGlobalInputTermination)(void);
/* added v5, 2009-11-03 */
SIMP_PROP(ParseHOSTNAMEandTAG, int)
+ /* note: v4, v5 are already used by more recent versions, so we need to skip them! */
+ /* added v6, 2009-11-16 as part of varmojfekoj's "unlimited select()" patch
+ * Note that it must be always present, otherwise the interface would have different
+ * versions depending on compile settings, what is not acceptable.
+ * Use this property with care, it is only truly available if UNLIMITED_SELECT is enabled
+ * (I did not yet further investigate the details, because that code hopefully can be removed
+ * at some later stage).
+ */
+ SIMP_PROP(FdSetSize, int)
+ /* v7: was neeeded to mean v5+v6 - do NOT add anything else for that version! */
+ /* next change is v8! */
#undef SIMP_PROP
ENDinterface(glbl)
-#define glblCURR_IF_VERSION 5 /* increment whenever you change the interface structure! */
+#define glblCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */
/* version 2 had PreserveFQDN added - rgerhards, 2008-12-08 */
/* the remaining prototypes */
diff --git a/runtime/net.c b/runtime/net.c
index 51db606a..ab431f7c 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1611,6 +1611,9 @@ CODESTARTobjQueryInterface(net)
pIf->PermittedPeerWildcardMatch = PermittedPeerWildcardMatch;
pIf->CmpHost = CmpHost;
pIf->HasRestrictions = HasRestrictions;
+ /* data members */
+ pIf->pACLAddHostnameOnFail = &ACLAddHostnameOnFail;
+ pIf->pACLDontResolve = &ACLDontResolve;
finalize_it:
ENDobjQueryInterface(net)
diff --git a/runtime/net.h b/runtime/net.h
index 9e6fb9da..2add3557 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -152,8 +152,8 @@ BEGINinterface(net) /* name must also be changed in ENDinterface macro! */
rsRetVal (*HasRestrictions)(uchar *, int *bHasRestrictions);
int (*isAllowedSender2)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS);
/* data members - these should go away over time... TODO */
- int pACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */
- int pACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */
+ int *pACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */
+ int *pACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */
ENDinterface(net)
#define netCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */
diff --git a/runtime/nsdsel_ptcp.c b/runtime/nsdsel_ptcp.c
index 41b85e0c..e2cfca7c 100644
--- a/runtime/nsdsel_ptcp.c
+++ b/runtime/nsdsel_ptcp.c
@@ -36,6 +36,7 @@
#include "errmsg.h"
#include "nsd_ptcp.h"
#include "nsdsel_ptcp.h"
+#include "unlimited_select.h"
/* static data */
DEFobjStaticHelpers
@@ -47,14 +48,23 @@ DEFobjCurrIf(glbl)
*/
BEGINobjConstruct(nsdsel_ptcp) /* be sure to specify the object type also in END macro! */
pThis->maxfds = 0;
+#ifdef USE_UNLIMITED_SELECT
+ pThis->pReadfds = calloc(1, glbl.GetFdSetSize());
+ pThis->pWritefds = calloc(1, glbl.GetFdSetSize());
+#else
FD_ZERO(&pThis->readfds);
FD_ZERO(&pThis->writefds);
+#endif
ENDobjConstruct(nsdsel_ptcp)
/* destructor for the nsdsel_ptcp object */
BEGINobjDestruct(nsdsel_ptcp) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(nsdsel_ptcp)
+#ifdef USE_UNLIMITED_SELECT
+ freeFdSet(pThis->pReadfds);
+ freeFdSet(pThis->pWritefds);
+#endif
ENDobjDestruct(nsdsel_ptcp)
@@ -65,20 +75,27 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
DEFiRet;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pSock, nsd_ptcp);
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
switch(waitOp) {
case NSDSEL_RD:
- FD_SET(pSock->sock, &pThis->readfds);
+ FD_SET(pSock->sock, pReadfds);
break;
case NSDSEL_WR:
- FD_SET(pSock->sock, &pThis->writefds);
+ FD_SET(pSock->sock, pWritefds);
break;
case NSDSEL_RDWR:
- FD_SET(pSock->sock, &pThis->readfds);
- FD_SET(pSock->sock, &pThis->writefds);
+ FD_SET(pSock->sock, pReadfds);
+ FD_SET(pSock->sock, pWritefds);
break;
}
@@ -98,6 +115,13 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
DEFiRet;
int i;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
assert(piNumReady != NULL);
@@ -106,13 +130,13 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
// TODO: name in dbgprintf!
dbgprintf("--------<NSDSEL_PTCP> calling select, active fds (max %d): ", pThis->maxfds);
for(i = 0; i <= pThis->maxfds; ++i)
- if(FD_ISSET(i, &pThis->readfds) || FD_ISSET(i, &pThis->writefds))
+ if(FD_ISSET(i, pReadfds) || FD_ISSET(i, pWritefds))
dbgprintf("%d ", i);
dbgprintf("\n");
}
/* now do the select */
- *piNumReady = select(pThis->maxfds+1, &pThis->readfds, &pThis->writefds, NULL, NULL);
+ *piNumReady = select(pThis->maxfds+1, pReadfds, pWritefds, NULL, NULL);
RETiRet;
}
@@ -125,6 +149,13 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
DEFiRet;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
ISOBJ_TYPE_assert(pSock, nsd_ptcp);
@@ -132,14 +163,14 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
switch(waitOp) {
case NSDSEL_RD:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds);
+ *pbIsReady = FD_ISSET(pSock->sock, pReadfds);
break;
case NSDSEL_WR:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->writefds);
+ *pbIsReady = FD_ISSET(pSock->sock, pWritefds);
break;
case NSDSEL_RDWR:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds)
- | FD_ISSET(pSock->sock, &pThis->writefds);
+ *pbIsReady = FD_ISSET(pSock->sock, pReadfds)
+ | FD_ISSET(pSock->sock, pWritefds);
break;
}
diff --git a/runtime/nsdsel_ptcp.h b/runtime/nsdsel_ptcp.h
index 6c0c7fa7..f9ec8210 100644
--- a/runtime/nsdsel_ptcp.h
+++ b/runtime/nsdsel_ptcp.h
@@ -31,8 +31,13 @@ typedef nsdsel_if_t nsdsel_ptcp_if_t; /* we just *implement* this interface */
struct nsdsel_ptcp_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
int maxfds;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds;
+ fd_set *pWritefds;
+#else
fd_set readfds;
fd_set writefds;
+#endif
};
/* interface is defined in nsd.h, we just implement it! */
diff --git a/runtime/unlimited_select.h b/runtime/unlimited_select.h
new file mode 100644
index 00000000..32dadc03
--- /dev/null
+++ b/runtime/unlimited_select.h
@@ -0,0 +1,45 @@
+/* unlimited_select.h
+ * Tweak the macros for accessing fd_set so that the select() syscall
+ * won't be limited to a particular number of file descriptors.
+ *
+ * Copyright 2009 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+
+#ifndef UNLIMITED_SELECT_H_INCLUDED
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include "glbl.h"
+
+#ifdef USE_UNLIMITED_SELECT
+# undef FD_ZERO
+# define FD_ZERO(set) memset((set), 0, glbl.GetFdSetSize());
+#endif
+
+#ifdef USE_UNLIMITED_SELECT
+void freeFdSet(fd_set *p) {
+ free(p);
+}
+#else
+# define freeFdSet(x)
+#endif
+
+#endif /* #ifndef UNLIMITED_SELECT_H_INCLUDED */
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 3fc3da0d..d510bc41 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1158,6 +1158,9 @@ static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles)
iFiles, errStr, (long) maxFiles.rlim_max);
ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE);
}
+#ifdef USE_UNLIMITED_SELECT
+ glbl.SetFdSetSize(howmany(iFiles, __NFDBITS) * sizeof (fd_mask));
+#endif
DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max);
finalize_it:
@@ -2721,10 +2724,10 @@ int realMain(int argc, char **argv)
fprintf(stderr, "error -p is no longer supported, use module imuxsock instead");
}
case 'q': /* add hostname if DNS resolving has failed */
- net.pACLAddHostnameOnFail = 1;
+ *(net.pACLAddHostnameOnFail) = 1;
break;
case 'Q': /* dont resolve hostnames in ACL to IPs */
- net.pACLDontResolve = 1;
+ *(net.pACLDontResolve) = 1;
break;
case 'r': /* accept remote messages */
if(iCompatibilityMode < 3) {