* specified. For TCP ports, hostName is either NULL for all interfaces or
* the interface to listen on, and unixSocketDir is ignored (can be NULL).
*
- * Successfully opened sockets are added to the ListenSocket[] array (of
- * length MaxListen), at the first position that isn't PGINVALID_SOCKET.
+ * Successfully opened sockets are appended to the ListenSockets[] array. On
+ * entry, *NumListenSockets holds the number of elements currently in the
+ * array, and it is updated to reflect the opened sockets. MaxListen is the
+ * allocated size of the array.
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
-
int
StreamServerPort(int family, const char *hostName, unsigned short portNumber,
const char *unixSocketDir,
- pgsocket ListenSocket[], int MaxListen)
+ pgsocket ListenSockets[], int *NumListenSockets, int MaxListen)
{
pgsocket fd;
int err;
struct addrinfo *addrs = NULL,
*addr;
struct addrinfo hint;
- int listen_index = 0;
int added = 0;
char unixSocketPath[MAXPGPATH];
#if !defined(WIN32) || defined(IPV6_V6ONLY)
}
/* See if there is still room to add 1 more socket. */
- for (; listen_index < MaxListen; listen_index++)
- {
- if (ListenSocket[listen_index] == PGINVALID_SOCKET)
- break;
- }
- if (listen_index >= MaxListen)
+ if (*NumListenSockets == MaxListen)
{
ereport(LOG,
(errmsg("could not bind to all requested addresses: MAXLISTEN (%d) exceeded",
(errmsg("listening on %s address \"%s\", port %d",
familyDesc, addrDesc, (int) portNumber)));
- ListenSocket[listen_index] = fd;
+ ListenSockets[*NumListenSockets] = fd;
+ (*NumListenSockets)++;
added++;
}
/* The socket(s) we're listening to. */
#define MAXLISTEN 64
-static pgsocket ListenSocket[MAXLISTEN];
+static int NumListenSockets = 0;
+static pgsocket *ListenSockets = NULL;
/* still more option variables */
bool EnableSSL = false;
int status;
char *userDoption = NULL;
bool listen_addr_saved = false;
- int i;
char *output_config_variable = NULL;
InitProcessGlobals();
errmsg("could not remove file \"%s\": %m",
LOG_METAINFO_DATAFILE)));
- /*
- * Initialize input sockets.
- *
- * Mark them all closed, and set up an on_proc_exit function that's
- * charged with closing the sockets again at postmaster shutdown.
- */
- for (i = 0; i < MAXLISTEN; i++)
- ListenSocket[i] = PGINVALID_SOCKET;
-
- on_proc_exit(CloseServerPorts, 0);
-
/*
* If enabled, start up syslogger collection subprocess
*/
/*
* Establish input sockets.
+ *
+ * First set up an on_proc_exit function that's charged with closing the
+ * sockets again at postmaster shutdown.
*/
+ ListenSockets = palloc(MAXLISTEN * sizeof(pgsocket));
+ on_proc_exit(CloseServerPorts, 0);
+
if (ListenAddresses)
{
char *rawstring;
status = StreamServerPort(AF_UNSPEC, NULL,
(unsigned short) PostPortNumber,
NULL,
- ListenSocket, MAXLISTEN);
+ ListenSockets,
+ &NumListenSockets,
+ MAXLISTEN);
else
status = StreamServerPort(AF_UNSPEC, curhost,
(unsigned short) PostPortNumber,
NULL,
- ListenSocket, MAXLISTEN);
+ ListenSockets,
+ &NumListenSockets,
+ MAXLISTEN);
if (status == STATUS_OK)
{
#ifdef USE_BONJOUR
/* Register for Bonjour only if we opened TCP socket(s) */
- if (enable_bonjour && ListenSocket[0] != PGINVALID_SOCKET)
+ if (enable_bonjour && NumListenSockets > 0)
{
DNSServiceErrorType err;
status = StreamServerPort(AF_UNIX, NULL,
(unsigned short) PostPortNumber,
socketdir,
- ListenSocket, MAXLISTEN);
+ ListenSockets,
+ &NumListenSockets,
+ MAXLISTEN);
if (status == STATUS_OK)
{
/*
* check that we have some socket to listen on
*/
- if (ListenSocket[0] == PGINVALID_SOCKET)
+ if (NumListenSockets == 0)
ereport(FATAL,
(errmsg("no socket created for listening")));
* before we remove the postmaster.pid lockfile; otherwise there's a race
* condition if a new postmaster wants to re-use the TCP port number.
*/
- for (i = 0; i < MAXLISTEN; i++)
- {
- if (ListenSocket[i] != PGINVALID_SOCKET)
- {
- StreamClose(ListenSocket[i]);
- ListenSocket[i] = PGINVALID_SOCKET;
- }
- }
+ for (i = 0; i < NumListenSockets; i++)
+ StreamClose(ListenSockets[i]);
+ NumListenSockets = 0;
/*
* Next, remove any filesystem entries for Unix sockets. To avoid race
static void
ConfigurePostmasterWaitSet(bool accept_connections)
{
- int nsockets;
-
if (pm_wait_set)
FreeWaitEventSet(pm_wait_set);
pm_wait_set = NULL;
- /* How many server sockets do we need to wait for? */
- nsockets = 0;
- if (accept_connections)
- {
- while (nsockets < MAXLISTEN &&
- ListenSocket[nsockets] != PGINVALID_SOCKET)
- ++nsockets;
- }
-
- pm_wait_set = CreateWaitEventSet(CurrentMemoryContext, 1 + nsockets);
+ pm_wait_set = CreateWaitEventSet(CurrentMemoryContext,
+ accept_connections ? (1 + NumListenSockets) : 1);
AddWaitEventToSet(pm_wait_set, WL_LATCH_SET, PGINVALID_SOCKET, MyLatch,
NULL);
if (accept_connections)
{
- for (int i = 0; i < nsockets; i++)
- AddWaitEventToSet(pm_wait_set, WL_SOCKET_ACCEPT, ListenSocket[i],
+ for (int i = 0; i < NumListenSockets; i++)
+ AddWaitEventToSet(pm_wait_set, WL_SOCKET_ACCEPT, ListenSockets[i],
NULL, NULL);
}
}
* EXEC_BACKEND mode.
*/
#ifndef EXEC_BACKEND
- for (int i = 0; i < MAXLISTEN; i++)
- {
- if (ListenSocket[i] != PGINVALID_SOCKET)
- {
- StreamClose(ListenSocket[i]);
- ListenSocket[i] = PGINVALID_SOCKET;
- }
- }
+ for (int i = 0; i < NumListenSockets; i++)
+ StreamClose(ListenSockets[i]);
+ NumListenSockets = 0;
+ pfree(ListenSockets);
+ ListenSockets = NULL;
#endif
/*