Opened 10 years ago

Last modified 18 months ago

#1487 new bug

unix package: test needed for getLoginName

Reported by: simonmar Owned by:
Priority: lowest Milestone:
Component: Core Libraries Version:
Keywords: Cc: adrien@…, core-libraries-committee@…
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Test Case:
Blocked By: Blocking:
Related Tickets: #8293 Differential Rev(s):
Wiki Page:

Description

I disabled the test for getLoginName in unix/tests/user001 because getLoginName cannot be called unless stdin is a terminal, which it isn't during an unattended build. Perhaps we can test this by setting up a pseudoterminal first, but that requires the pty patches which aren't in yet.

Attachments (1)

0001-Enable-test-for-getLoginName.patch (3.1 KB) - added by thomie 3 years ago.

Download all attachments as: .zip

Change History (30)

comment:1 Changed 9 years ago by igloo

Milestone: 6.8 branchNot GHC

comment:2 Changed 8 years ago by simonmar

Architecture: UnknownUnknown/Multiple

comment:3 Changed 8 years ago by simonmar

Operating System: UnknownUnknown/Multiple

comment:4 Changed 7 years ago by simonmar

difficulty: Easy (1 hr)Easy (less than 1 hour)

comment:5 Changed 6 years ago by igloo

Milestone: Not GHC7.4.1
Type of failure: None/Unknown

comment:6 Changed 5 years ago by igloo

Milestone: 7.4.17.6.1
Priority: lowlowest

comment:7 Changed 5 years ago by adrien

Hello,

What are the pty patches? are they in now? If not, is there a related ticket that needs to be solved first?

comment:8 Changed 5 years ago by adrien

Cc: adrien@… added
Owner: set to adrien

comment:9 Changed 5 years ago by simonmar

The pty patches have been in for some time.

comment:10 Changed 5 years ago by adrien

Thank you. I realize now I should have read the commit logs of the unix lib before naively asking, I may have found the answer there.

It can take me some time to fix this, as I need to become familiar with the code and the workflow, but I think this is a good place to start.

comment:11 Changed 4 years ago by igloo

Milestone: 7.6.17.6.2

comment:12 Changed 4 years ago by adrien

Hello,

Strangely, the issue doesn't seem to occur anymore. I am using ghc 7.7.20121207 on Arch Linux 64 bits (cloned it today).

After uncommenting the line for getLoginName, I:

  • loaded it in ghci, and run main: ok
  • compiled user001.hs and run it locally: ok
  • ran the testsuite without modifying user001.stdout, to check I edited the right file: got a difference with user001.stdout, what I expected
  • added the line 'getLoginName: OK' after getGroups, ran the test suite: ok

I did the same for getUserEntryForName, no error.

I cannot reproduce the bug. Is there another to test it, or shall we conclude that the bug disappeared?

Kind regards, Adrien

comment:13 Changed 4 years ago by igloo

It still fails for me:

$ make CLEANUP=1 TEST=user001
[...]
=====> user001(normal) 5 of 28 [0, 0, 0]
cd . && '/home/ian/ghc/git/ghc/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -o user001 user001.hs  -package unix  >user001.comp.stderr 2>&1
cd . && ./user001    </dev/null >user001.run.stdout 2>user001.run.stderr
Actual stdout output differs from expected:
--- ./user001.stdout    2011-04-01 14:32:07.000000000 +0100
+++ ./user001.run.stdout        2012-12-08 17:05:06.000000000 +0000
@@ -3,6 +3,7 @@
 getEffectiveUserID: OK
 getEffectiveGroupID: OK
 getGroups: OK
+getLoginName: ERROR: getLoginName: illegal operation (Inappropriate ioctl for device)
 getEffectiveUserName: OK
 getGroupEntryForID: OK
 getGroupEntryForName: OK
*** unexpected failure for user001(normal)
[...]

comment:14 Changed 4 years ago by adrien

Thanks for the feedback.

It eludes me why it works on my linux and not yours. On which platform did you run the test? I can install it in a virtual machine and see if I can reproduce it. I am not of great help if I can't reproduce it.

I could then try to use getlogin_r, maybe the problem is in the code and not in the test. Or strace the test and get more info on the error.

comment:15 Changed 4 years ago by igloo

I used Debian amd64/Linux.

comment:16 Changed 4 years ago by adrien

Thanks. I installed Debian 6.0.6 amd64 in a virtual machine and I can reproduce it.

comment:17 Changed 4 years ago by morabbin

Operating System: Unknown/MultipleLinux
Type of failure: None/UnknownIncorrect result at runtime

comment:18 Changed 3 years ago by thomie

Owner: changed from adrien to thomie

Changed 3 years ago by thomie

comment:19 Changed 3 years ago by thomie

The attached patch fixes this issue.

