C / Linux:如何在没有`getlogin`的情况下获取用户登录名

时间:2016-09-02 12:36:57

标签: c linux

我需要在C程序中检索用户的用户名。我知道getlogingetlogin_r。但是我的程序有一个重定向的标准输入(因为有些forks)。

我遇到的问题在联机帮助页中说明:

  

请注意,glibc不遵循POSIX规范并使用stdin   而不是/ dev / tty。一个bug。 (其他最近的系统,如SunOS 5.8   和HP-UX 11.11和FreeBSD 4.8都返回登录名   stdin被重定向)。

我还有其他方法可以检索用户名吗?

3 个答案:

答案 0 :(得分:6)

使用getresuid(2)或一些更具体的ID检索功能来获取您想要的ID(真实,有效或保存集)(如果您想模仿getlogin,您可能需要RUID ,在这种情况下,您可以简单地调用getuid并忘记有效和已保存集合的uid),然后使用getpwuid(3)或其可重入对应项将其转换为用户ID字符串。

getenv("USER")可能会给您相同的结果,但如果您想要真正的安全性,则无法依赖它。

从技术上讲,当stdin是你的控制终端时,所有这些可能与getlogin获得的结果不同。如果你真的需要与getlogin得到的答案相同的答案,你可以暂时让你的fd 0指向你的控制终端,然后拨打getlogin,然后恢复你的fd 0:

int saved_fd0;
if(0>(saved_fd0 = dup(0))
       /*handle error*/;
close(0);

/*open always gets the lowest possible fd number == now 0*/
/*"/dev/tty" is always your current processes's controlling terminal*/
if(0>open("/dev/tty", O_RDONLY))
    /*handle error*/;
/*
getlogin()
..
*/
/*restore saved_fd0*/
if(0>dup2(saved_fd0, 0))
       /*handle error*/;

答案 1 :(得分:5)

您可以使用getuid检索ID用户,然后拨打getpwuid_r以找出与该ID对应的用户名。

修改:哎呀,我的意思是getpwuid_r而不是getpwent_r正如@PSkocik指出的那样。

答案 2 :(得分:2)

如果您对可能的错误标识(多个登录绑定到同一UID)没问题,可以使用getuid(2)getresuid(2)获取UID,然后使用getpwuid(3)获取名称(或者,如果多个用户名具有相同的UID,则其中一个名称,文档不清楚这是否是随机名称,第一个在文件中遇到,...)。

这不依赖于指向登录终端的任何特定文件描述符,也不依赖于utmp记录,但它依赖于/ etc / passwd中存在的UID并且可能无法识别正确的登录名使用时,在存在与同一UID相关联的多个登录时(尽管这种情况应该很少,不足以成为实际问题)。