2929 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
3030 * Portions Copyright (c) 1994, Regents of the University of California
3131 *
32- * $Id: pqcomm.c,v 1.113 2000/11/21 23:03:53 petere Exp $
32+ * $Id: pqcomm.c,v 1.114 2000/11/29 20:59:51 tgl Exp $
3333 *
3434 *-------------------------------------------------------------------------
3535 */
@@ -169,7 +169,7 @@ StreamDoUnlink(void)
169169/*
170170 * StreamServerPort -- open a sock stream "listening" port.
171171 *
172- * This initializes the Postmaster's connection-accepting port fdP.
172+ * This initializes the Postmaster's connection-accepting port * fdP.
173173 *
174174 * RETURNS: STATUS_OK or STATUS_ERROR
175175 */
@@ -183,9 +183,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
183183 err ;
184184 size_t len = 0 ;
185185 int one = 1 ;
186- #ifdef HAVE_FCNTL_SETLK
187- int lock_fd ;
188- #endif
189186
190187 Assert (family == AF_INET || family == AF_UNIX );
191188
@@ -223,22 +220,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
223220 len = UNIXSOCK_LEN (saddr .un );
224221 strcpy (sock_path , saddr .un .sun_path );
225222 /*
226- * If the socket exists but nobody has an advisory lock on it we
227- * can safely delete the file.
223+ * Grab an interlock file associated with the socket file.
228224 */
229- #ifdef HAVE_FCNTL_SETLK
230- if ((lock_fd = open (sock_path , O_WRONLY | O_NONBLOCK | PG_BINARY , 0666 )) >= 0 )
231- {
232- struct flock lck ;
233-
234- lck .l_whence = SEEK_SET ;
235- lck .l_start = lck .l_len = 0 ;
236- lck .l_type = F_WRLCK ;
237- if (fcntl (lock_fd , F_SETLK , & lck ) != -1 )
238- unlink (sock_path );
239- close (lock_fd );
240- }
241- #endif /* HAVE_FCNTL_SETLK */
225+ if (! CreateSocketLockFile (sock_path , true))
226+ return STATUS_ERROR ;
227+ /*
228+ * Once we have the interlock, we can safely delete any pre-existing
229+ * socket file to avoid failure at bind() time.
230+ */
231+ unlink (sock_path );
242232 }
243233#endif /* HAVE_UNIX_SOCKETS */
244234
@@ -274,8 +264,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
274264 {
275265 snprintf (PQerrormsg , PQERRORMSG_LENGTH ,
276266 "FATAL: StreamServerPort: bind() failed: %s\n"
277- "\tIs another postmaster already running on that port?\n" ,
278- strerror (errno ));
267+ "\tIs another postmaster already running on port %d ?\n" ,
268+ strerror (errno ), ( int ) portNumber );
279269 if (family == AF_UNIX )
280270 snprintf (PQerrormsg + strlen (PQerrormsg ),
281271 PQERRORMSG_LENGTH - strlen (PQerrormsg ),
@@ -293,41 +283,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
293283#ifdef HAVE_UNIX_SOCKETS
294284 if (family == AF_UNIX )
295285 {
286+ /* Arrange to unlink the socket file at exit */
296287 on_proc_exit (StreamDoUnlink , 0 );
297288
298289 /*
299- * Open the socket file and get an advisory lock on it. The
300- * lock_fd is left open to keep the lock.
290+ * Fix socket ownership/permission if requested. Note we must
291+ * do this before we listen() to avoid a window where unwanted
292+ * connections could get accepted.
301293 */
302- #ifdef HAVE_FCNTL_SETLK
303- if ((lock_fd = open (sock_path , O_WRONLY | O_NONBLOCK | PG_BINARY , 0666 )) >= 0 )
304- {
305- struct flock lck ;
306-
307- lck .l_whence = SEEK_SET ;
308- lck .l_start = lck .l_len = 0 ;
309- lck .l_type = F_WRLCK ;
310- if (fcntl (lock_fd , F_SETLK , & lck ) != 0 )
311- elog (DEBUG , "flock error on %s: %s" , sock_path , strerror (errno ));
312- }
313- #endif /* HAVE_FCNTL_SETLK */
314- }
315- #endif /* HAVE_UNIX_SOCKETS */
316-
317- listen (fd , SOMAXCONN );
318-
319- /*
320- * MS: I took this code from Dillon's version. It makes the listening
321- * port non-blocking. That is not necessary (and may tickle kernel
322- * bugs).
323- *
324- * fcntl(fd, F_SETFD, 1); fcntl(fd, F_SETFL, FNDELAY);
325- */
326-
327- * fdP = fd ;
328-
329- if (family == AF_UNIX )
330- {
331294 Assert (Unix_socket_group );
332295 if (Unix_socket_group [0 ] != '\0' )
333296 {
@@ -379,6 +342,12 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
379342 return STATUS_ERROR ;
380343 }
381344 }
345+ #endif /* HAVE_UNIX_SOCKETS */
346+
347+ listen (fd , SOMAXCONN );
348+
349+ * fdP = fd ;
350+
382351 return STATUS_OK ;
383352}
384353
0 commit comments