I wrote a simple C program:
#include <unistd.h>
#include <stdio.h>
int main( int argc, char *argv[] ) {
printf( "%s\n", getlogin() );
return 0;
}
… to try some things out. I’ve tried making getlogin() fail by making sure there isn’t a controlling terminal, but it’s still getting the login name and printing it. The most extreme example to demonstrate this:
#!/bin/bash
for i in $(env | grep -vP ^PATH\\b | awk -F= \{print \$1\}); do
unset $i;
done;
(tty; perl -e 'setpgrp; sleep( 1 ); exec( qw( getlogin_test ) );' ) &
In the way of explanation: it un-sets all environment variables except PATH, then runs a sub-shell that executes ‘tty’ then a perl instance; the sub-shell is backgrounded. Calls setpgrp to make sure it isn’t using the process group to find the parent’s controlling terminal (I don’t believe it does, but I put it in there in case that assumption was wrong).
At this point, I’m at a loss. It still prints the username. A simpler example that I’ve seen from quite a few sources has the same behavior:
sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' &'
sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' & wait'
Both of these still print the username, under both Solaris 10 and Redhat 6 with differing versions of perl, bash, sh, and tcsh.
Closing or redirecting STDIN to a file does the trick.
This is a self-built Perl (default options) on a Debian box.