2012-03-20 13 views
6

リダイレクトSTDIN Unix.getloginと予期しない例外:OCamlは:私はこの単純なコードで次の問題を発見し

let() = 
    print_endline "Hello"; 
    print_endline (Unix.getlogin()) 

通常の場合には実行./a.outでは、与えられる:

Hello 
ricardo 

しかし、 ./a.out </dev/nullのように実行すると、Unix.getloginが失敗します。

Hello 
Fatal error: exception Unix.Unix_error(20, "getlogin", "") 

すべてのIDなぜこのようなことが起こるのでしょうか?

+0

私のシステムでこれを試しました:Mac OS X 10.6.8/OCaml 3.12.0と私は問題を見ることができません。どちらの場合も出力は同じです。あなたのシステムは何ですか? –

+0

Linux、もう一度man 3 getloginを読んで、glibcでstdinのリダイレクトについて "バグ"を見ました: -/ – Ricardo

+0

はい、bkconradはそれを釘付けにしました! –

答えて

5

プログラムの入力をリダイレクトすると、その制御端末が上書きされます。制御端末がなければ、発見される何のログインはありません。

$ tty 
/dev/pts/2 
$ tty < /dev/null 
not a tty 

あなたは、しかし、まだユーザーのIDを取得(getuid)と彼のpasswd entry (related docs)getpwuid)を調べることで(多分)、ユーザーの名前を見つけることができ、その中で彼のユーザー名を見つける。

+0

答えは、制御端末からではなく、プロセスのuidから来るべきです。しかし、それでも問題になる可能性があります。 –

+0

実際に 'getlogin'(http://linux.die.net/man/3/getlogin)を呼び出すと仮定すると、実際には制御端末から来ています。 – bkconrad

+0

うわー。 BSD(およびMac OS X)では、ログイン時に別々の値が設定されます。予想通りgetuid()またはgeteuid()に基づいているのではなく、端末を制御していません。私には少し良く見えます。 –

3

アプリケーションによって:あなたはおそらく何かを得るだろう

try 
    Unix.getlogin() 
with _ -> Sys.getenv "USER" 

  • をあなたは本当に「にgetlogin」によって返された値を気にしないならば、あなたのような何かを行うことができますgetuidよりも優れています。これは、Set-User-IDフラグ(sudo/su)を持つプログラムでも機能するためです。

  • 「getlogin」によって返された値を本当に気にしている場合、つまり、本当に誰がログインしているか知りたい場合は、getloginが失敗したときに失敗するだけです。他の解決方法では、正しい結果の近似値しか得られません。

関連する問題