blob: df122f712ca1c9288c7857ea53ee85995fc1d7f0 [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 Peterson15773c82014-05-17 16:07:53 -0700197 @unittest.skipUnless(hasattr(posix, 'fdopen') and
Benjamin Peterson5918f8f2014-05-17 16:33:59 -0700198 not sys.platform.startswith("sunos"),
Benjamin Peterson15773c82014-05-17 16:07:53 -0700199 'test needs posix.fdopen()')
200 def test_fdopen_keeps_fd_open_on_errors(self):
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400201 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Benjamin Peterson15773c82014-05-17 16:07:53 -0700202 self.assertRaises(OSError, posix.fdopen, fd, 'w')
Benjamin Peterson5c863bf2014-04-14 19:45:46 -0400203 os.close(fd) # fd should not be closed.
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400204
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200205 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
206 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000207 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200208 fd = os.open(test_support.TESTFN,
209 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
210 self.assertRaises(OSError, os.open, test_support.TESTFN,
211 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
212 os.close(fd)
213
214 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000215 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200216 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000217 self.assertRaises(OSError, os.open, test_support.TESTFN,
218 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
219 os.close(fd)
220
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200221 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
222 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000223 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200224 fd1 = os.open(test_support.TESTFN,
225 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
226 fd2 = os.open(test_support.TESTFN,
227 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
228 os.close(fd2)
229 os.close(fd1)
230
231 if hasattr(posix, "O_EXLOCK"):
232 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000233 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200234 self.assertRaises(OSError, os.open, test_support.TESTFN,
235 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
236 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000237
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200238 @unittest.skipUnless(hasattr(posix, 'fstat'),
239 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000240 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200241 fp = open(test_support.TESTFN)
242 try:
243 self.assertTrue(posix.fstat(fp.fileno()))
244 finally:
245 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000246
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200247 @unittest.skipUnless(hasattr(posix, 'stat'),
248 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000249 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200250 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000251
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200252 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000253 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200254 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200255 if stat_func is not None:
256 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200257 self.assertEqual(stat.st_uid, uid)
258 self.assertEqual(stat.st_gid, gid)
259 uid = os.getuid()
260 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200261 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200262 chown_func(first_param, uid, gid)
263 check_stat(uid, gid)
264 chown_func(first_param, -1, gid)
265 check_stat(uid, gid)
266 chown_func(first_param, uid, -1)
267 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200268
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200269 if uid == 0:
270 # Try an amusingly large uid/gid to make sure we handle
271 # large unsigned values. (chown lets you use any
272 # uid/gid you like, even if they aren't defined.)
273 #
274 # This problem keeps coming up:
275 # http://bugs.python.org/issue1747858
276 # http://bugs.python.org/issue4591
277 # http://bugs.python.org/issue15301
278 # Hopefully the fix in 4591 fixes it for good!
279 #
280 # This part of the test only runs when run as root.
281 # Only scary people run their tests as root.
282
283 big_value = 2**31
284 chown_func(first_param, big_value, big_value)
285 check_stat(big_value, big_value)
286 chown_func(first_param, -1, -1)
287 check_stat(big_value, big_value)
288 chown_func(first_param, uid, gid)
289 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200290 elif platform.system() in ('HP-UX', 'SunOS'):
291 # HP-UX and Solaris can allow a non-root user to chown() to root
292 # (issue #5113)
293 raise unittest.SkipTest("Skipping because of non-standard chown() "
294 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000295 else:
296 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200297 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200298 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200299 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200300 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200301 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200302 self.assertRaises(OSError, chown_func, first_param, -1, 0)
303 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200304 # test illegal types
305 for t in str, float:
306 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
307 check_stat(uid, gid)
308 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
309 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000310
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000311 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
312 def test_chown(self):
313 # raise an OSError if the file does not exist
314 os.unlink(test_support.TESTFN)
315 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
316
317 # re-create the file
318 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200319 self._test_all_chown_common(posix.chown, test_support.TESTFN,
320 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000321
322 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
323 def test_fchown(self):
324 os.unlink(test_support.TESTFN)
325
326 # re-create the file
327 test_file = open(test_support.TESTFN, 'w')
328 try:
329 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200330 self._test_all_chown_common(posix.fchown, fd,
331 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000332 finally:
333 test_file.close()
334
335 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
336 def test_lchown(self):
337 os.unlink(test_support.TESTFN)
338 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700339 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200340 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
341 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000342
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200343 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000344 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200345 posix.chdir(os.curdir)
346 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000347
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200348 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000349 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200350 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000351
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200352 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000353 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200354 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000355
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200356 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000357 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200358 old_mask = posix.umask(0)
359 self.assertIsInstance(old_mask, int)
360 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000361
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200362 @unittest.skipUnless(hasattr(posix, 'strerror'),
363 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000364 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200365 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000366
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200367 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000368 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200369 reader, writer = posix.pipe()
370 os.close(reader)
371 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000372
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200373 @unittest.skipUnless(hasattr(posix, 'tempnam'),
374 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000375 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200376 with warnings.catch_warnings():
377 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
378 self.assertTrue(posix.tempnam())
379 self.assertTrue(posix.tempnam(os.curdir))
380 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000381
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200382 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
383 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000384 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200385 with warnings.catch_warnings():
386 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
387 fp = posix.tmpfile()
388 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000389
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200390 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000391 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200392 now = time.time()
393 posix.utime(test_support.TESTFN, None)
394 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
395 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
396 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
397 posix.utime(test_support.TESTFN, (int(now), int(now)))
398 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000399
Ned Deily43e10542011-06-27 23:41:53 -0700400 def _test_chflags_regular_file(self, chflags_func, target_file):
401 st = os.stat(target_file)
402 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100403
404 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
405 try:
406 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
407 except OSError as err:
408 if err.errno != errno.EOPNOTSUPP:
409 raise
410 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
411 self.skipTest(msg)
412
Ned Deily43e10542011-06-27 23:41:53 -0700413 try:
414 new_st = os.stat(target_file)
415 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
416 try:
417 fd = open(target_file, 'w+')
418 except IOError as e:
419 self.assertEqual(e.errno, errno.EPERM)
420 finally:
421 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000422
Ned Deily43e10542011-06-27 23:41:53 -0700423 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
424 def test_chflags(self):
425 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
426
427 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
428 def test_lchflags_regular_file(self):
429 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
430
431 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
432 def test_lchflags_symlink(self):
433 testfn_st = os.stat(test_support.TESTFN)
434
435 self.assertTrue(hasattr(testfn_st, 'st_flags'))
436
437 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
438 self.teardown_files.append(_DUMMY_SYMLINK)
439 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
440
Victor Stinner8c7c6972012-12-04 10:07:16 +0100441 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
442 try:
443 posix.lchflags(_DUMMY_SYMLINK,
444 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
445 except OSError as err:
446 if err.errno != errno.EOPNOTSUPP:
447 raise
448 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
449 self.skipTest(msg)
450
Ned Deily43e10542011-06-27 23:41:53 -0700451 try:
452 new_testfn_st = os.stat(test_support.TESTFN)
453 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
454
455 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
456 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
457 new_dummy_symlink_st.st_flags)
458 finally:
459 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000460
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200461 @unittest.skipUnless(hasattr(posix, 'getcwd'),
462 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000463 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200464 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
465 curdir = os.getcwd()
466 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000467
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200468 try:
469 os.mkdir(base_path)
470 os.chdir(base_path)
471 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600472 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000473
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200474 try:
475 def _create_and_do_getcwd(dirname, current_path_length = 0):
476 try:
477 os.mkdir(dirname)
478 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600479 self.skipTest("mkdir cannot create directory sufficiently "
480 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000481
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200482 os.chdir(dirname)
483 try:
484 os.getcwd()
485 if current_path_length < 4099:
486 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
487 except OSError as e:
488 expected_errno = errno.ENAMETOOLONG
489 # The following platforms have quirky getcwd()
490 # behaviour -- see issue 9185 and 15765 for
491 # more information.
492 quirky_platform = (
493 'sunos' in sys.platform or
494 'netbsd' in sys.platform or
495 'openbsd' in sys.platform
496 )
497 if quirky_platform:
498 expected_errno = errno.ERANGE
499 self.assertEqual(e.errno, expected_errno)
500 finally:
501 os.chdir('..')
502 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000503
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200504 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000505
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200506 finally:
507 os.chdir(curdir)
508 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000509
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000510 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000511 def test_getgroups(self):
Jesus Ceafd3ba7b2014-06-28 18:39:01 +0200512 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000513 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200514 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000515
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200516 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000517 raise unittest.SkipTest("need working 'id -G'")
518
Ned Deilycc23cc62013-02-02 15:06:45 -0800519 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
520 if sys.platform == 'darwin':
521 import sysconfig
522 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily1f70b872014-06-25 13:33:57 -0700523 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deilycc23cc62013-02-02 15:06:45 -0800524 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
525
Ronald Oussorenac72e582010-08-03 07:31:12 +0000526 # 'id -G' and 'os.getgroups()' should return the same
527 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000528 # #10822 - it is implementation defined whether posix.getgroups()
529 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000530 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000531 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000532 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000533
534class PosixGroupsTester(unittest.TestCase):
535
536 def setUp(self):
537 if posix.getuid() != 0:
538 raise unittest.SkipTest("not enough privileges")
539 if not hasattr(posix, 'getgroups'):
540 raise unittest.SkipTest("need posix.getgroups")
541 if sys.platform == 'darwin':
542 raise unittest.SkipTest("getgroups(2) is broken on OSX")
543 self.saved_groups = posix.getgroups()
544
545 def tearDown(self):
546 if hasattr(posix, 'setgroups'):
547 posix.setgroups(self.saved_groups)
548 elif hasattr(posix, 'initgroups'):
549 name = pwd.getpwuid(posix.getuid()).pw_name
550 posix.initgroups(name, self.saved_groups[0])
551
552 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200553 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000554 def test_initgroups(self):
555 # find missing group
556
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500557 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000558 name = pwd.getpwuid(posix.getuid()).pw_name
559 posix.initgroups(name, g)
560 self.assertIn(g, posix.getgroups())
561
562 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200563 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000564 def test_setgroups(self):
565 for groups in [[0], range(16)]:
566 posix.setgroups(groups)
567 self.assertListEqual(groups, posix.getgroups())
568
Facundo Batista5596b0c2008-06-22 13:36:20 +0000569
Neal Norwitze241ce82003-02-17 18:17:05 +0000570def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000571 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000572
573if __name__ == '__main__':
574 test_main()