即使没有控制终端,为什么getlogin()会成功

时间:2012-06-21 18:26:36

标签: c perl

我写了一个简单的C程序:

#include <unistd.h>
#include <stdio.h>

int main( int argc, char *argv[] ) {
  printf( "%s\n", getlogin() );
  return 0;
}

...尝试一些事情。我已经尝试通过确保没有控制终端来使getlogin()失败,但它仍然获取登录名并打印它。证明这一点的最极端的例子:

#!/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 ) );' ) &

以解释的方式:它取消设置除PATH之外的所有环境变量,然后运行一个执行“tty”的子shell。然后是perl实例;子壳是背景的。调用setpgrp以确保它没有使用进程组来查找父控制终端(我不相信它,但我把它放在那里以防假设错误)。

此时此刻,我感到茫然。它仍然打印用户名。我从很多来源看到的一个更简单的例子具有相同的行为:

sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' &'
sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' & wait'

这两个版本仍在Solaris 10和Redhat 6下打印用户名,其中包含不同版本的perl,bash,sh和tcsh。

1 个答案:

答案 0 :(得分:1)

将STDIN关闭或重定向到文件就可以了。

$ perl -wE'say getlogin()'
eric

$ perl -wE'open STDIN, "<", "/dev/null" or die $!; say getlogin()'
Use of uninitialized value in say at -e line 1.

这是Debian盒子上的自建Perl(默认选项)。