From 15ab7a87206d657a4182d2932970384d540004d0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 25 Jan 2003 05:19:47 +0000 Subject: [PATCH] Where available, use utime() or utimes() to update the file mod time of the socket file and socket lock file; this should prevent both of them from being removed by even the stupidest varieties of /tmp-cleaning script. Per suggestion from Giles Lean. --- configure | 7 +++- configure.in | 6 +-- src/backend/libpq/pqcomm.c | 59 ++++++++++++++++++++++++----- src/backend/postmaster/postmaster.c | 3 +- src/backend/utils/init/miscinit.c | 35 +++++++++++++---- src/include/libpq/libpq.h | 3 +- src/include/pg_config.h.in | 11 +++++- 7 files changed, 99 insertions(+), 25 deletions(-) diff --git a/configure b/configure index d0d1682c7f..e9971ce570 100755 --- a/configure +++ b/configure @@ -6887,7 +6887,8 @@ done -for ac_header in crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h kernel/OS.h kernel/image.h SupportDefs.h + +for ac_header in crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h utime.h kernel/OS.h kernel/image.h SupportDefs.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -9819,7 +9820,9 @@ test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext" -for ac_func in cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync + + +for ac_func in cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync utime utimes do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index ad801d1e77..840c5a0a2b 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.232 2003/01/11 04:58:44 momjian Exp $ +dnl $Header: /cvsroot/pgsql/configure.in,v 1.233 2003/01/25 05:19:45 tgl Exp $ dnl dnl Developers, please strive to achieve this order: dnl @@ -675,7 +675,7 @@ fi ## dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES -AC_CHECK_HEADERS([crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h kernel/OS.h kernel/image.h SupportDefs.h]) +AC_CHECK_HEADERS([crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h utime.h kernel/OS.h kernel/image.h SupportDefs.h]) # At least on IRIX, cpp test for netinet/tcp.h will fail unless # netinet/in.h is included first. @@ -782,7 +782,7 @@ PGAC_FUNC_GETTIMEOFDAY_1ARG # SunOS doesn't handle negative byte comparisons properly with +/- return AC_FUNC_MEMCMP -AC_CHECK_FUNCS([cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync]) +AC_CHECK_FUNCS([cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync utime utimes]) AC_CHECK_DECLS(fdatasync, [], [], [#include ]) diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 7ad3dea2a8..8c6e1dc6d0 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -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.146 2003/01/14 22:52:57 momjian Exp $ + * $Id: pqcomm.c,v 1.147 2003/01/25 05:19:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,6 +41,7 @@ * StreamServerPort - Open postmaster's server port * StreamConnection - Create new connection with client * StreamClose - Close a client/backend connection + * TouchSocketFile - Protect socket file against /tmp cleaners * pq_init - initialize libpq at backend startup * pq_close - shutdown libpq at backend exit * @@ -66,15 +67,19 @@ #include #include #include -#include +#include #include +#include +#include #include #include #ifdef HAVE_NETINET_TCP_H #include #endif #include -#include +#ifdef HAVE_UTIME_H +#include +#endif #include "libpq/libpq.h" #include "miscadmin.h" @@ -87,8 +92,8 @@ extern ssize_t secure_write(Port *, const void *, size_t); static void pq_close(void); #ifdef HAVE_UNIX_SOCKETS -int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName); -int Setup_AF_UNIX(void); +static int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName); +static int Setup_AF_UNIX(void); #endif /* HAVE_UNIX_SOCKETS */ #ifdef HAVE_IPV6 @@ -175,12 +180,14 @@ static char sock_path[MAXPGPATH]; * Shutdown routine for backend connection * If a Unix socket is used for communication, explicitly close it. */ +#ifdef HAVE_UNIX_SOCKETS static void StreamDoUnlink(void) { Assert(sock_path[0]); unlink(sock_path); } +#endif /* HAVE_UNIX_SOCKETS */ /* * StreamServerPort -- open a sock stream "listening" port. @@ -345,12 +352,13 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, } + +#ifdef HAVE_UNIX_SOCKETS + /* * Lock_AF_UNIX -- configure unix socket file path */ - -#ifdef HAVE_UNIX_SOCKETS -int +static int Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName) { SockAddr saddr; /* just used to get socket path */ @@ -377,7 +385,7 @@ Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName) /* * Setup_AF_UNIX -- configure unix socket permissions */ -int +static int Setup_AF_UNIX(void) { /* Arrange to unlink the socket file at exit */ @@ -429,6 +437,7 @@ Setup_AF_UNIX(void) } return STATUS_OK; } + #endif /* HAVE_UNIX_SOCKETS */ @@ -506,6 +515,38 @@ StreamClose(int sock) close(sock); } +/* + * TouchSocketFile -- mark socket file as recently accessed + * + * This routine should be called every so often to ensure that the socket + * file has a recent mod date (ordinary operations on sockets usually won't + * change the mod date). That saves it from being removed by + * overenthusiastic /tmp-directory-cleaner daemons. (Another reason we should + * never have put the socket file in /tmp...) + */ +void +TouchSocketFile(void) +{ + /* Do nothing if we did not create a socket... */ + if (sock_path[0] != '\0') + { + /* + * utime() is POSIX standard, utimes() is a common alternative. + * If we have neither, there's no way to affect the mod or access + * time of the socket :-( + * + * In either path, we ignore errors; there's no point in complaining. + */ +#ifdef HAVE_UTIME + utime(sock_path, NULL); +#else /* !HAVE_UTIME */ +#ifdef HAVE_UTIMES + utimes(sock_path, NULL); +#endif /* HAVE_UTIMES */ +#endif /* HAVE_UTIME */ + } +} + /* -------------------------------- * Low-level I/O routines begin here. diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index c9334ef514..85a11ce8a4 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.305 2003/01/16 00:26:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.306 2003/01/25 05:19:46 tgl Exp $ * * NOTES * @@ -2678,6 +2678,7 @@ SSDataBase(int xlop) * do other actions that should happen every now and then on no * particular schedule. Such as... */ + TouchSocketFile(); TouchSocketLockFile(); } diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 4ef5b0fb8d..ad0df82135 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.98 2002/12/05 04:04:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.99 2003/01/25 05:19:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,8 +16,9 @@ #include #include -#include #include +#include +#include #include #include #include @@ -25,6 +26,9 @@ #include #include #include +#ifdef HAVE_UTIME_H +#include +#endif #include "catalog/catname.h" #include "catalog/pg_shadow.h" @@ -872,27 +876,42 @@ CreateSocketLockFile(const char *socketfile, bool amPostmaster) } /* - * Re-read the socket lock file. This should be called every so often - * to ensure that the lock file has a recent access date. That saves it + * TouchSocketLockFile -- mark socket lock file as recently accessed + * + * This routine should be called every so often to ensure that the lock file + * has a recent mod or access date. That saves it * from being removed by overenthusiastic /tmp-directory-cleaner daemons. * (Another reason we should never have put the socket file in /tmp...) */ void TouchSocketLockFile(void) { - int fd; - char buffer[1]; - /* Do nothing if we did not create a socket... */ if (socketLockFile[0] != '\0') { - /* XXX any need to complain about errors here? */ + /* + * utime() is POSIX standard, utimes() is a common alternative; + * if we have neither, fall back to actually reading the file + * (which only sets the access time not mod time, but that should + * be enough in most cases). In all paths, we ignore errors. + */ +#ifdef HAVE_UTIME + utime(socketLockFile, NULL); +#else /* !HAVE_UTIME */ +#ifdef HAVE_UTIMES + utimes(socketLockFile, NULL); +#else /* !HAVE_UTIMES */ + int fd; + char buffer[1]; + fd = open(socketLockFile, O_RDONLY | PG_BINARY, 0); if (fd >= 0) { read(fd, buffer, sizeof(buffer)); close(fd); } +#endif /* HAVE_UTIMES */ +#endif /* HAVE_UTIME */ } } diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 0e8ecad246..04248b5c95 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq.h,v 1.55 2003/01/06 03:18:27 momjian Exp $ + * $Id: libpq.h,v 1.56 2003/01/25 05:19:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,6 +49,7 @@ extern int StreamServerPort(int family, char *hostName, unsigned short portNumber, char *unixSocketName, int *fdP); extern int StreamConnection(int server_fd, Port *port); extern void StreamClose(int sock); +extern void TouchSocketFile(void); extern void pq_init(void); extern int pq_getbytes(char *s, size_t len); extern int pq_getstring(StringInfo s, int maxlen); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index ecc198fbc8..ba878df0ac 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -8,7 +8,7 @@ * or in pg_config.h afterwards. Of course, if you edit pg_config.h, then your * changes will be overwritten the next time you run configure. * - * $Id: pg_config.h.in,v 1.37 2003/01/06 06:07:20 momjian Exp $ + * $Id: pg_config.h.in,v 1.38 2003/01/25 05:19:47 tgl Exp $ */ #ifndef PG_CONFIG_H @@ -383,6 +383,9 @@ /* Set to 1 if you have */ #undef HAVE_TERMIOS_H +/* Set to 1 if you have */ +#undef HAVE_UTIME_H + /* Set to 1 if you have */ #undef HAVE_SYS_PSTAT_H @@ -520,6 +523,12 @@ /* Define if you have fdatasync() */ #undef HAVE_FDATASYNC +/* Define if you have utime() */ +#undef HAVE_UTIME + +/* Define if you have utimes() */ +#undef HAVE_UTIMES + /* Define if the standard header unistd.h declares fdatasync() */ #undef HAVE_DECL_FDATASYNC -- GitLab