2012-03-20 22 views
6

tôi phát hiện ra vấn đề tiếp theo trong mã đơn giản này:OCaml: ngoại lệ bất ngờ với Unix.getlogin khi stdin chuyển hướng

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

Chạy trong trường hợp bình thường, với ./a.out cho:

Hello 
ricardo 

Nhưng chạy như ./a.out </dev/null khiến Unix.getlogin không thành công:

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

Bất kỳ id nào ea tại sao điều này xảy ra?

+0

Tôi vừa thử trên hệ thống của mình: Mac OS X 10.6.8/OCaml 3.12.0 và tôi không thấy sự cố. Đầu ra là như nhau trong cả hai trường hợp. Hệ thống của bạn là gì? –

+0

Linux, tôi đã đọc một lần nữa người đàn ông 3 getlogin và tôi thấy "lỗi" trong glibc về chuyển hướng các stdin: -/ – Ricardo

+0

Có, bkconrad đóng đinh nó! –

Trả lời

5

Chuyển hướng đầu vào của chương trình sẽ ghi đè đầu cuối điều khiển của chương trình. Nếu không có một thiết bị đầu cuối kiểm soát, không có đăng nhập để được tìm thấy:

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

Bạn có thể, tuy nhiên, vẫn thấy tên của người dùng (có lẽ) bằng cách id của người dùng (getuid) và nhìn lên passwd entry (related docs) (getpwuid) của mình, sau đó tìm tên người dùng của mình trong đó.

+0

Câu trả lời phải đến từ uid của quá trình, không phải từ thiết bị đầu cuối điều khiển. Nhưng điều này vẫn có thể là vấn đề. –

+0

Giả sử nó gọi thực tế là 'getlogin' (http://linux.die.net/man/3/getlogin), thì thực tế nó đến từ thiết bị đầu cuối điều khiển. – bkconrad

+0

Chà. Trên BSD (và Mac OS X), đó là một giá trị riêng biệt được thiết lập khi bạn đăng nhập. Nó không dựa trên getuid() hoặc geteuid() như tôi mong đợi, nhưng không phải trên thiết bị đầu cuối điều khiển. Có vẻ tốt hơn một chút với tôi. –

3

Tùy thuộc vào ứng dụng của bạn:

  • nếu bạn không thực sự quan tâm đến giá trị trả về bởi "getlogin", bạn có thể làm điều gì đó như:

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

    có thể bạn sẽ có được một cái gì đó tốt hơn getuid, vì nó cũng sẽ hoạt động đối với các chương trình có cờ Set-User-ID (sudo/su).

  • nếu bạn thực sự quan tâm đến giá trị được trả về bởi "getlogin", tức là bạn thực sự muốn biết ai đã đăng nhập, bạn chỉ nên thất bại khi getlogin không thành công. Bất kỳ giải pháp nào khác sẽ chỉ cung cấp cho bạn một kết quả gần đúng của kết quả chính xác.

Các vấn đề liên quan