aboutsummaryrefslogtreecommitdiff
path: root/src/port/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/port/thread.c')
-rw-r--r--src/port/thread.c96
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 */