I tried going the pseudo-terminal route, but it doesn't work.

System.Posix.User's getLoginName calls the C function getlogin. This function, on GNU/Linux at least, looks in the file /var/run/utmp for a login record with a tty name that matches that of the terminal connected to stdin (filedescriptor 0).

It is possible to trick getlogin to check a pseudo terminal's name with something like:

(master, slave) <- openPseudoTerminal dupTo master stdInput

But, as far as I understand, pseudo-terminals are never registered in /var/run/utmp. Therefore getlogin will not find the user's login name and just return 'No such file or directory'. Maybe better than 'Inappropriate ioctl for device', but still an error.

What does work, surprisingly, is adding this to user001.hs:

dupTo stdOutput stdInput

, but only if we wouldn't redirect stdout as well. The same for stderr.

The solution is to simply not redirect stdin (i.e. don't do ./user001 < /dev/null). This implies skipping the ghci way. The commit that introduced the no_stdin test option alluded to this as well: fa52a8c9d8eae5e3fc4c0cf0e5672875e161e05c.

One general concern is that there are no guarantees that getlogin will return anything other than NULL, so the test with this patch applied might fail on some systems. Another option therefore would be to turn the getLoginName test back off again, document why, and close this issue regardless.

Review of patch requested.

Last edited 3 years ago by thomie (previous) (diff)

comment:20 Changed 3 years ago by thomie

Milestone: 7.6.2
Status: newpatch
Version: 6.6.1

comment:21 Changed 3 years ago by thomie

comment:22 Changed 3 years ago by thomie

Resolution: fixed
Status: patchclosed

Merged in unix package:

Enable test for getLoginName

Fixes #1487.

Make use of no_stdin test option, introduced explictly for this purpose in fa52a8c9d8eae5e3fc4c0cf0e5672875e161e05c

comment:23 Changed 3 years ago by ezyang

Owner: thomie deleted
Resolution: fixed
Status: closednew

Hello, the test is still failing for me, using GHC HEAD and the latest version of unix:

=====> user001(normal) 5 of 29 [0, 0, 0]
cd . && '/5playpen/t-edyang/ghc-master/inplace/bin/ghc-stage2' -fforce-recomp -dcore-lint -dcmm-lint -dno-debug-output -no-user-package-db -rtsopts -fno-ghci-history -o user001 user001.hs  -package unix  >user001.comp.stderr 2>&1
cd . && ./user001    >user001.run.stdout 2>user001.run.stderr
Actual stdout output differs from expected:
--- ./user001.stdout    2014-08-22 23:28:41.969906580 +0100
+++ ./user001.run.stdout        2014-08-23 00:33:07.631841764 +0100
@@ -3,11 +3,11 @@
 getEffectiveUserID: OK
 getEffectiveGroupID: OK
 getGroups: OK
-getLoginName: OK
+getLoginName: ERROR: getLoginName: does not exist (No such file or directory)
 getEffectiveUserName: OK
 getGroupEntryForID: OK
 getGroupEntryForName: OK
 getAllGroupEntries: OK
 getUserEntryForID: OK
-getUserEntryForName: OK
+getUserEntryForName: ERROR: getLoginName: does not exist (No such file or directory)
 getAllUserEntries: OK
*** unexpected failure for user001(normal)

Unexpected results from:
TEST="user001"

On my box, running the following C program in terminal returns null:

#include <stdio.h>
#include <unistd.h>
int main() {
    printf("%p\n", getlogin());
}

This StackOverflow post suggests that getlogin works quite unreliably: http://stackoverflow.com/questions/4785126/getlogin-c-function-returns-null-and-error-no-such-file-or-directory

comment:24 Changed 3 years ago by thomie

@ezyang: which terminal emulator are you using? Does it work with xterm?

Maybe we should change the signature of getLoginName to:

getLoginName :: IO (Maybe String)

, since the man page explicitly mentions that getlogin can return NULL:

getlogin() returns a pointer to a string containing the name of the
user logged in on the controlling terminal of the process, or a NULL
pointer if this information cannot be determined.

The same applies to getGroupEntryForID, ticket #8293.

comment:25 Changed 3 years ago by ezyang

From a cygwin terminal, I am moshed into a screen session. I can't easily test xterm because I don't have X forwarding.

comment:26 Changed 2 years ago by thomie

A library proposal to solve this. The test has been disabled again for the time being.

comment:27 Changed 2 years ago by thoughtpolice

Component: libraries/unixCore Libraries
Owner: set to ekmett

Moving over to new owning component 'Core Libraries'.

comment:28 Changed 2 years ago by argiopeweb

Cc: core-libraries-committee@… added

comment:29 Changed 18 months ago by thomie

Owner: ekmett deleted
Note: See TracTickets for help on using tickets.