我需要在C程序中检索用户的用户名。我知道getlogin
和getlogin_r
。但是我的程序有一个重定向的标准输入(因为有些forks
)。
我遇到的问题在联机帮助页中说明:
请注意,glibc不遵循POSIX规范并使用stdin 而不是/ dev / tty。一个bug。 (其他最近的系统,如SunOS 5.8 和HP-UX 11.11和FreeBSD 4.8都返回登录名 stdin被重定向)。
我还有其他方法可以检索用户名吗?
答案 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相关联的多个登录时(尽管这种情况应该很少,不足以成为实际问题)。