You must check the $HOME environment variable first, and if it 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 save configuration data or cache as part of the program that you write and want to distribute to users, you should consider complying with the XDG Base Directory specification . For example, if you want to create a configuration directory for your application, you must first check $XDG_CONFIG_HOME using getenv as shown above, and return to the code above only if the variable is not set.
If you require multi-threaded security, you should use getpwuid_r instead of getpwuid as follows (from the getpwnam(3) 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;
josch Nov 02 '14 at 6:44 2014-11-02 06:44
source share