When we need to identify the home directory on non-Windows, first
consult getenv("HOME"). If that's empty or unset, fall back
on our previous method of checking the <pwd.h> database.
Preferring $HOME allows the user to intentionally point at some
other directory, and it seems to be in line with the behavior of
most other utilities. However, we shouldn't rely on it completely,
as $HOME is likely to be unset when running as a daemon.
Anders Kaseorg
Discussion: https://postgr.es/m/
1634252654444.90107@mit.edu
else
{
#ifndef WIN32
- struct passwd *pw;
- uid_t user_id = geteuid();
-
- errno = 0; /* clear errno before call */
- pw = getpwuid(user_id);
- if (!pw)
+ /* This should match get_home_path() */
+ dir = getenv("HOME");
+ if (dir == NULL || dir[0] == '\0')
{
- pg_log_error("could not get home directory for user ID %ld: %s",
- (long) user_id,
- errno ? strerror(errno) : _("user does not exist"));
- exit(EXIT_FAILURE);
+ uid_t user_id = geteuid();
+ struct passwd *pw;
+
+ errno = 0; /* clear errno before call */
+ pw = getpwuid(user_id);
+ if (pw)
+ dir = pw->pw_dir;
+ else
+ {
+ pg_log_error("could not get home directory for user ID %ld: %s",
+ (long) user_id,
+ errno ? strerror(errno) : _("user does not exist"));
+ success = false;
+ }
}
- dir = pw->pw_dir;
#else /* WIN32 */
/*
#endif /* WIN32 */
}
- if (chdir(dir) == -1)
+ if (success &&
+ chdir(dir) < 0)
{
pg_log_error("\\%s: could not change directory to \"%s\": %m",
cmd, dir);
pqGetHomeDirectory(char *buf, int bufsize)
{
#ifndef WIN32
- char pwdbuf[BUFSIZ];
- struct passwd pwdstr;
- struct passwd *pwd = NULL;
+ const char *home;
- (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
- if (pwd == NULL)
- return false;
- strlcpy(buf, pwd->pw_dir, bufsize);
+ home = getenv("HOME");
+ if (home == NULL || home[0] == '\0')
+ {
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pwd = NULL;
+
+ (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
+ if (pwd == NULL)
+ return false;
+ home = pwd->pw_dir;
+ }
+ strlcpy(buf, home, bufsize);
return true;
#else
char tmppath[MAX_PATH];
get_home_path(char *ret_path)
{
#ifndef WIN32
- char pwdbuf[BUFSIZ];
- struct passwd pwdstr;
- struct passwd *pwd = NULL;
+ /*
+ * We first consult $HOME. If that's unset, try to get the info from
+ * <pwd.h>.
+ */
+ const char *home;
- (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
- if (pwd == NULL)
- return false;
- strlcpy(ret_path, pwd->pw_dir, MAXPGPATH);
+ home = getenv("HOME");
+ if (home == NULL || home[0] == '\0')
+ {
+ char pwdbuf[BUFSIZ];
+ struct passwd pwdstr;
+ struct passwd *pwd = NULL;
+
+ (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
+ if (pwd == NULL)
+ return false;
+ home = pwd->pw_dir;
+ }
+ strlcpy(ret_path, home, MAXPGPATH);
return true;
#else
char *tmppath;