C++の基礎 - ユーザとグループ

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要



Linuxのグループの取得

以下の例では、現在のユーザが所属しているグループ名を取得している。

標準C++とPOSIX APIのみを使用している。
ただし、この実装はUNIX系システム (Linux、MacOS) 向けであるため、Windowsでは動作しないことに注意すること。
Windowsで同様の機能を実装する場合は、Windows APIを使用する必要がある。

このサンプルコードは、以下に示すような手順で動作する。

  1. まず、現在のユーザのUIDを取得する。
  2. UIDを使用してユーザ情報を取得する。
  3. UNIX系システム向けのgetgrouplist関数を使用して、ユーザが所属するグループの数とIDを取得する。
  4. 各グループIDに対して、getgrgid関数を使用してグループ名を取得する。
  5. 取得したグループ名をstd::std::vector<std::string>クラスに追加する。


 #include <iostream>
 #include <vector>
 #include <string>
 #include <cstring>
 #include <grp.h>
 #include <pwd.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <errno.h>
 
 std::vector<std::string> getUserGroups(std::string& errorMessage)
 {
    std::vector<std::string> groups;
    errorMessage.clear();
 
    uid_t uid = getuid();
 
    struct passwd *pw = getpwuid(uid);
    if (!pw) {
       errorMessage = "Failed to get user info: " + std::string(strerror(errno));
       return groups;
    }
 
    int ngroups = 0;
    if (getgrouplist(pw->pw_name, pw->pw_gid, nullptr, &ngroups) == -1) {
       errorMessage = "Failed to get group list size";
       return groups;
    }
 
    if (ngroups > 0) {
       std::vector<gid_t> gids(ngroups);
       if (getgrouplist(pw->pw_name, pw->pw_gid, gids.data(), &ngroups) == -1) {
          errorMessage = "Failed to get group list";
          return groups;
       }
 
       for (int i = 0; i < ngroups; i++) {
          errno = 0;
          struct group *gr = getgrgid(gids[i]);
          if (gr) {
             groups.push_back(std::string(gr->gr_name));
          }
          else {
             std::cerr << "Failed to get group name for gid " << gids[i] << ": " << strerror(errno) << std::endl;
          }
       }
    }
    else {
       errorMessage = "User is not a member of any groups";
    }
 
    return groups;
 }


 // 使用例
 int main()
 {
    std::string errorMessage;
    std::vector<std::string> userGroups = getUserGroups(errorMessage);
 
    if (!errorMessage.empty()) {
       std::cerr << "Error occurred: " << errorMessage << std::endl;
    }
    else if (userGroups.empty()) {
       std::cout << "User is not a member of any groups" << std::endl;
    }
    else {
       std::cout << "User groups:" << std::endl;
       for (const auto& group : userGroups) {
          std::cout << "  " << group << std::endl;
       }
    }
 
    return 0;
 }