blob: 3f44aa37fa74a3a8a0282aa51ef6b03125325757 [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 Storchakada5c2a02013-02-12 09:27:53 +0200264 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000265 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200266 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200267 if stat_func is not None:
268 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200269 self.assertEqual(stat.st_uid, uid)
270 self.assertEqual(stat.st_gid, gid)
271 uid = os.getuid()
272 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200273 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200274 chown_func(first_param, uid, gid)
275 check_stat(uid, gid)
276 chown_func(first_param, -1, gid)
277 check_stat(uid, gid)
278 chown_func(first_param, uid, -1)
279 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200280
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200281 if uid == 0:
282 # Try an amusingly large uid/gid to make sure we handle
283 # large unsigned values. (chown lets you use any
284 # uid/gid you like, even if they aren't defined.)
285 #
286 # This problem keeps coming up:
287 # http://bugs.python.org/issue1747858
288 # http://bugs.python.org/issue4591
289 # http://bugs.python.org/issue15301
290 # Hopefully the fix in 4591 fixes it for good!
291 #
292 # This part of the test only runs when run as root.
293 # Only scary people run their tests as root.
294
295 big_value = 2**31
296 chown_func(first_param, big_value, big_value)
297 check_stat(big_value, big_value)
298 chown_func(first_param, -1, -1)
299 check_stat(big_value, big_value)
300 chown_func(first_param, uid, gid)
301 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200302 elif platform.system() in ('HP-UX', 'SunOS'):
303 # HP-UX and Solaris can allow a non-root user to chown() to root
304 # (issue #5113)
305 raise unittest.SkipTest("Skipping because of non-standard chown() "
306 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000307 else:
308 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200309 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200310 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200311 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200312 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200313 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200314 self.assertRaises(OSError, chown_func, first_param, -1, 0)
315 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200316 # test illegal types
317 for t in str, float:
318 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
319 check_stat(uid, gid)
320 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
321 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000322
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000323 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
324 def test_chown(self):
325 # raise an OSError if the file does not exist
326 os.unlink(test_support.TESTFN)
327 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
328
329 # re-create the file
330 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200331 self._test_all_chown_common(posix.chown, test_support.TESTFN,
332 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000333
334 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
335 def test_fchown(self):
336 os.unlink(test_support.TESTFN)
337
338 # re-create the file
339 test_file = open(test_support.TESTFN, 'w')
340 try:
341 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200342 self._test_all_chown_common(posix.fchown, fd,
343 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000344 finally:
345 test_file.close()
346
347 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
348 def test_lchown(self):
349 os.unlink(test_support.TESTFN)
350 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700351 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200352 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
353 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000354
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200355 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000356 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200357 posix.chdir(os.curdir)
358 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000359
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200360 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000361 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200362 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000363
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200364 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000365 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200366 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000367
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200368 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000369 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200370 old_mask = posix.umask(0)
371 self.assertIsInstance(old_mask, int)
372 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000373
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200374 @unittest.skipUnless(hasattr(posix, 'strerror'),
375 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000376 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200377 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000378
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200379 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000380 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200381 reader, writer = posix.pipe()
382 os.close(reader)
383 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000384
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200385 @unittest.skipUnless(hasattr(posix, 'tempnam'),
386 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000387 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200388 with warnings.catch_warnings():
389 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
390 self.assertTrue(posix.tempnam())
391 self.assertTrue(posix.tempnam(os.curdir))
392 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000393
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200394 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
395 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000396 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200397 with warnings.catch_warnings():
398 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
399 fp = posix.tmpfile()
400 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000401
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200402 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000403 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200404 now = time.time()
405 posix.utime(test_support.TESTFN, None)
406 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
407 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
408 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
409 posix.utime(test_support.TESTFN, (int(now), int(now)))
410 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000411
Ned Deily43e10542011-06-27 23:41:53 -0700412 def _test_chflags_regular_file(self, chflags_func, target_file):
413 st = os.stat(target_file)
414 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100415
416 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
417 try:
418 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
419 except OSError as err:
420 if err.errno != errno.EOPNOTSUPP:
421 raise
422 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
423 self.skipTest(msg)
424
Ned Deily43e10542011-06-27 23:41:53 -0700425 try:
426 new_st = os.stat(target_file)
427 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
428 try:
429 fd = open(target_file, 'w+')
430 except IOError as e:
431 self.assertEqual(e.errno, errno.EPERM)
432 finally:
433 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000434
Ned Deily43e10542011-06-27 23:41:53 -0700435 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
436 def test_chflags(self):
437 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
438
439 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
440 def test_lchflags_regular_file(self):
441 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
442
443 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
444 def test_lchflags_symlink(self):
445 testfn_st = os.stat(test_support.TESTFN)
446
447 self.assertTrue(hasattr(testfn_st, 'st_flags'))
448
449 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
450 self.teardown_files.append(_DUMMY_SYMLINK)
451 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
452
Victor Stinner8c7c6972012-12-04 10:07:16 +0100453 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
454 try:
455 posix.lchflags(_DUMMY_SYMLINK,
456 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
457 except OSError as err:
458 if err.errno != errno.EOPNOTSUPP:
459 raise
460 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
461 self.skipTest(msg)
462
Ned Deily43e10542011-06-27 23:41:53 -0700463 try:
464 new_testfn_st = os.stat(test_support.TESTFN)
465 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
466
467 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
468 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
469 new_dummy_symlink_st.st_flags)
470 finally:
471 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000472
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200473 @unittest.skipUnless(hasattr(posix, 'getcwd'),
474 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000475 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200476 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
477 curdir = os.getcwd()
478 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000479
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200480 try:
481 os.mkdir(base_path)
482 os.chdir(base_path)
483 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600484 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000485
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200486 try:
487 def _create_and_do_getcwd(dirname, current_path_length = 0):
488 try:
489 os.mkdir(dirname)
490 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600491 self.skipTest("mkdir cannot create directory sufficiently "
492 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000493
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200494 os.chdir(dirname)
495 try:
496 os.getcwd()
497 if current_path_length < 4099:
498 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
499 except OSError as e:
500 expected_errno = errno.ENAMETOOLONG
501 # The following platforms have quirky getcwd()
502 # behaviour -- see issue 9185 and 15765 for
503 # more information.
504 quirky_platform = (
505 'sunos' in sys.platform or
506 'netbsd' in sys.platform or
507 'openbsd' in sys.platform
508 )
509 if quirky_platform:
510 expected_errno = errno.ERANGE
511 self.assertEqual(e.errno, expected_errno)
512 finally:
513 os.chdir('..')
514 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000515
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200516 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000517
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200518 finally:
519 os.chdir(curdir)
520 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000521
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000522 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000523 def test_getgroups(self):
Jesus Ceafd3ba7b2014-06-28 18:39:01 +0200524 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000525 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200526 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000527
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200528 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000529 raise unittest.SkipTest("need working 'id -G'")
530
Ned Deilycc23cc62013-02-02 15:06:45 -0800531 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
532 if sys.platform == 'darwin':
533 import sysconfig
534 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily1f70b872014-06-25 13:33:57 -0700535 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deilycc23cc62013-02-02 15:06:45 -0800536 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
537
Ronald Oussorenac72e582010-08-03 07:31:12 +0000538 # 'id -G' and 'os.getgroups()' should return the same
539 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000540 # #10822 - it is implementation defined whether posix.getgroups()
541 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000542 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000543 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000544 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000545
546class PosixGroupsTester(unittest.TestCase):
547
548 def setUp(self):
549 if posix.getuid() != 0:
550 raise unittest.SkipTest("not enough privileges")
551 if not hasattr(posix, 'getgroups'):
552 raise unittest.SkipTest("need posix.getgroups")
553 if sys.platform == 'darwin':
554 raise unittest.SkipTest("getgroups(2) is broken on OSX")
555 self.saved_groups = posix.getgroups()
556
557 def tearDown(self):
558 if hasattr(posix, 'setgroups'):
559 posix.setgroups(self.saved_groups)
560 elif hasattr(posix, 'initgroups'):
561 name = pwd.getpwuid(posix.getuid()).pw_name
562 posix.initgroups(name, self.saved_groups[0])
563
564 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200565 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000566 def test_initgroups(self):
567 # find missing group
568
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500569 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000570 name = pwd.getpwuid(posix.getuid()).pw_name
571 posix.initgroups(name, g)
572 self.assertIn(g, posix.getgroups())
573
574 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200575 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000576 def test_setgroups(self):
577 for groups in [[0], range(16)]:
578 posix.setgroups(groups)
579 self.assertListEqual(groups, posix.getgroups())
580
Facundo Batista5596b0c2008-06-22 13:36:20 +0000581
Neal Norwitze241ce82003-02-17 18:17:05 +0000582def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000583 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000584
585if __name__ == '__main__':
586 test_main()