Skip to content

Commit 267c79d

Browse files
committed
Fix #982 by using the effective user id on unix systems instead of depending on
getpass.getuser(). This is required because on some systems 'LOGNAME' is not updated by sudo. Signed-off-by: david <[email protected]>
1 parent 499f45d commit 267c79d

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

pip/locations.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ def virtualenv_no_global():
4848
if running_under_virtualenv() and os.path.isfile(no_global_file):
4949
return True
5050

51+
def __get_username():
52+
""" Returns the effective username of the current process. """
53+
if sys.platform == 'win32':
54+
return getpass.getuser()
55+
import pwd
56+
return pwd.getpwuid(os.geteuid()).pw_name
57+
5158
def _get_build_prefix():
5259
""" Returns a safe build_prefix """
53-
path = os.path.join(tempfile.gettempdir(), 'pip-build-%s' % \
54-
getpass.getuser())
60+
path = os.path.join(tempfile.gettempdir(), 'pip-build-%s' %
61+
__get_username())
5562
if sys.platform == 'win32':
5663
""" on windows(tested on 7) temp dirs are isolated """
5764
return path
@@ -66,7 +73,7 @@ def _get_build_prefix():
6673
os.close(fd)
6774
except OSError:
6875
file_uid = None
69-
if file_uid != os.getuid():
76+
if file_uid != os.geteuid():
7077
msg = "The temporary folder for building (%s) is not owned by your user!" \
7178
% path
7279
print (msg)

tests/unit/test_locations.py

+28-8
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@
99
import getpass
1010
from mock import Mock
1111
from nose import SkipTest
12-
from nose.tools import assert_raises
12+
from nose.tools import assert_raises, assert_equal
1313
import pip
1414

15+
if sys.platform == 'win32':
16+
pwd = Mock()
17+
else:
18+
import pwd
19+
20+
1521
class TestLocations:
1622
def setup(self):
1723
self.tempdir = tempfile.mkdtemp()
@@ -28,23 +34,28 @@ def patch(self):
2834
self.tempfile_gettempdir = tempfile.gettempdir
2935
self.old_os_fstat = os.fstat
3036
if sys.platform != 'win32':
31-
# os.getuid not implemented on windows
32-
self.old_os_getuid = os.getuid
37+
# os.geteuid and pwd.getpwuid are not implemented on windows
38+
self.old_os_geteuid = os.geteuid
39+
self.old_pwd_getpwuid = pwd.getpwuid
3340
self.old_getpass_getuser = getpass.getuser
3441

3542
# now patch
3643
tempfile.gettempdir = lambda : self.tempdir
3744
getpass.getuser = lambda : self.username
38-
os.getuid = lambda : self.st_uid
45+
os.geteuid = lambda : self.st_uid
3946
os.fstat = lambda fd : self.get_mock_fstat(fd)
4047

48+
if sys.platform != 'win32':
49+
pwd.getpwuid = lambda uid: self.get_mock_getpwuid(uid)
50+
4151
def revert_patch(self):
4252
""" revert the patches to python methods """
4353
tempfile.gettempdir = self.tempfile_gettempdir
4454
getpass.getuser = self.old_getpass_getuser
4555
if sys.platform != 'win32':
46-
# os.getuid not implemented on windows
47-
os.getuid = self.old_os_getuid
56+
# os.geteuid and pwd.getpwuid are not implemented on windows
57+
os.geteuid = self.old_os_geteuid
58+
pwd.getpwuid = self.old_pwd_getpwuid
4859
os.fstat = self.old_os_fstat
4960

5061
def get_mock_fstat(self, fd):
@@ -55,6 +66,14 @@ def get_mock_fstat(self, fd):
5566
result.st_uid = self.st_uid
5667
return result
5768

69+
def get_mock_getpwuid(self, uid):
70+
""" returns a basic mock pwd.getpwuid call result.
71+
Currently only the pw_name attribute has been set.
72+
"""
73+
result = Mock()
74+
result.pw_name = self.username
75+
return result
76+
5877
def get_build_dir_location(self):
5978
""" returns a string pointing to the
6079
current build_prefix.
@@ -65,7 +84,8 @@ def test_dir_path(self):
6584
""" test the path name for the build_prefix
6685
"""
6786
from pip import locations
68-
assert locations._get_build_prefix() == self.get_build_dir_location()
87+
assert_equal(locations._get_build_prefix(),
88+
self.get_build_dir_location())
6989

7090
def test_dir_created(self):
7191
""" test that the build_prefix directory is generated when
@@ -89,7 +109,7 @@ def test_error_raised_when_owned_by_another(self):
89109
if sys.platform == 'win32':
90110
raise SkipTest()
91111
from pip import locations
92-
os.getuid = lambda : 1111
112+
os.geteuid = lambda : 1111
93113
os.mkdir(self.get_build_dir_location() )
94114
assert_raises(pip.exceptions.InstallationError, locations._get_build_prefix)
95115

0 commit comments

Comments
 (0)