web-dev-qa-db-ja.com

Linuxでホームディレクトリを取得する

Linuxで実行されているC++プログラムでユーザーのホームディレクトリを取得する方法が必要です。同じコードがUnixで動作する場合、それは素晴らしいでしょう。 HOME環境値を使用したくありません。

私の知る限り、ルートホームディレクトリは/ rootです。プログラムがrootユーザーによって実行されている場合、このディレクトリにいくつかのファイル/フォルダーを作成しても大丈夫ですか?

61
Alex F

現在のユーザーのユーザーIDを取得するにはgetuidが必要で、そのユーザーのパスワードエントリ(ホームディレクトリを含む)を取得するにはgetpwuidが必要です。

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

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

const char *homedir = pw->pw_dir;

注:スレッドアプリケーションでこれが必要な場合は、getpwuid_r代わりに。

88

最初に_$HOME_環境変数を確認し、存在しない場合はgetpwuidを使用する必要があります。

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

const char *homedir;

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

また、作成するプログラムの一部としてホームディレクトリに構成またはキャッシュデータを保存し、ユーザーに配布する場合は、 XDG Base Directory Specification に従うことを検討してください。たとえば、アプリケーションの構成ディレクトリを作成する場合、最初に上記のgetenvを使用して_$XDG_CONFIG_HOME_を確認し、変数が設定されていない場合にのみ上記のコードにフォールバックする必要があります。

マルチスレッドの安全性が必要な場合は、getpwuidの代わりに_getpwuid_r_を次のように使用する必要があります(getpwnam(3) manページから):

_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;
_
63
josch

ルートとしてプログラムを実行している場合、このディレクトリへのrwxアクセスができます。内部に何かを作成するのは問題ないと思います。

0
Anthony