mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Back out V6 code, caused postmaster startup failure.
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pqcomm.c,v 1.142 2002/12/06 03:46:28 momjian Exp $
|
||||
* $Id: pqcomm.c,v 1.143 2002/12/06 04:37:02 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -85,11 +85,6 @@ extern ssize_t secure_read(Port *, void *, size_t);
|
||||
extern ssize_t secure_write(Port *, const void *, size_t);
|
||||
|
||||
static void pq_close(void);
|
||||
#ifdef HAVE_UNIX_SOCKETS
|
||||
int StreamServerPortSubAFUNIX1(unsigned short portNumber,
|
||||
char *unixSocketName );
|
||||
int StreamServerPortSubAFUNIX2(void);
|
||||
#endif /* HAVE_UNIX_SOCKETS */
|
||||
|
||||
|
||||
/*
|
||||
@@ -187,198 +182,170 @@ int
|
||||
StreamServerPort(int family, char *hostName, unsigned short portNumber,
|
||||
char *unixSocketName, int *fdP)
|
||||
{
|
||||
int fd,
|
||||
err;
|
||||
int maxconn;
|
||||
int one = 1;
|
||||
SockAddr saddr;
|
||||
int fd,
|
||||
err;
|
||||
int maxconn;
|
||||
size_t len = 0;
|
||||
int one = 1;
|
||||
|
||||
int ret;
|
||||
struct addrinfo* addrs = NULL;
|
||||
struct addrinfo hint;
|
||||
char portNumberStr[64];
|
||||
char* service = portNumberStr;
|
||||
char* hostn = (hostName[0] == '\0')? NULL : hostName;
|
||||
Assert(family == AF_INET || family == AF_UNIX);
|
||||
|
||||
Assert(family == AF_INET6 || family == AF_INET || family == AF_UNIX);
|
||||
if ((fd = socket(family, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
elog(LOG, "StreamServerPort: socket() failed: %m");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
hint.ai_family = family;
|
||||
hint.ai_flags = AI_PASSIVE;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
if (family == AF_INET)
|
||||
{
|
||||
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
|
||||
sizeof(one))) == -1)
|
||||
{
|
||||
elog(LOG, "StreamServerPort: setsockopt(SO_REUSEADDR) failed: %m");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(portNumberStr, sizeof(portNumberStr)/sizeof(char),
|
||||
"%d", portNumber);
|
||||
MemSet((char *) &saddr, 0, sizeof(saddr));
|
||||
saddr.sa.sa_family = family;
|
||||
|
||||
#ifdef HAVE_UNIX_SOCKETS
|
||||
if (family == AF_UNIX) {
|
||||
if(StreamServerPortSubAFUNIX1(portNumber, unixSocketName) != STATUS_OK){
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
service = sock_path;
|
||||
}
|
||||
if (family == AF_UNIX)
|
||||
{
|
||||
UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
|
||||
len = UNIXSOCK_LEN(saddr.un);
|
||||
strcpy(sock_path, saddr.un.sun_path);
|
||||
|
||||
/*
|
||||
* Grab an interlock file associated with the socket file.
|
||||
*/
|
||||
if (!CreateSocketLockFile(sock_path, true))
|
||||
return STATUS_ERROR;
|
||||
|
||||
/*
|
||||
* Once we have the interlock, we can safely delete any
|
||||
* pre-existing socket file to avoid failure at bind() time.
|
||||
*/
|
||||
unlink(sock_path);
|
||||
}
|
||||
#endif /* HAVE_UNIX_SOCKETS */
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
/* TCP/IP socket */
|
||||
if (hostName[0] == '\0')
|
||||
saddr.in.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
else
|
||||
{
|
||||
struct hostent *hp;
|
||||
|
||||
hp = gethostbyname(hostName);
|
||||
if ((hp == NULL) || (hp->h_addrtype != AF_INET))
|
||||
{
|
||||
elog(LOG, "StreamServerPort: gethostbyname(%s) failed",
|
||||
hostName);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
memmove((char *) &(saddr.in.sin_addr), (char *) hp->h_addr,
|
||||
hp->h_length);
|
||||
}
|
||||
|
||||
ret = getaddrinfo2(hostn, service, &hint, &addrs);
|
||||
if(ret || addrs == NULL){
|
||||
elog(LOG, "FATAL: StreamServerPort: getaddrinfo2() failed: %s\n",
|
||||
gai_strerror(ret));
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
saddr.in.sin_port = htons(portNumber);
|
||||
len = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
|
||||
/** YY DEBUG
|
||||
if(addrs->ai_family == AF_UNIX){
|
||||
printf("%s-%s-%s \n", "debug: AF_UNIX!", unixSocketName, hostName);
|
||||
}
|
||||
else {
|
||||
printf("%s", "debug: NOT AF_UNIX!\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
**/
|
||||
|
||||
if( (fd = socket(addrs->ai_family, SOCK_STREAM, 0)) < 0){
|
||||
elog(LOG, "FATAL: StreamServerPort: socket() failed: %s\n",
|
||||
strerror(errno));
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if( isAF_INETx2(family) ){
|
||||
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one,
|
||||
sizeof(one) )) == -1 ){
|
||||
elog(LOG, "FATAL: StreamServerPort: setsockopt(SO_REUSEADDR) failed: %s\n",
|
||||
strerror(errno));
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
err = bind(fd, addrs->ai_addr, addrs->ai_addrlen);
|
||||
if(err < 0){
|
||||
elog(LOG, "FATAL: StreamServerPort: bind() failed: %s\n"
|
||||
"\tIs another postmaster already running on port %d?\n",
|
||||
strerror(errno), (int) portNumber);
|
||||
if (family == AF_UNIX)
|
||||
elog(LOG, "\tIf not, remove socket node (%s) and retry.\n",
|
||||
sock_path);
|
||||
else
|
||||
elog(LOG, "\tIf not, wait a few seconds and retry.\n");
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
err = bind(fd, (struct sockaddr *) & saddr.sa, len);
|
||||
if (err < 0)
|
||||
{
|
||||
if (family == AF_UNIX)
|
||||
elog(LOG, "StreamServerPort: bind() failed: %m\n"
|
||||
"\tIs another postmaster already running on port %d?\n"
|
||||
"\tIf not, remove socket node (%s) and retry.",
|
||||
(int) portNumber, sock_path);
|
||||
else
|
||||
elog(LOG, "StreamServerPort: bind() failed: %m\n"
|
||||
"\tIs another postmaster already running on port %d?\n"
|
||||
"\tIf not, wait a few seconds and retry.",
|
||||
(int) portNumber);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNIX_SOCKETS
|
||||
if (family == AF_UNIX){
|
||||
if(StreamServerPortSubAFUNIX2() != STATUS_OK){
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (family == AF_UNIX)
|
||||
{
|
||||
/* Arrange to unlink the socket file at exit */
|
||||
on_proc_exit(StreamDoUnlink, 0);
|
||||
|
||||
/*
|
||||
* Select appropriate accept-queue length limit. PG_SOMAXCONN is only
|
||||
* intended to provide a clamp on the request on platforms where an
|
||||
* overly large request provokes a kernel error (are there any?).
|
||||
*/
|
||||
maxconn = MaxBackends * 2;
|
||||
if (maxconn > PG_SOMAXCONN)
|
||||
maxconn = PG_SOMAXCONN;
|
||||
/*
|
||||
* Fix socket ownership/permission if requested. Note we must do
|
||||
* this before we listen() to avoid a window where unwanted
|
||||
* connections could get accepted.
|
||||
*/
|
||||
Assert(Unix_socket_group);
|
||||
if (Unix_socket_group[0] != '\0')
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long int val;
|
||||
gid_t gid;
|
||||
|
||||
err = listen(fd, maxconn);
|
||||
if (err < 0) {
|
||||
elog(LOG, "FATAL: StreamServerPort: listen() failed: %s\n",
|
||||
strerror(errno));
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
val = strtoul(Unix_socket_group, &endptr, 10);
|
||||
if (*endptr == '\0')
|
||||
{
|
||||
/* numeric group id */
|
||||
gid = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* convert group name to id */
|
||||
struct group *gr;
|
||||
|
||||
*fdP = fd;
|
||||
freeaddrinfo2(hint.ai_family, addrs);
|
||||
return STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNIX_SOCKETS
|
||||
int StreamServerPortSubAFUNIX1(unsigned short portNumber,
|
||||
char *unixSocketName )
|
||||
{
|
||||
SockAddr saddr;
|
||||
int len;
|
||||
|
||||
MemSet((char *) &saddr, 0, sizeof(saddr));
|
||||
|
||||
UNIXSOCK_PATH(saddr.un, portNumber, unixSocketName);
|
||||
len = UNIXSOCK_LEN(saddr.un);
|
||||
strcpy(sock_path, saddr.un.sun_path);
|
||||
|
||||
/*
|
||||
* Grab an interlock file associated with the socket file.
|
||||
*/
|
||||
if (!CreateSocketLockFile(sock_path, true))
|
||||
return STATUS_ERROR;
|
||||
|
||||
/*
|
||||
* Once we have the interlock, we can safely delete any
|
||||
* pre-existing socket file to avoid failure at bind() time.
|
||||
*/
|
||||
unlink(sock_path);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
int StreamServerPortSubAFUNIX2(void)
|
||||
{
|
||||
/* Arrange to unlink the socket file at exit */
|
||||
on_proc_exit(StreamDoUnlink, 0);
|
||||
|
||||
/*
|
||||
* Fix socket ownership/permission if requested. Note we must do
|
||||
* this before we listen() to avoid a window where unwanted
|
||||
* connections could get accepted.
|
||||
*/
|
||||
Assert(Unix_socket_group);
|
||||
if (Unix_socket_group[0] != '\0') {
|
||||
char *endptr;
|
||||
unsigned long int val;
|
||||
gid_t gid;
|
||||
|
||||
val = strtoul(Unix_socket_group, &endptr, 10);
|
||||
if (*endptr == '\0'){ /* numeric group id */
|
||||
gid = val;
|
||||
}
|
||||
else { /* convert group name to id */
|
||||
struct group *gr;
|
||||
gr = getgrnam(Unix_socket_group);
|
||||
if (!gr) {
|
||||
elog(LOG, "FATAL: no such group '%s'\n",
|
||||
Unix_socket_group);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
gid = gr->gr_gid;
|
||||
}
|
||||
if (chown(sock_path, -1, gid) == -1){
|
||||
elog(LOG, "FATAL: could not set group of %s: %s\n",
|
||||
sock_path, strerror(errno));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (chmod(sock_path, Unix_socket_permissions) == -1){
|
||||
elog(LOG, "FATAL: could not set permissions on %s: %s\n",
|
||||
sock_path, strerror(errno));
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
return STATUS_OK;
|
||||
}
|
||||
gr = getgrnam(Unix_socket_group);
|
||||
if (!gr)
|
||||
{
|
||||
elog(LOG, "No such group as '%s'",
|
||||
Unix_socket_group);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
gid = gr->gr_gid;
|
||||
}
|
||||
if (chown(sock_path, -1, gid) == -1)
|
||||
{
|
||||
elog(LOG, "Could not set group of %s: %m",
|
||||
sock_path);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (chmod(sock_path, Unix_socket_permissions) == -1)
|
||||
{
|
||||
elog(LOG, "Could not set permissions on %s: %m",
|
||||
sock_path);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_UNIX_SOCKETS */
|
||||
|
||||
/*
|
||||
* Select appropriate accept-queue length limit. PG_SOMAXCONN is only
|
||||
* intended to provide a clamp on the request on platforms where an
|
||||
* overly large request provokes a kernel error (are there any?).
|
||||
*/
|
||||
maxconn = MaxBackends * 2;
|
||||
if (maxconn > PG_SOMAXCONN)
|
||||
maxconn = PG_SOMAXCONN;
|
||||
|
||||
err = listen(fd, maxconn);
|
||||
if (err < 0)
|
||||
{
|
||||
elog(LOG, "StreamServerPort: listen() failed: %m");
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
*fdP = fd;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* StreamConnection -- create a new connection with client using
|
||||
@@ -424,20 +391,8 @@ StreamConnection(int server_fd, Port *port)
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
/* DEBUG YY
|
||||
{
|
||||
char l_hostinfo[INET6_ADDRSTRLEN];
|
||||
char r_hostinfo[INET6_ADDRSTRLEN];
|
||||
SockAddr_ntop(&port->laddr, l_hostinfo, INET6_ADDRSTRLEN, 1);
|
||||
SockAddr_ntop(&port->raddr, r_hostinfo, INET6_ADDRSTRLEN, 1);
|
||||
printf("StreamConnect() l: %s r: %s\n", l_hostinfo, r_hostinfo);
|
||||
printf("StreamConnect() l: %d r: %d\n", port->laddr.sa.sa_family,
|
||||
port->raddr.sa.sa_family);
|
||||
}
|
||||
*/
|
||||
|
||||
/* select NODELAY and KEEPALIVE options if it's a TCP connection */
|
||||
if ( isAF_INETx(&port->laddr) )
|
||||
if (port->laddr.sa.sa_family == AF_INET)
|
||||
{
|
||||
int on = 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user