This fails when there are multiple users with the same uid as getpwuid()
will likely fetch the first matching entry. On FreeBSD (& May be other
BSDs) getlogin() is a syscall and works correctly without a controlling
terminal. But I was forgetting about Linux which never disappoints
in disappointing. I think use of $LOGNAME as a fallback may be good
I have to say ... if you have multiple users with the same UID, you deserve
whatever breakage you get. According to POSIX:
The getlogin() function shall return a pointer to a string
containing the user name associated by the login activity with
the controlling terminal of the current process.
And getlogin() is allowed to return ENXIO if there is no controlling
terminal. So while Linux's behavior may be undesirable in this case
it is certainly permitted.
Also, POSIX says about LOGNAME:
The system shall initialize this variable at the time of login
to be the user's login name.
I am unclear on what "login" means; does it apply when running as part
of a .forward file? When you have a controlling terminal, yes, that is
understood but I see no guarantees for other execution environments.
True story: a long time ago we had a number of IRIX systems. The inetd
on those systems was buggy so it was common when you changed the inetd
configuration you just restarted it instead of sending it a HUP signal.
But even though the person who did this had su'd to root, some of their
user environment variables were inherited by their root shell and then
inherited by inetd ... and those made it down into various daemons
spawned by inetd which caused a whole bunch of confusing behavior at
login time. We eventually figured that out and fixed everything, but it
just made me realize that depending on inherited environment variables
isn't always safe. If nmh already depended on LOGNAME or USER, then
I'd be fine with keeping that behavior but I just fear the unintended
consequences of making a significant change like this.