I need to retrieve the users username in a C program. I know about getlogin
and getlogin_r
. But my program has a redirected stdin (because of some forks
).
The Problem I face is stated in the manpage:
Note that glibc does not follow the POSIX specification and uses stdin instead of /dev/tty. A bug. (Other recent systems, like SunOS 5.8 and HP-UX 11.11 and FreeBSD 4.8 all return the login name also when stdin is redirected).
Is there any other way I could retrieve the username?
Use getresuid(2) or some of the more specific id retrieval functions to get the id you want (real, effective, or saved-set) (you probably want RUID, if you want to emulate getlogin
, in which case you can simply call getuid
and forget about the effective and saved-set uid), and then use getpwuid(3) or its reentrant counterpart to translate that to a user id string.
getenv("USER")
might give you the same result, but you can't rely on it if you want real security.
Technically, all these may be different from the result obtained by getlogin
when stdin is your controlling terminal. If you really need the same answer as what getlogin
would get you, you can temporarily make your fd 0 point to your controlling terminal again, then call getlogin
, and then restore your 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*/;
You can retrieve the id user with getuid and then call getpwuid_r to find out the username the corresponds to that id.
Edit: Oops, I meant to say getpwuid_r instead of getpwent_r as correctly @PSkocik pointed out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With