1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-28 18:48:04 +03:00

Clean up messy API for src/port/thread.c.

The point of this patch is to reduce inclusion spam by not needing
to #include <netdb.h> or <pwd.h> in port.h (which is read by every
compile in our tree).  To do that, we must remove port.h's
declarations of pqGetpwuid and pqGethostbyname.

pqGethostbyname is only used, and is only ever likely to be used,
in src/port/getaddrinfo.c --- which isn't even built on most
platforms, making pqGethostbyname dead code for most people.
Hence, deal with that by just moving it into getaddrinfo.c.

To clean up pqGetpwuid, invent a couple of simple wrapper
functions with less-messy APIs.  This allows removing some
duplicate error-handling code, too.

In passing, remove thread.c from the MSVC build, since it
contains nothing we use on Windows.

Noted while working on 376ce3e40.

Discussion: https://postgr.es/m/1634252654444.90107@mit.edu
This commit is contained in:
Tom Lane
2022-01-11 13:46:12 -05:00
parent 7fa945b857
commit 98e93a1fc9
11 changed files with 160 additions and 112 deletions

View File

@@ -45,10 +45,9 @@
* use *_r function names if they exit
* (*_THREADSAFE=yes)
* use non-*_r functions if they are thread-safe
*
* One thread-safe solution for gethostbyname() might be to use getaddrinfo().
*/
#ifndef WIN32
/*
* Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
@@ -60,8 +59,7 @@
* error during lookup: returns an errno code, *result is NULL
* (caller should *not* assume that the errno variable is set)
*/
#ifndef WIN32
int
static int
pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
size_t buflen, struct passwd **result)
{
@@ -75,42 +73,74 @@ pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
return (*result == NULL) ? errno : 0;
#endif
}
#endif
/*
* Wrapper around gethostbyname() or gethostbyname_r() to mimic
* POSIX gethostbyname_r() behaviour, if it is not available or required.
* This function is called _only_ by our getaddrinfo() portability function.
* pg_get_user_name - get the name of the user with the given ID
*
* On success, the user name is returned into the buffer (of size buflen),
* and "true" is returned. On failure, a localized error message is
* returned into the buffer, and "false" is returned.
*/
#ifndef HAVE_GETADDRINFO
int
pqGethostbyname(const char *name,
struct hostent *resultbuf,
char *buffer, size_t buflen,
struct hostent **result,
int *herrno)
bool
pg_get_user_name(uid_t user_id, char *buffer, size_t buflen)
{
#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
char pwdbuf[BUFSIZ];
struct passwd pwdstr;
struct passwd *pw = NULL;
int pwerr;
/*
* broken (well early POSIX draft) gethostbyname_r() which returns 'struct
* hostent *'
*/
*result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
return (*result == NULL) ? -1 : 0;
#else
/* no gethostbyname_r(), just use gethostbyname() */
*result = gethostbyname(name);
if (*result != NULL)
*herrno = h_errno;
if (*result != NULL)
return 0;
pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
if (pw != NULL)
{
strlcpy(buffer, pw->pw_name, buflen);
return true;
}
if (pwerr != 0)
snprintf(buffer, buflen,
_("could not look up local user ID %d: %s"),
(int) user_id,
strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
else
return -1;
#endif
snprintf(buffer, buflen,
_("local user with ID %d does not exist"),
(int) user_id);
return false;
}
#endif
/*
* pg_get_user_home_dir - get the home directory of the user with the given ID
*
* On success, the directory path is returned into the buffer (of size buflen),
* and "true" is returned. On failure, a localized error message is
* returned into the buffer, and "false" is returned.
*
* Note that this does not incorporate the common behavior of checking
* $HOME first, since it's independent of which user_id is queried.
*/
bool
pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen)
{
char pwdbuf[BUFSIZ];
struct passwd pwdstr;
struct passwd *pw = NULL;
int pwerr;
pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
if (pw != NULL)
{
strlcpy(buffer, pw->pw_dir, buflen);
return true;
}
if (pwerr != 0)
snprintf(buffer, buflen,
_("could not look up local user ID %d: %s"),
(int) user_id,
strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
else
snprintf(buffer, buflen,
_("local user with ID %d does not exist"),
(int) user_id);
return false;
}
#endif /* !WIN32 */