blob: 9810c77bc833917c9e4f31e9a7adbb9ca04725aa [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Walter Dörwald21d3a322003-05-01 17:45:56 +00003from test import test_support
Neal Norwitze241ce82003-02-17 18:17:05 +00004
R. David Murray95fb46c2009-04-21 13:06:04 +00005# Skip these tests if there is no posix module.
6posix = test_support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008import errno
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Charles-François Natalif8387642012-04-17 19:46:06 +020012import platform
Gregory P. Smithf48da8f2008-03-18 19:05:32 +000013import pwd
Facundo Batista5596b0c2008-06-22 13:36:20 +000014import shutil
Ned Deily43e10542011-06-27 23:41:53 -070015import stat
Stefan Krah182ae642010-07-13 19:17:08 +000016import sys
Ned Deilyd88131a2011-07-26 13:52:14 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
R. David Murray59beec32009-03-30 19:04:00 +000020
Ned Deilyd88131a2011-07-26 13:52:14 -070021_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
22 test_support.TESTFN + '-dummy-symlink')
R. David Murray59beec32009-03-30 19:04:00 +000023
Neal Norwitze241ce82003-02-17 18:17:05 +000024warnings.filterwarnings('ignore', '.* potential security risk .*',
25 RuntimeWarning)
26
27class PosixTester(unittest.TestCase):
28
29 def setUp(self):
30 # create empty file
Walter Dörwald21d3a322003-05-01 17:45:56 +000031 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000032 fp.close()
Ned Deily43e10542011-06-27 23:41:53 -070033 self.teardown_files = [ test_support.TESTFN ]
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily43e10542011-06-27 23:41:53 -070036 for teardown_file in self.teardown_files:
37 os.unlink(teardown_file)
Neal Norwitze241ce82003-02-17 18:17:05 +000038
39 def testNoArgFunctions(self):
40 # test posix functions which take no arguments and have
41 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
42 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname",
Neal Norwitz71b13e82003-02-23 22:12:24 +000043 "times", "getloadavg", "tmpnam",
Neal Norwitze241ce82003-02-17 18:17:05 +000044 "getegid", "geteuid", "getgid", "getgroups",
45 "getpid", "getpgrp", "getppid", "getuid",
46 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000047
Antoine Pitroub0614612011-01-02 20:04:52 +000048 with warnings.catch_warnings():
49 warnings.filterwarnings("ignore", "", DeprecationWarning)
50 for name in NO_ARG_FUNCTIONS:
51 posix_func = getattr(posix, name, None)
52 if posix_func is not None:
53 posix_func()
54 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020056 @unittest.skipUnless(hasattr(posix, 'getresuid'),
57 'test needs posix.getresuid()')
58 def test_getresuid(self):
59 user_ids = posix.getresuid()
60 self.assertEqual(len(user_ids), 3)
61 for val in user_ids:
62 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000063
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020064 @unittest.skipUnless(hasattr(posix, 'getresgid'),
65 'test needs posix.getresgid()')
66 def test_getresgid(self):
67 group_ids = posix.getresgid()
68 self.assertEqual(len(group_ids), 3)
69 for val in group_ids:
70 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000071
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020072 @unittest.skipUnless(hasattr(posix, 'setresuid'),
73 'test needs posix.setresuid()')
74 def test_setresuid(self):
75 current_user_ids = posix.getresuid()
76 self.assertIsNone(posix.setresuid(*current_user_ids))
77 # -1 means don't change that value.
78 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000079
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020080 @unittest.skipUnless(hasattr(posix, 'setresuid'),
81 'test needs posix.setresuid()')
82 def test_setresuid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_user_ids = posix.getresuid()
85 if 0 not in current_user_ids:
86 new_user_ids = (current_user_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000088
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020089 @unittest.skipUnless(hasattr(posix, 'setresgid'),
90 'test needs posix.setresgid()')
91 def test_setresgid(self):
92 current_group_ids = posix.getresgid()
93 self.assertIsNone(posix.setresgid(*current_group_ids))
94 # -1 means don't change that value.
95 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000096
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020097 @unittest.skipUnless(hasattr(posix, 'setresgid'),
98 'test needs posix.setresgid()')
99 def test_setresgid_exception(self):
100 # Don't do this test if someone is silly enough to run us as root.
101 current_group_ids = posix.getresgid()
102 if 0 not in current_group_ids:
103 new_group_ids = (current_group_ids[0]+1, -1, -1)
104 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +0000105
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000106 @unittest.skipUnless(hasattr(posix, 'initgroups'),
107 "test needs os.initgroups()")
108 def test_initgroups(self):
109 # It takes a string and an integer; check that it raises a TypeError
110 # for other argument lists.
111 self.assertRaises(TypeError, posix.initgroups)
112 self.assertRaises(TypeError, posix.initgroups, None)
113 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
115
116 # If a non-privileged user invokes it, it should fail with OSError
117 # EPERM.
118 if os.getuid() != 0:
Charles-François Natali666a5732012-05-02 20:00:37 +0200119 try:
120 name = pwd.getpwuid(posix.getuid()).pw_name
121 except KeyError:
122 # the current UID may not have a pwd entry
123 raise unittest.SkipTest("need a pwd entry")
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000124 try:
125 posix.initgroups(name, 13)
126 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000127 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000128 else:
129 self.fail("Expected OSError to be raised by initgroups")
130
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200131 @unittest.skipUnless(hasattr(posix, 'statvfs'),
132 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 def test_statvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200134 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000135
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
137 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 def test_fstatvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200139 fp = open(test_support.TESTFN)
140 try:
141 self.assertTrue(posix.fstatvfs(fp.fileno()))
142 finally:
143 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000144
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200145 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
146 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 def test_ftruncate(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200148 fp = open(test_support.TESTFN, 'w+')
149 try:
150 # we need to have some data to truncate
151 fp.write('test')
152 fp.flush()
153 posix.ftruncate(fp.fileno(), 0)
154 finally:
155 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000156
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200157 @unittest.skipUnless(hasattr(posix, 'dup'),
158 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000159 def test_dup(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200160 fp = open(test_support.TESTFN)
161 try:
162 fd = posix.dup(fp.fileno())
163 self.assertIsInstance(fd, int)
164 os.close(fd)
165 finally:
166 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000167
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200168 @unittest.skipUnless(hasattr(posix, 'confstr'),
169 'test needs posix.confstr()')
Skip Montanaro94785ef2006-04-20 01:29:48 +0000170 def test_confstr(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200171 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
172 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Skip Montanaro94785ef2006-04-20 01:29:48 +0000173
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200174 @unittest.skipUnless(hasattr(posix, 'dup2'),
175 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000176 def test_dup2(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200177 fp1 = open(test_support.TESTFN)
178 fp2 = open(test_support.TESTFN)
179 try:
180 posix.dup2(fp1.fileno(), fp2.fileno())
181 finally:
182 fp1.close()
183 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000184
185 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000186 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000187 fp2 = posix.fdopen(fd, *args)
188 fp2.close()
189
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200190 @unittest.skipUnless(hasattr(posix, 'fdopen'),
191 'test needs posix.fdopen()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000192 def test_fdopen(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200193 self.fdopen_helper()
194 self.fdopen_helper('r')
195 self.fdopen_helper('r', 100)
Neal Norwitze241ce82003-02-17 18:17:05 +0000196
Benjamin Petersone3737542014-08-24 10:37:12 -0500197 @unittest.skipUnless(hasattr(posix, 'fdopen'),
198 'test needs posix.fdopen()')
199 def test_fdopen_directory(self):
200 try:
201 fd = os.open('.', os.O_RDONLY)
202 except OSError as e:
203 self.assertEqual(e.errno, errno.EACCES)
204 self.skipTest("system cannot open directories")
205 with self.assertRaises(IOError) as cm:
206 os.fdopen(fd, 'r')
207 self.assertEqual(cm.exception.errno, errno.EISDIR)
208
Benjamin Peterson15773c82014-05-17 16:07:53 -0700209 @unittest.skipUnless(hasattr(posix, 'fdopen') and
Benjamin Peterson5918f8f2014-05-17 16:33:59 -0700210 not sys.platform.startswith("sunos"),
Benjamin Peterson15773c82014-05-17 16:07:53 -0700211 'test needs posix.fdopen()')
212 def test_fdopen_keeps_fd_open_on_errors(self):
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400213 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Benjamin Peterson15773c82014-05-17 16:07:53 -0700214 self.assertRaises(OSError, posix.fdopen, fd, 'w')
Benjamin Peterson5c863bf2014-04-14 19:45:46 -0400215 os.close(fd) # fd should not be closed.
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400216
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200217 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
218 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000219 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200220 fd = os.open(test_support.TESTFN,
221 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
222 self.assertRaises(OSError, os.open, test_support.TESTFN,
223 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
224 os.close(fd)
225
226 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000227 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200228 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000229 self.assertRaises(OSError, os.open, test_support.TESTFN,
230 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
231 os.close(fd)
232
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200233 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
234 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000235 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200236 fd1 = os.open(test_support.TESTFN,
237 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
238 fd2 = os.open(test_support.TESTFN,
239 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
240 os.close(fd2)
241 os.close(fd1)
242
243 if hasattr(posix, "O_EXLOCK"):
244 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000245 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200246 self.assertRaises(OSError, os.open, test_support.TESTFN,
247 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
248 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000249
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200250 @unittest.skipUnless(hasattr(posix, 'fstat'),
251 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000252 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200253 fp = open(test_support.TESTFN)
254 try:
255 self.assertTrue(posix.fstat(fp.fileno()))
256 finally:
257 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000258
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200259 @unittest.skipUnless(hasattr(posix, 'stat'),
260 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000261 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200262 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000263
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300264 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
265 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
266 def test_makedev(self):
267 st = posix.stat(test_support.TESTFN)
268 dev = st.st_dev
269 self.assertIsInstance(dev, (int, long))
270 self.assertGreaterEqual(dev, 0)
271
272 major = posix.major(dev)
273 self.assertIsInstance(major, (int, long))
274 self.assertGreaterEqual(major, 0)
275 self.assertEqual(posix.major(int(dev)), major)
276 self.assertEqual(posix.major(long(dev)), major)
277 self.assertRaises(TypeError, posix.major, float(dev))
278 self.assertRaises(TypeError, posix.major)
279 self.assertRaises((ValueError, OverflowError), posix.major, -1)
280
281 minor = posix.minor(dev)
282 self.assertIsInstance(minor, (int, long))
283 self.assertGreaterEqual(minor, 0)
284 self.assertEqual(posix.minor(int(dev)), minor)
285 self.assertEqual(posix.minor(long(dev)), minor)
286 self.assertRaises(TypeError, posix.minor, float(dev))
287 self.assertRaises(TypeError, posix.minor)
288 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
289
290 self.assertEqual(posix.makedev(major, minor), dev)
291 self.assertEqual(posix.makedev(int(major), int(minor)), dev)
292 self.assertEqual(posix.makedev(long(major), long(minor)), dev)
293 self.assertRaises(TypeError, posix.makedev, float(major), minor)
294 self.assertRaises(TypeError, posix.makedev, major, float(minor))
295 self.assertRaises(TypeError, posix.makedev, major)
296 self.assertRaises(TypeError, posix.makedev)
297
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200298 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000299 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200300 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200301 if stat_func is not None:
302 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200303 self.assertEqual(stat.st_uid, uid)
304 self.assertEqual(stat.st_gid, gid)
305 uid = os.getuid()
306 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200307 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200308 chown_func(first_param, uid, gid)
309 check_stat(uid, gid)
310 chown_func(first_param, -1, gid)
311 check_stat(uid, gid)
312 chown_func(first_param, uid, -1)
313 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200314
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200315 if uid == 0:
316 # Try an amusingly large uid/gid to make sure we handle
317 # large unsigned values. (chown lets you use any
318 # uid/gid you like, even if they aren't defined.)
319 #
320 # This problem keeps coming up:
321 # http://bugs.python.org/issue1747858
322 # http://bugs.python.org/issue4591
323 # http://bugs.python.org/issue15301
324 # Hopefully the fix in 4591 fixes it for good!
325 #
326 # This part of the test only runs when run as root.
327 # Only scary people run their tests as root.
328
329 big_value = 2**31
330 chown_func(first_param, big_value, big_value)
331 check_stat(big_value, big_value)
332 chown_func(first_param, -1, -1)
333 check_stat(big_value, big_value)
334 chown_func(first_param, uid, gid)
335 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200336 elif platform.system() in ('HP-UX', 'SunOS'):
337 # HP-UX and Solaris can allow a non-root user to chown() to root
338 # (issue #5113)
339 raise unittest.SkipTest("Skipping because of non-standard chown() "
340 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000341 else:
342 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200343 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200344 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200345 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200346 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200347 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200348 self.assertRaises(OSError, chown_func, first_param, -1, 0)
349 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200350 # test illegal types
351 for t in str, float:
352 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
353 check_stat(uid, gid)
354 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
355 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000356
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000357 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
358 def test_chown(self):
359 # raise an OSError if the file does not exist
360 os.unlink(test_support.TESTFN)
361 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
362
363 # re-create the file
364 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200365 self._test_all_chown_common(posix.chown, test_support.TESTFN,
366 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000367
368 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
369 def test_fchown(self):
370 os.unlink(test_support.TESTFN)
371
372 # re-create the file
373 test_file = open(test_support.TESTFN, 'w')
374 try:
375 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200376 self._test_all_chown_common(posix.fchown, fd,
377 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000378 finally:
379 test_file.close()
380
381 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
382 def test_lchown(self):
383 os.unlink(test_support.TESTFN)
384 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700385 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200386 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
387 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000388
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200389 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000390 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200391 posix.chdir(os.curdir)
392 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000393
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200394 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000395 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200396 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000397
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200398 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000399 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200400 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000401
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200402 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000403 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200404 old_mask = posix.umask(0)
405 self.assertIsInstance(old_mask, int)
406 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000407
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200408 @unittest.skipUnless(hasattr(posix, 'strerror'),
409 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000410 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200411 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000412
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200413 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000414 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200415 reader, writer = posix.pipe()
416 os.close(reader)
417 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000418
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200419 @unittest.skipUnless(hasattr(posix, 'tempnam'),
420 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000421 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200422 with warnings.catch_warnings():
423 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
424 self.assertTrue(posix.tempnam())
425 self.assertTrue(posix.tempnam(os.curdir))
426 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000427
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200428 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
429 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000430 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200431 with warnings.catch_warnings():
432 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
433 fp = posix.tmpfile()
434 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000435
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200436 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000437 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200438 now = time.time()
439 posix.utime(test_support.TESTFN, None)
440 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
441 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
442 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
443 posix.utime(test_support.TESTFN, (int(now), int(now)))
444 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000445
Ned Deily43e10542011-06-27 23:41:53 -0700446 def _test_chflags_regular_file(self, chflags_func, target_file):
447 st = os.stat(target_file)
448 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100449
450 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
451 try:
452 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
453 except OSError as err:
454 if err.errno != errno.EOPNOTSUPP:
455 raise
456 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
457 self.skipTest(msg)
458
Ned Deily43e10542011-06-27 23:41:53 -0700459 try:
460 new_st = os.stat(target_file)
461 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
462 try:
463 fd = open(target_file, 'w+')
464 except IOError as e:
465 self.assertEqual(e.errno, errno.EPERM)
466 finally:
467 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000468
Ned Deily43e10542011-06-27 23:41:53 -0700469 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
470 def test_chflags(self):
471 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
472
473 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
474 def test_lchflags_regular_file(self):
475 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
476
477 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
478 def test_lchflags_symlink(self):
479 testfn_st = os.stat(test_support.TESTFN)
480
481 self.assertTrue(hasattr(testfn_st, 'st_flags'))
482
483 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
484 self.teardown_files.append(_DUMMY_SYMLINK)
485 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
486
Victor Stinner8c7c6972012-12-04 10:07:16 +0100487 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
488 try:
489 posix.lchflags(_DUMMY_SYMLINK,
490 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
491 except OSError as err:
492 if err.errno != errno.EOPNOTSUPP:
493 raise
494 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
495 self.skipTest(msg)
496
Ned Deily43e10542011-06-27 23:41:53 -0700497 try:
498 new_testfn_st = os.stat(test_support.TESTFN)
499 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
500
501 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
502 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
503 new_dummy_symlink_st.st_flags)
504 finally:
505 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000506
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200507 @unittest.skipUnless(hasattr(posix, 'getcwd'),
508 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000509 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200510 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
511 curdir = os.getcwd()
512 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000513
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200514 try:
515 os.mkdir(base_path)
516 os.chdir(base_path)
517 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600518 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000519
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200520 try:
521 def _create_and_do_getcwd(dirname, current_path_length = 0):
522 try:
523 os.mkdir(dirname)
524 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600525 self.skipTest("mkdir cannot create directory sufficiently "
526 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000527
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200528 os.chdir(dirname)
529 try:
530 os.getcwd()
531 if current_path_length < 4099:
532 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
533 except OSError as e:
534 expected_errno = errno.ENAMETOOLONG
535 # The following platforms have quirky getcwd()
536 # behaviour -- see issue 9185 and 15765 for
537 # more information.
538 quirky_platform = (
539 'sunos' in sys.platform or
540 'netbsd' in sys.platform or
541 'openbsd' in sys.platform
542 )
543 if quirky_platform:
544 expected_errno = errno.ERANGE
545 self.assertEqual(e.errno, expected_errno)
546 finally:
547 os.chdir('..')
548 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000549
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200550 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000551
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200552 finally:
553 os.chdir(curdir)
554 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000555
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000556 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000557 def test_getgroups(self):
Jesus Ceafd3ba7b2014-06-28 18:39:01 +0200558 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000559 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200560 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000561
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200562 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000563 raise unittest.SkipTest("need working 'id -G'")
564
Ned Deilycc23cc62013-02-02 15:06:45 -0800565 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
566 if sys.platform == 'darwin':
567 import sysconfig
568 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily1f70b872014-06-25 13:33:57 -0700569 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deilycc23cc62013-02-02 15:06:45 -0800570 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
571
Ronald Oussorenac72e582010-08-03 07:31:12 +0000572 # 'id -G' and 'os.getgroups()' should return the same
573 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000574 # #10822 - it is implementation defined whether posix.getgroups()
575 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000576 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000577 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000578 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000579
580class PosixGroupsTester(unittest.TestCase):
581
582 def setUp(self):
583 if posix.getuid() != 0:
584 raise unittest.SkipTest("not enough privileges")
585 if not hasattr(posix, 'getgroups'):
586 raise unittest.SkipTest("need posix.getgroups")
587 if sys.platform == 'darwin':
588 raise unittest.SkipTest("getgroups(2) is broken on OSX")
589 self.saved_groups = posix.getgroups()
590
591 def tearDown(self):
592 if hasattr(posix, 'setgroups'):
593 posix.setgroups(self.saved_groups)
594 elif hasattr(posix, 'initgroups'):
595 name = pwd.getpwuid(posix.getuid()).pw_name
596 posix.initgroups(name, self.saved_groups[0])
597
598 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200599 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000600 def test_initgroups(self):
601 # find missing group
602
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500603 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000604 name = pwd.getpwuid(posix.getuid()).pw_name
605 posix.initgroups(name, g)
606 self.assertIn(g, posix.getgroups())
607
608 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200609 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000610 def test_setgroups(self):
611 for groups in [[0], range(16)]:
612 posix.setgroups(groups)
613 self.assertListEqual(groups, posix.getgroups())
614
Facundo Batista5596b0c2008-06-22 13:36:20 +0000615
Neal Norwitze241ce82003-02-17 18:17:05 +0000616def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000617 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000618
619if __name__ == '__main__':
620 test_main()