Get home directory in Linux

C++CLinux

C++ Problem Overview


I need a way to get user home directory in C++ program running on Linux. If the same code works on Unix, it would be nice. I don't want to use HOME environment value.

AFAIK, root home directory is /root. Is it OK to create some files/folders in this directory, in the case my program is running by root user?

C++ Solutions


Solution 1 - C++

You need getuid to get the user id of the current user and then getpwuid to get the password entry (which includes the home directory) of that user:

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

struct passwd *pw = getpwuid(getuid());

const char *homedir = pw->pw_dir;

Note: if you need this in a threaded application, you'll want to use getpwuid_r instead.

Solution 2 - C++

You should first check the $HOME environment variable, and if that does not exist, use getpwuid.

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

const char *homedir;

if ((homedir = getenv("HOME")) == NULL) {
    homedir = getpwuid(getuid())->pw_dir;
}

Also note, that if you want the home directory to store configuration or cache data as part of a program you write and want to distribute to users, you should consider following the XDG Base Directory Specification. For example if you want to create a configuration directory for your application, you should first check $XDG_CONFIG_HOME using getenv as shown above and only fall back to the code above if the variable is not set.

If you require multi-thread safety, you should use getpwuid_r instead of getpwuid like this (from the getpwnam(3) man page):

struct passwd pwd;
struct passwd *result;
char *buf;
size_t bufsize;
int s;
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1)
    bufsize = 0x4000; // = all zeroes with the 14th bit set (1 << 14)
buf = malloc(bufsize);
if (buf == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
}
s = getpwuid_r(getuid(), &pwd, buf, bufsize, &result);
if (result == NULL) {
    if (s == 0)
        printf("Not found\n");
    else {
        errno = s;
        perror("getpwnam_r");
    }
    exit(EXIT_FAILURE);
}
char *homedir = result.pw_dir;

Solution 3 - C++

If you're running the program as root then you'll have rwx access to this directory. Creating stuff inside it is fine, i suppose.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex FView Question on Stackoverflow
Solution 1 - C++R Samuel KlatchkoView Answer on Stackoverflow
Solution 2 - C++joschView Answer on Stackoverflow
Solution 3 - C++AnthonyView Answer on Stackoverflow