Zat42
Zat42

Reputation: 2921

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

How can I get the actual "username" without using the environment (getenv, ...) in a program? Environment is C/C++ with Linux.

Upvotes: 47

Views: 124839

Answers (7)

Timmmm
Timmmm

Reputation: 96822

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

// Return username or nullptr if unknown.
const char* username() {
    const passwd* pw = getpwuid(geteuid());
    return pw == nullptr ? nullptr : pw->pw_name;
}

Upvotes: 0

Akash
Akash

Reputation: 189

#include <iostream>
#include <unistd.h>
int main()
{
    std::string Username = getlogin();
    std::cout << Username << std::endl;
    return 0 ;
}

Another way is this -

#include <iostream>
using namespace std;
int main()
{
       cout << system("whoami");
}

Upvotes: 5

Hossein
Hossein

Reputation: 26004

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)
        // whoami works on windows as well but it returns the name 
        // in the format of `computer_name\user_name` so instead
        // we use %USERNAME% which gives us the exact username.
        #define USERNAME_QUERY "echo %USERNAME%" 
    #elif defined(unix) || defined(__unix__) || defined(__unix)
        #define USERNAME_QUERY "whoami"
    #endif
    auto username = execute_command(USERNAME_QUERY);
    // this line removes the white spaces (such as newline, etc)
    // from the username.
    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://paiza.io/projects/e/xmBuf3rD7MhYca02v5V2dw?theme=twilight

Upvotes: -2

r3t40
r3t40

Reputation: 637

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

Upvotes: 2

juanba
juanba

Reputation: 51

working a little bit through modern c++ specs

static auto whoAmI = [](){ struct passwd *tmp = getpwuid (geteuid ());
  return tmp ? tmp->pw_name : "onlyGodKnows"; 
}

Upvotes: 1

Nemanja Boric
Nemanja Boric

Reputation: 22177

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 "";
}

Upvotes: 63

drrlvn
drrlvn

Reputation: 8437

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++.

Upvotes: 68

Related Questions