diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-01-11 13:46:12 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-01-11 13:46:20 -0500 |
commit | 98e93a1fc93e9b54eb477d870ec744e9e1669f34 (patch) | |
tree | 8d16b420c2b1b49c9c21af5d8fe93c9d1da93e1e /src/port/thread.c | |
parent | 7fa945b857cc1b2964799411f1633468826861ff (diff) | |
download | postgresql-98e93a1fc93e9b54eb477d870ec744e9e1669f34.tar.gz postgresql-98e93a1fc93e9b54eb477d870ec744e9e1669f34.zip |
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
Diffstat (limited to 'src/port/thread.c')
-rw-r--r-- | src/port/thread.c | 96 |
1 files changed, 63 insertions, 33 deletions
diff --git a/src/port/thread.c b/src/port/thread.c index c1040d4e240..23c3fbdf864 100644 --- a/src/port/thread.c +++ b/src/port/thread.c @@ -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) - - /* - * 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 + char pwdbuf[BUFSIZ]; + struct passwd pwdstr; + struct passwd *pw = NULL; + int pwerr; - /* no gethostbyname_r(), just use gethostbyname() */ - *result = gethostbyname(name); + 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 + snprintf(buffer, buflen, + _("local user with ID %d does not exist"), + (int) user_id); + return false; +} - if (*result != NULL) - *herrno = h_errno; +/* + * 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; - if (*result != NULL) - return 0; + 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 - return -1; -#endif + snprintf(buffer, buflen, + _("local user with ID %d does not exist"), + (int) user_id); + return false; } -#endif +#endif /* !WIN32 */ |