How to get the username in C/C++ in Linux?

后端 未结 5 482
灰色年华
灰色年华 2020-12-05 10:18

How can I get the actual \"username\" without using the environment (getenv, ...) in a program?

相关标签:
5条回答
  • 2020-12-05 10:34

    Today I had to do the same thing, but didn't like to include any OS specific headers. So here is what you can do in a cross-platform way without resorting to any Linux/Windows specific headers:

    #include <stdio.h> 
    #include <memory>
    #include <stdexcept>
    #include <array>
    #include <regex>
    
    std::string execute_command(std::string cmd) 
    {
        std::array<char, 128> buffer;
        std::string result;
        
        #if defined(_WIN32)
            #define POPEN _popen
            #define PCLOSE _pclose
        #elif defined(unix) || defined(__unix__) || defined(__unix)
            #define POPEN popen
            #define PCLOSE pclose
        #endif
    
        std::unique_ptr<FILE, decltype(&PCLOSE)> pipe(POPEN(cmd.c_str(), "r"), PCLOSE);
        if (!pipe) 
        {
            throw std::runtime_error("popen() failed!");
        }
        while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) 
        {
            result += buffer.data();
        }
        return result;
    }
    std::string get_current_username()
    {
        #if defined(_WIN32)
            #define USERNAME_QUERY "echo %USERNAME%" // whoami works on windows as well but it returns the name with the format `computer_name\user_name`
        #elif defined(unix) || defined(__unix__) || defined(__unix)
            #define USERNAME_QUERY "whoami"
        #endif
        auto username = execute_command(USERNAME_QUERY);
        username = std::regex_replace(username, std::regex("\\s"), "");
        return username;
    }
    

    This works just fine on both Linux and Windows and is C++11 compatible!

    Test it online: https://onlinegdb.com/rk8T5LM9P

    0 讨论(0)
  • 2020-12-05 10:37

    working a little bit through modern c++ specs

    static auto whoAmI = [](){ struct passwd *tmp = getpwuid (geteuid ());
      return tmp ? tmp->pw_name : "onlyGodKnows"; 
    }
    
    0 讨论(0)
  • 2020-12-05 10:43

    The function getlogin_r() defined in unistd.h returns the username. See man getlogin_r for more information.

    Its signature is:

    int getlogin_r(char *buf, size_t bufsize);
    

    Needless to say, this function can just as easily be called in C or C++.

    0 讨论(0)
  • 2020-12-05 10:43

    Use char *cuserid(char *s) found in stdio.h.

    #include <stdio.h>
    
    #define MAX_USERID_LENGTH 32
    
    int main()
    {
      char username[MAX_USERID_LENGTH];
      cuserid(username);
      printf("%s\n", username);
      return 0;
    }
    

    See for more details:

    1. https://pubs.opengroup.org/onlinepubs/007908799/xsh/cuserid.html
    2. https://serverfault.com/questions/294121/what-is-the-maximum-username-length-on-current-gnu-linux-systems
    0 讨论(0)
  • 2020-12-05 10:51

    From http://www.unix.com/programming/21041-getting-username-c-program-unix.html :

    /* whoami.c */
    #define _PROGRAM_NAME "whoami"
    #include <stdlib.h>
    #include <pwd.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
      register struct passwd *pw;
      register uid_t uid;
      int c;
    
      uid = geteuid ();
      pw = getpwuid (uid);
      if (pw)
        {
          puts (pw->pw_name);
          exit (EXIT_SUCCESS);
        }
      fprintf (stderr,"%s: cannot find username for UID %u\n",
           _PROGRAM_NAME, (unsigned) uid);
      exit (EXIT_FAILURE);
    
    }
    

    Just take main lines and encapsulate it in class:

    class Env{
        public:
        static std::string getUserName()
        {
            uid_t uid = geteuid ();
            struct passwd *pw = getpwuid (uid);
            if (pw)
            {
                return std::string(pw->pw_name);
            }
            return {};
        }
    };
    

    For C only:

    const char *getUserName()
    {
      uid_t uid = geteuid();
      struct passwd *pw = getpwuid(uid);
      if (pw)
      {
        return pw->pw_name;
      }
    
      return "";
    }
    
    0 讨论(0)
提交回复
热议问题