diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index c548d38c4d..9dfdccdd04 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -29,11 +29,10 @@ * INTERFACE ROUTINES * * setup/teardown: - * StreamServerPort - Open postmaster's server port - * StreamConnection - Create new connection with client - * StreamClose - Close a client/backend connection + * ListenServerPort - Open postmaster's server port + * AcceptConnection - Accept new connection with client * TouchSocketFiles - Protect socket files against /tmp cleaners - * pq_init - initialize libpq at backend startup + * pq_init - initialize libpq at backend startup * socket_comm_reset - reset libpq during error recovery * socket_close - shutdown libpq at backend exit * @@ -168,13 +167,18 @@ WaitEventSet *FeBeWaitSet; * pq_init - initialize libpq at backend startup * -------------------------------- */ -void -pq_init(void) +Port * +pq_init(ClientSocket *client_sock) { - Port *port = MyProcPort; + Port *port; int socket_pos PG_USED_FOR_ASSERTS_ONLY; int latch_pos PG_USED_FOR_ASSERTS_ONLY; + /* allocate the Port struct and copy the ClientSocket contents to it */ + port = palloc0(sizeof(Port)); + port->sock = client_sock->sock; + port->raddr = client_sock->raddr; + /* fill in the server (local) address */ port->laddr.salen = sizeof(port->laddr.addr); if (getsockname(port->sock, @@ -310,6 +314,8 @@ pq_init(void) */ Assert(socket_pos == FeBeWaitSetSocketPos); Assert(latch_pos == FeBeWaitSetLatchPos); + + return port; } /* -------------------------------- @@ -384,16 +390,13 @@ socket_close(int code, Datum arg) -/* - * Streams -- wrapper around Unix socket system calls - * - * - * Stream functions are used for vanilla TCP connection protocol. +/* -------------------------------- + * Postmaster functions to handle sockets. + * -------------------------------- */ - /* - * StreamServerPort -- open a "listening" port to accept connections. + * ListenServerPort -- open a "listening" port to accept connections. * * family should be AF_UNIX or AF_UNSPEC; portNumber is the port number. * For AF_UNIX ports, hostName should be NULL and unixSocketDir must be @@ -408,7 +411,7 @@ socket_close(int code, Datum arg) * RETURNS: STATUS_OK or STATUS_ERROR */ int -StreamServerPort(int family, const char *hostName, unsigned short portNumber, +ListenServerPort(int family, const char *hostName, unsigned short portNumber, const char *unixSocketDir, pgsocket ListenSockets[], int *NumListenSockets, int MaxListen) { @@ -774,8 +777,9 @@ Setup_AF_UNIX(const char *sock_path) /* - * StreamConnection -- create a new connection with client using - * server port. Set port->sock to the FD of the new connection. + * AcceptConnection -- accept a new connection with client using + * server port. Fills *client_sock with the FD and endpoint info + * of the new connection. * * ASSUME: that this doesn't need to be non-blocking because * the Postmaster waits for the socket to be ready to accept(). @@ -783,13 +787,13 @@ Setup_AF_UNIX(const char *sock_path) * RETURNS: STATUS_OK or STATUS_ERROR */ int -StreamConnection(pgsocket server_fd, Port *port) +AcceptConnection(pgsocket server_fd, ClientSocket *client_sock) { /* accept connection and fill in the client (remote) address */ - port->raddr.salen = sizeof(port->raddr.addr); - if ((port->sock = accept(server_fd, - (struct sockaddr *) &port->raddr.addr, - &port->raddr.salen)) == PGINVALID_SOCKET) + client_sock->raddr.salen = sizeof(client_sock->raddr.addr); + if ((client_sock->sock = accept(server_fd, + (struct sockaddr *) &client_sock->raddr.addr, + &client_sock->raddr.salen)) == PGINVALID_SOCKET) { ereport(LOG, (errcode_for_socket_access(), @@ -809,23 +813,6 @@ StreamConnection(pgsocket server_fd, Port *port) return STATUS_OK; } -/* - * StreamClose -- close a client/backend connection - * - * NOTE: this is NOT used to terminate a session; it is just used to release - * the file descriptor in a process that should no longer have the socket - * open. (For example, the postmaster calls this after passing ownership - * of the connection to a child process.) It is expected that someone else - * still has the socket open. So, we only want to close the descriptor, - * we do NOT want to send anything to the far end. - */ -void -StreamClose(pgsocket sock) -{ - if (closesocket(sock) != 0) - elog(LOG, "could not close client or listen socket: %m"); -} - /* * TouchSocketFiles -- mark socket files as recently accessed * diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 860d50e2ad..49fc6f979e 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -399,8 +399,6 @@ static void CloseServerPorts(int status, Datum arg); static void unlink_external_pid_file(int status, Datum arg); static void getInstallationPaths(const char *argv0); static void checkControlFile(void); -static Port *ConnCreate(int serverFd); -static void ConnFree(Port *port); static void handle_pm_pmsignal_signal(SIGNAL_ARGS); static void handle_pm_child_exit_signal(SIGNAL_ARGS); static void handle_pm_reload_request_signal(SIGNAL_ARGS); @@ -430,15 +428,15 @@ typedef enum CAC_state CAC_TOOMANY, } CAC_state; -static void BackendInitialize(Port *port, CAC_state cac); -static void BackendRun(Port *port) pg_attribute_noreturn(); +static void BackendInitialize(ClientSocket *client_sock, CAC_state cac); +static void BackendRun(void) pg_attribute_noreturn(); static void ExitPostmaster(int status) pg_attribute_noreturn(); static int ServerLoop(void); -static int BackendStartup(Port *port); +static int BackendStartup(ClientSocket *client_sock); static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done); static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options); static void processCancelRequest(Port *port, void *pkt); -static void report_fork_failure_to_client(Port *port, int errnum); +static void report_fork_failure_to_client(ClientSocket *client_sock, int errnum); static CAC_state canAcceptConnections(int backend_type); static bool RandomCancelKey(int32 *cancel_key); static void signal_child(pid_t pid, int signal); @@ -489,8 +487,8 @@ typedef struct } win32_deadchild_waitinfo; #endif /* WIN32 */ -static pid_t backend_forkexec(Port *port, CAC_state cac); -static pid_t internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker); +static pid_t backend_forkexec(ClientSocket *client_sock, CAC_state cac); +static pid_t internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker); /* Type for a socket that can be inherited to a client process */ #ifdef WIN32 @@ -509,9 +507,9 @@ typedef int InheritableSocket; */ typedef struct { - bool has_port; - Port port; - InheritableSocket portsocket; + bool has_client_sock; + ClientSocket client_sock; + InheritableSocket inh_sock; bool has_bgworker; BackgroundWorker bgworker; @@ -560,13 +558,13 @@ typedef struct char pkglib_path[MAXPGPATH]; } BackendParameters; -static void read_backend_variables(char *id, Port **port, BackgroundWorker **worker); -static void restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorker **worker); +static void read_backend_variables(char *id, ClientSocket **client_sock, BackgroundWorker **worker); +static void restore_backend_variables(BackendParameters *param, ClientSocket **client_sock, BackgroundWorker **worker); #ifndef WIN32 -static bool save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker); +static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker); #else -static bool save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker, +static bool save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker, HANDLE childProcess, pid_t childPid); #endif @@ -1222,14 +1220,14 @@ PostmasterMain(int argc, char *argv[]) char *curhost = (char *) lfirst(l); if (strcmp(curhost, "*") == 0) - status = StreamServerPort(AF_UNSPEC, NULL, + status = ListenServerPort(AF_UNSPEC, NULL, (unsigned short) PostPortNumber, NULL, ListenSockets, &NumListenSockets, MAXLISTEN); else - status = StreamServerPort(AF_UNSPEC, curhost, + status = ListenServerPort(AF_UNSPEC, curhost, (unsigned short) PostPortNumber, NULL, ListenSockets, @@ -1323,7 +1321,7 @@ PostmasterMain(int argc, char *argv[]) { char *socketdir = (char *) lfirst(l); - status = StreamServerPort(AF_UNIX, NULL, + status = ListenServerPort(AF_UNIX, NULL, (unsigned short) PostPortNumber, socketdir, ListenSockets, @@ -1503,7 +1501,10 @@ CloseServerPorts(int status, Datum arg) * condition if a new postmaster wants to re-use the TCP port number. */ for (i = 0; i < NumListenSockets; i++) - StreamClose(ListenSockets[i]); + { + if (closesocket(ListenSockets[i]) != 0) + elog(LOG, "could not close listen socket: %m"); + } NumListenSockets = 0; /* @@ -1773,19 +1774,16 @@ ServerLoop(void) if (events[i].events & WL_SOCKET_ACCEPT) { - Port *port; + ClientSocket s; - port = ConnCreate(events[i].fd); - if (port) + if (AcceptConnection(events[i].fd, &s) == STATUS_OK) + BackendStartup(&s); + + /* We no longer need the open socket in this process */ + if (s.sock != PGINVALID_SOCKET) { - BackendStartup(port); - - /* - * We no longer need the open socket or port structure in - * this process - */ - StreamClose(port->sock); - ConnFree(port); + if (closesocket(s.sock) != 0) + elog(LOG, "could not close client socket: %m"); } } } @@ -2157,11 +2155,7 @@ retry1: /* * Now fetch parameters out of startup packet and save them into the Port - * structure. All data structures attached to the Port struct must be - * allocated in TopMemoryContext so that they will remain available in a - * running backend (even after PostmasterContext is destroyed). We need - * not worry about leaking this storage on failure, since we aren't in the - * postmaster process anymore. + * structure. */ oldcontext = MemoryContextSwitchTo(TopMemoryContext); @@ -2297,7 +2291,7 @@ retry1: port->database_name[0] = '\0'; /* - * Done putting stuff in TopMemoryContext. + * Done filling the Port structure */ MemoryContextSwitchTo(oldcontext); @@ -2454,50 +2448,6 @@ canAcceptConnections(int backend_type) return result; } - -/* - * ConnCreate -- create a local connection data structure - * - * Returns NULL on failure, other than out-of-memory which is fatal. - */ -static Port * -ConnCreate(int serverFd) -{ - Port *port; - - if (!(port = (Port *) calloc(1, sizeof(Port)))) - { - ereport(LOG, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - ExitPostmaster(1); - } - - if (StreamConnection(serverFd, port) != STATUS_OK) - { - if (port->sock != PGINVALID_SOCKET) - StreamClose(port->sock); - ConnFree(port); - return NULL; - } - - return port; -} - - -/* - * ConnFree -- free a local connection data structure - * - * Caller has already closed the socket if any, so there's not much - * to do here. - */ -static void -ConnFree(Port *port) -{ - free(port); -} - - /* * ClosePostmasterPorts -- close all the postmaster's open sockets * @@ -2545,7 +2495,10 @@ ClosePostmasterPorts(bool am_syslogger) if (ListenSockets) { for (int i = 0; i < NumListenSockets; i++) - StreamClose(ListenSockets[i]); + { + if (closesocket(ListenSockets[i]) != 0) + elog(LOG, "could not close listen socket: %m"); + } pfree(ListenSockets); } NumListenSockets = 0; @@ -4095,7 +4048,7 @@ TerminateChildren(int signal) * Note: if you change this code, also consider StartAutovacuumWorker. */ static int -BackendStartup(Port *port) +BackendStartup(ClientSocket *client_sock) { Backend *bn; /* for backend cleanup */ pid_t pid; @@ -4146,7 +4099,7 @@ BackendStartup(Port *port) bn->bgworker_notify = false; #ifdef EXEC_BACKEND - pid = backend_forkexec(port, cac); + pid = backend_forkexec(client_sock, cac); #else /* !EXEC_BACKEND */ pid = fork_process(); if (pid == 0) /* child */ @@ -4158,10 +4111,10 @@ BackendStartup(Port *port) ClosePostmasterPorts(false); /* Perform additional initialization and collect startup packet */ - BackendInitialize(port, cac); + BackendInitialize(client_sock, cac); /* And run the backend */ - BackendRun(port); + BackendRun(); } #endif /* EXEC_BACKEND */ @@ -4176,14 +4129,14 @@ BackendStartup(Port *port) errno = save_errno; ereport(LOG, (errmsg("could not fork new process for connection: %m"))); - report_fork_failure_to_client(port, save_errno); + report_fork_failure_to_client(client_sock, save_errno); return STATUS_ERROR; } /* in parent, successful fork */ ereport(DEBUG2, (errmsg_internal("forked new backend, pid=%d socket=%d", - (int) pid, (int) port->sock))); + (int) pid, (int) client_sock->sock))); /* * Everything's been successful, it's safe to add this backend to our list @@ -4210,7 +4163,7 @@ BackendStartup(Port *port) * it's not up and running. */ static void -report_fork_failure_to_client(Port *port, int errnum) +report_fork_failure_to_client(ClientSocket *client_sock, int errnum) { char buffer[1000]; int rc; @@ -4221,13 +4174,13 @@ report_fork_failure_to_client(Port *port, int errnum) strerror(errnum)); /* Set port to non-blocking. Don't do send() if this fails */ - if (!pg_set_noblock(port->sock)) + if (!pg_set_noblock(client_sock->sock)) return; /* We'll retry after EINTR, but ignore all other failures */ do { - rc = send(port->sock, buffer, strlen(buffer) + 1, 0); + rc = send(client_sock->sock, buffer, strlen(buffer) + 1, 0); } while (rc < 0 && errno == EINTR); } @@ -4245,18 +4198,17 @@ report_fork_failure_to_client(Port *port, int errnum) * but have not yet set up most of our local pointers to shmem structures. */ static void -BackendInitialize(Port *port, CAC_state cac) +BackendInitialize(ClientSocket *client_sock, CAC_state cac) { int status; int ret; + Port *port; char remote_host[NI_MAXHOST]; char remote_port[NI_MAXSERV]; StringInfoData ps_data; + MemoryContext oldcontext; - /* Save port etc. for ps status */ - MyProcPort = port; - - /* Tell fd.c about the long-lived FD associated with the port */ + /* Tell fd.c about the long-lived FD associated with the client_sock */ ReserveExternalFD(); /* @@ -4272,17 +4224,25 @@ BackendInitialize(Port *port, CAC_state cac) /* This flag will remain set until InitPostgres finishes authentication */ ClientAuthInProgress = true; /* limit visibility of log messages */ - /* set these to empty in case they are needed before we set them up */ - port->remote_host = ""; - port->remote_port = ""; - /* * Initialize libpq and enable reporting of ereport errors to the client. * Must do this now because authentication uses libpq to send messages. + * + * The Port structure and all data structures attached to it are allocated + * in TopMemoryContext, so that they survive into PostgresMain execution. + * We need not worry about leaking this storage on failure, since we + * aren't in the postmaster process anymore. */ - pq_init(); /* initialize libpq to talk to client */ + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + port = MyProcPort = pq_init(client_sock); + MemoryContextSwitchTo(oldcontext); + whereToSendOutput = DestRemote; /* now safe to ereport to client */ + /* set these to empty in case they are needed before we set them up */ + port->remote_host = ""; + port->remote_port = ""; + /* * We arrange to do _exit(1) if we receive SIGTERM or timeout while trying * to collect the startup packet; while SIGQUIT results in _exit(2). @@ -4315,8 +4275,9 @@ BackendInitialize(Port *port, CAC_state cac) * Save remote_host and remote_port in port structure (after this, they * will appear in log_line_prefix data for log messages). */ - port->remote_host = strdup(remote_host); - port->remote_port = strdup(remote_port); + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + port->remote_host = pstrdup(remote_host); + port->remote_port = pstrdup(remote_port); /* And now we can issue the Log_connections message, if wanted */ if (Log_connections) @@ -4347,7 +4308,10 @@ BackendInitialize(Port *port, CAC_state cac) ret == 0 && strspn(remote_host, "0123456789.") < strlen(remote_host) && strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host)) - port->remote_hostname = strdup(remote_host); + { + port->remote_hostname = pstrdup(remote_host); + } + MemoryContextSwitchTo(oldcontext); /* * Ready to begin client interaction. We will give up and _exit(1) after @@ -4471,7 +4435,7 @@ BackendInitialize(Port *port, CAC_state cac) * Doesn't return at all. */ static void -BackendRun(Port *port) +BackendRun(void) { /* * Create a per-backend PGPROC struct in shared memory. We must do this @@ -4485,7 +4449,7 @@ BackendRun(Port *port) */ MemoryContextSwitchTo(TopMemoryContext); - PostgresMain(port->database_name, port->user_name); + PostgresMain(MyProcPort->database_name, MyProcPort->user_name); } @@ -4519,7 +4483,7 @@ postmaster_forkexec(int argc, char *argv[]) * returns the pid of the fork/exec'd process, or -1 on failure */ static pid_t -backend_forkexec(Port *port, CAC_state cac) +backend_forkexec(ClientSocket *client_sock, CAC_state cac) { char *av[5]; int ac = 0; @@ -4535,7 +4499,7 @@ backend_forkexec(Port *port, CAC_state cac) av[ac] = NULL; Assert(ac < lengthof(av)); - return internal_forkexec(ac, av, port, NULL); + return internal_forkexec(ac, av, client_sock, NULL); } #ifndef WIN32 @@ -4547,7 +4511,7 @@ backend_forkexec(Port *port, CAC_state cac) * - fork():s, and then exec():s the child process */ static pid_t -internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker) +internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker) { static unsigned long tmpBackendFileNum = 0; pid_t pid; @@ -4563,7 +4527,7 @@ internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker) */ memset(¶m, 0, sizeof(BackendParameters)); - if (!save_backend_variables(¶m, port, worker)) + if (!save_backend_variables(¶m, client_sock, worker)) return -1; /* log made by save_backend_variables */ /* Calculate name for temp file */ @@ -4647,7 +4611,7 @@ internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker) * file is complete. */ static pid_t -internal_forkexec(int argc, char *argv[], Port *port, BackgroundWorker *worker) +internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundWorker *worker) { int retry_count = 0; STARTUPINFO si; @@ -4744,7 +4708,7 @@ retry: return -1; } - if (!save_backend_variables(param, port, worker, pi.hProcess, pi.dwProcessId)) + if (!save_backend_variables(param, client_sock, worker, pi.hProcess, pi.dwProcessId)) { /* * log made by save_backend_variables, but we have to clean up the @@ -4861,7 +4825,7 @@ retry: void SubPostmasterMain(int argc, char *argv[]) { - Port *port; + ClientSocket *client_sock; BackgroundWorker *worker; /* In EXEC_BACKEND case we will not have inherited these settings */ @@ -4876,7 +4840,7 @@ SubPostmasterMain(int argc, char *argv[]) elog(FATAL, "invalid subpostmaster invocation"); /* Read in the variables file */ - read_backend_variables(argv[2], &port, &worker); + read_backend_variables(argv[2], &client_sock, &worker); /* Close the postmaster's sockets (as soon as we know them) */ ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0); @@ -4975,13 +4939,14 @@ SubPostmasterMain(int argc, char *argv[]) * PGPROC slots, we have already initialized libpq and are able to * report the error to the client. */ - BackendInitialize(port, cac); + BackendInitialize(client_sock, cac); /* Restore basic shared memory pointers */ InitShmemAccess(UsedShmemSegAddr); /* And run the backend */ - BackendRun(port); /* does not return */ + BackendRun(); /* does not return */ + } if (strcmp(argv[1], "--forkaux") == 0) { @@ -6101,24 +6066,24 @@ static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src); /* Save critical backend variables into the BackendParameters struct */ #ifndef WIN32 static bool -save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker) +save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker) #else static bool -save_backend_variables(BackendParameters *param, Port *port, BackgroundWorker *worker, +save_backend_variables(BackendParameters *param, ClientSocket *client_sock, BackgroundWorker *worker, HANDLE childProcess, pid_t childPid) #endif { - if (port) + if (client_sock) { - memcpy(¶m->port, port, sizeof(Port)); - if (!write_inheritable_socket(¶m->portsocket, port->sock, childPid)) + memcpy(¶m->client_sock, client_sock, sizeof(ClientSocket)); + if (!write_inheritable_socket(¶m->inh_sock, client_sock->sock, childPid)) return false; - param->has_port = true; + param->has_client_sock = true; } else { - memset(¶m->port, 0, sizeof(Port)); - param->has_port = false; + memset(¶m->client_sock, 0, sizeof(ClientSocket)); + param->has_client_sock = false; } if (worker) @@ -6285,7 +6250,7 @@ read_inheritable_socket(SOCKET *dest, InheritableSocket *src) #endif static void -read_backend_variables(char *id, Port **port, BackgroundWorker **worker) +read_backend_variables(char *id, ClientSocket **client_sock, BackgroundWorker **worker) { BackendParameters param; @@ -6349,21 +6314,21 @@ read_backend_variables(char *id, Port **port, BackgroundWorker **worker) } #endif - restore_backend_variables(¶m, port, worker); + restore_backend_variables(¶m, client_sock, worker); } /* Restore critical backend variables from the BackendParameters struct */ static void -restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorker **worker) +restore_backend_variables(BackendParameters *param, ClientSocket **client_sock, BackgroundWorker **worker) { - if (param->has_port) + if (param->has_client_sock) { - *port = (Port *) MemoryContextAlloc(TopMemoryContext, sizeof(Port)); - memcpy(*port, ¶m->port, sizeof(Port)); - read_inheritable_socket(&(*port)->sock, ¶m->portsocket); + *client_sock = (ClientSocket *) MemoryContextAlloc(TopMemoryContext, sizeof(ClientSocket)); + memcpy(*client_sock, ¶m->client_sock, sizeof(ClientSocket)); + read_inheritable_socket(&(*client_sock)->sock, ¶m->inh_sock); } else - *port = NULL; + *client_sock = NULL; if (param->has_bgworker) { @@ -6429,7 +6394,7 @@ restore_backend_variables(BackendParameters *param, Port **port, BackgroundWorke /* * We need to restore fd.c's counts of externally-opened FDs; to avoid * confusion, be sure to do this after restoring max_safe_fds. (Note: - * BackendInitialize will handle this for port->sock.) + * BackendInitialize will handle this for (*client_sock)->sock.) */ #ifndef WIN32 if (postmaster_alive_fds[0] >= 0) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index aec1b19442..6b7903314a 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -4233,10 +4233,7 @@ PostgresMain(const char *dbname, const char *username) /* * If the PostmasterContext is still around, recycle the space; we don't - * need it anymore after InitPostgres completes. Note this does not trash - * *MyProcPort, because ConnCreate() allocated that space with malloc() - * ... else we'd need to copy the Port data first. Also, subsidiary data - * such as the username isn't lost either; see ProcessStartupPacket(). + * need it anymore after InitPostgres completes. */ if (PostmasterContext) { diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index 59c2a1d874..4dce767751 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -110,12 +110,9 @@ typedef struct ClientConnectionInfo } ClientConnectionInfo; /* - * This is used by the postmaster in its communication with frontends. It - * contains all state information needed during this communication before the - * backend is run. The Port structure is kept in malloc'd memory and is - * still available when a backend is running (see MyProcPort). The data - * it points to must also be malloc'd, or else palloc'd in TopMemoryContext, - * so that it survives into PostgresMain execution! + * The Port structure holds state information about a client connection in a + * backend process. It is available in the global variable MyProcPort. The + * struct and all the data it points are kept in TopMemoryContext. * * remote_hostname is set if we did a successful reverse lookup of the * client's IP address during connection setup. @@ -217,6 +214,17 @@ typedef struct Port #endif } Port; +/* + * ClientSocket holds a socket for an accepted connection, along with the + * information about the remote endpoint. This is passed from postmaster to + * the backend process. + */ +typedef struct ClientSocket +{ + pgsocket sock; /* File descriptor */ + SockAddr raddr; /* remote addr (client) */ +} ClientSocket; + #ifdef USE_SSL /* * Hardcoded DH parameters, used in ephemeral DH keying. (See also diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 6171a0d17a..be054b59dd 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -64,14 +64,13 @@ extern PGDLLIMPORT WaitEventSet *FeBeWaitSet; #define FeBeWaitSetLatchPos 1 #define FeBeWaitSetNEvents 3 -extern int StreamServerPort(int family, const char *hostName, +extern int ListenServerPort(int family, const char *hostName, unsigned short portNumber, const char *unixSocketDir, pgsocket ListenSocket[], int *NumListenSockets, int MaxListen); -extern int StreamConnection(pgsocket server_fd, Port *port); -extern void StreamClose(pgsocket sock); +extern int AcceptConnection(pgsocket server_fd, ClientSocket *client_sock); extern void TouchSocketFiles(void); extern void RemoveSocketFiles(void); -extern void pq_init(void); +extern Port *pq_init(ClientSocket *client_sock); extern int pq_getbytes(char *s, size_t len); extern void pq_startmsgread(void); extern void pq_endmsgread(void); diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index d3a7f75b08..a3052a181d 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -388,6 +388,7 @@ ClientCertMode ClientCertName ClientConnectionInfo ClientData +ClientSocket ClonePtrType ClosePortalStmt ClosePtrType