2012-03-20 8 views
6

मैं इस सरल कोड में अगले अंक में पता चला पुनः निर्देशित stdin:OCaml: Unix.getlogin साथ अनपेक्षित अपवाद जब

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", "") 

किसी भी आईडी और ऐसा क्यों होता है?

+0

मैंने अभी अपने सिस्टम पर यह कोशिश की: मैक ओएस एक्स 10.6.8/ओकैमल 3.12.0 और मुझे समस्या दिखाई नहीं दे रही है। दोनों मामलों में उत्पादन समान है। आपका सिस्टम क्या है? –

+0

लिनक्स, मैंने फिर से आदमी 3 getlogin पढ़ा है और मैंने stdin को पुनर्निर्देशित करने के बारे में glibc में "बग" देखा है: -/ – Ricardo

+0

हां, bkconrad इसे नकली! –

उत्तर

5

किसी प्रोग्राम के इनपुट को पुनर्निर्देशित करने से इसके नियंत्रण टर्मिनल को ओवरराइड किया जाता है। एक को नियंत्रित करने के लिए टर्मिनल के बिना, कोई लॉगिन पाया जा सकता है:

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

हालांकि, आप अभी भी एक उपयोगकर्ता का नाम पा सकते हैं (शायद) उपयोगकर्ता के आईडी (getuid) हो रही है और ऊपर देखकर भी उसकी passwd entry (related docs) (getpwuid), फिर इसमें अपना उपयोगकर्ता नाम ढूंढना।

+0

उत्तर प्रक्रिया के यूआईडी से आना चाहिए, नियंत्रण टर्मिनल से नहीं। लेकिन फिर भी यह समस्या हो सकती है। –

+0

मान लीजिए कि यह वास्तविक 'getlogin' (http://linux.die.net/man/3/getlogin) कहता है, तो वास्तव में, यह नियंत्रण टर्मिनल से आता है। – bkconrad

+0

वाह। बीएसडी (और मैक ओएस एक्स) पर, जब आप लॉग इन करते हैं तो यह एक अलग मूल्य सेट होता है। यह मुझे अपेक्षित रूप से getuid() या geteuid() पर आधारित नहीं है, लेकिन टर्मिनल को नियंत्रित करने पर भी नहीं। मेरे लिए थोड़ा बेहतर लगता है। –

3

आपके आवेदन पर निर्भर करता है:

  • यदि आप वास्तव में "getlogin" द्वारा दिए गए मान के बारे में परवाह नहीं है, आप की तरह कुछ कर सकते हैं:

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

    आप शायद कुछ मिल जाएगा getuid से बेहतर, क्योंकि यह सेट-यूजर-आईडी फ्लैग (सूडो/सु) वाले प्रोग्राम के लिए भी काम करेगा।

  • यदि आप वास्तव में "getlogin" द्वारा लौटाए गए मूल्य की परवाह करते हैं, यानी आप वास्तव में जानना चाहते हैं कि कौन लॉग इन है, तो आपको Getlogin विफल होने पर बस विफल होना चाहिए। कोई अन्य समाधान आपको केवल सही परिणाम का अनुमान लगाएगा।