blob: 93611f04515ae991a21e9db250089219c70b0d0c [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Hai Shibb0424b2020-08-04 00:47:42 +08004from test.support import import_helper
5from test.support import os_helper
6from test.support import warnings_helper
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007from test.support.script_helper import assert_python_ok
R. David Murrayeb3615d2009-04-22 02:24:39 +00008
9# Skip these tests if there is no posix module.
Hai Shibb0424b2020-08-04 00:47:42 +080010posix = import_helper.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +000011
Antoine Pitroub7572f02009-12-02 20:46:48 +000012import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +000013import sys
Pablo Galindo254a4662018-09-07 16:44:24 +010014import signal
Neal Norwitze241ce82003-02-17 18:17:05 +000015import time
16import os
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020017import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000018import pwd
Benjamin Peterson052a02b2010-08-17 01:27:09 +000019import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070020import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000021import unittest
22import warnings
Pablo Galindo254a4662018-09-07 16:44:24 +010023import textwrap
R. David Murraya21e4ca2009-03-31 23:16:50 +000024
Ned Deilyba2eab22011-07-26 13:53:55 -070025_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
Hai Shibb0424b2020-08-04 00:47:42 +080026 os_helper.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000027
Serhiy Storchaka9d572732018-07-31 10:24:54 +030028requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
29 'test is only meaningful on 32-bit builds')
30
Benjamin Petersonc7042222018-09-12 15:12:24 -070031def _supports_sched():
32 if not hasattr(posix, 'sched_getscheduler'):
33 return False
34 try:
35 posix.sched_getscheduler(0)
36 except OSError as e:
37 if e.errno == errno.ENOSYS:
38 return False
39 return True
40
41requires_sched = unittest.skipUnless(_supports_sched(), 'requires POSIX scheduler API')
42
Victor Stinner278c1e12020-03-31 20:08:12 +020043
Neal Norwitze241ce82003-02-17 18:17:05 +000044class PosixTester(unittest.TestCase):
45
46 def setUp(self):
47 # create empty file
Inada Naoki4663e5f2021-04-06 13:02:22 +090048 with open(os_helper.TESTFN, "wb"):
49 pass
Hai Shibb0424b2020-08-04 00:47:42 +080050 self.teardown_files = [ os_helper.TESTFN ]
51 self._warnings_manager = warnings_helper.check_warnings()
Brett Cannonc8d502e2010-03-20 21:53:28 +000052 self._warnings_manager.__enter__()
53 warnings.filterwarnings('ignore', '.* potential security risk .*',
54 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
56 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070057 for teardown_file in self.teardown_files:
Hai Shibb0424b2020-08-04 00:47:42 +080058 os_helper.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000059 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000060
61 def testNoArgFunctions(self):
62 # test posix functions which take no arguments and have
63 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000064 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000065 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000066 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020067 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000068 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000069
Neal Norwitze241ce82003-02-17 18:17:05 +000070 for name in NO_ARG_FUNCTIONS:
71 posix_func = getattr(posix, name, None)
72 if posix_func is not None:
73 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000074 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000075
Serhiy Storchaka43767632013-11-03 21:31:38 +020076 @unittest.skipUnless(hasattr(posix, 'getresuid'),
77 'test needs posix.getresuid()')
78 def test_getresuid(self):
79 user_ids = posix.getresuid()
80 self.assertEqual(len(user_ids), 3)
81 for val in user_ids:
82 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000083
Serhiy Storchaka43767632013-11-03 21:31:38 +020084 @unittest.skipUnless(hasattr(posix, 'getresgid'),
85 'test needs posix.getresgid()')
86 def test_getresgid(self):
87 group_ids = posix.getresgid()
88 self.assertEqual(len(group_ids), 3)
89 for val in group_ids:
90 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000091
Serhiy Storchaka43767632013-11-03 21:31:38 +020092 @unittest.skipUnless(hasattr(posix, 'setresuid'),
93 'test needs posix.setresuid()')
94 def test_setresuid(self):
95 current_user_ids = posix.getresuid()
96 self.assertIsNone(posix.setresuid(*current_user_ids))
97 # -1 means don't change that value.
98 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000099
Serhiy Storchaka43767632013-11-03 21:31:38 +0200100 @unittest.skipUnless(hasattr(posix, 'setresuid'),
101 'test needs posix.setresuid()')
102 def test_setresuid_exception(self):
103 # Don't do this test if someone is silly enough to run us as root.
104 current_user_ids = posix.getresuid()
105 if 0 not in current_user_ids:
106 new_user_ids = (current_user_ids[0]+1, -1, -1)
107 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000108
Serhiy Storchaka43767632013-11-03 21:31:38 +0200109 @unittest.skipUnless(hasattr(posix, 'setresgid'),
110 'test needs posix.setresgid()')
111 def test_setresgid(self):
112 current_group_ids = posix.getresgid()
113 self.assertIsNone(posix.setresgid(*current_group_ids))
114 # -1 means don't change that value.
115 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000116
Serhiy Storchaka43767632013-11-03 21:31:38 +0200117 @unittest.skipUnless(hasattr(posix, 'setresgid'),
118 'test needs posix.setresgid()')
119 def test_setresgid_exception(self):
120 # Don't do this test if someone is silly enough to run us as root.
121 current_group_ids = posix.getresgid()
122 if 0 not in current_group_ids:
123 new_group_ids = (current_group_ids[0]+1, -1, -1)
124 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000125
Antoine Pitroub7572f02009-12-02 20:46:48 +0000126 @unittest.skipUnless(hasattr(posix, 'initgroups'),
127 "test needs os.initgroups()")
128 def test_initgroups(self):
129 # It takes a string and an integer; check that it raises a TypeError
130 # for other argument lists.
131 self.assertRaises(TypeError, posix.initgroups)
132 self.assertRaises(TypeError, posix.initgroups, None)
133 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
134 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
135
136 # If a non-privileged user invokes it, it should fail with OSError
137 # EPERM.
138 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200139 try:
140 name = pwd.getpwuid(posix.getuid()).pw_name
141 except KeyError:
142 # the current UID may not have a pwd entry
143 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000144 try:
145 posix.initgroups(name, 13)
146 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000147 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000148 else:
149 self.fail("Expected OSError to be raised by initgroups")
150
Serhiy Storchaka43767632013-11-03 21:31:38 +0200151 @unittest.skipUnless(hasattr(posix, 'statvfs'),
152 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000153 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200154 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000155
Serhiy Storchaka43767632013-11-03 21:31:38 +0200156 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
157 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000158 def test_fstatvfs(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800159 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200160 try:
161 self.assertTrue(posix.fstatvfs(fp.fileno()))
162 self.assertTrue(posix.statvfs(fp.fileno()))
163 finally:
164 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000165
Serhiy Storchaka43767632013-11-03 21:31:38 +0200166 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
167 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000168 def test_ftruncate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800169 fp = open(os_helper.TESTFN, 'w+')
Serhiy Storchaka43767632013-11-03 21:31:38 +0200170 try:
171 # we need to have some data to truncate
172 fp.write('test')
173 fp.flush()
174 posix.ftruncate(fp.fileno(), 0)
175 finally:
176 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000177
Ross Lagerwall7807c352011-03-17 20:20:30 +0200178 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
179 def test_truncate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800180 with open(os_helper.TESTFN, 'w') as fp:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200181 fp.write('test')
182 fp.flush()
Hai Shibb0424b2020-08-04 00:47:42 +0800183 posix.truncate(os_helper.TESTFN, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200184
Larry Hastings9cf065c2012-06-22 16:30:09 -0700185 @unittest.skipUnless(getattr(os, 'execve', None) in os.supports_fd, "test needs execve() to support the fd parameter")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200186 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200187 def test_fexecve(self):
188 fp = os.open(sys.executable, os.O_RDONLY)
189 try:
190 pid = os.fork()
191 if pid == 0:
192 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700193 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200194 else:
Victor Stinner278c1e12020-03-31 20:08:12 +0200195 support.wait_process(pid, exitcode=0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200196 finally:
197 os.close(fp)
198
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000199
Ross Lagerwall7807c352011-03-17 20:20:30 +0200200 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
201 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
202 def test_waitid(self):
203 pid = os.fork()
204 if pid == 0:
205 os.chdir(os.path.split(sys.executable)[0])
206 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
207 else:
208 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
209 self.assertEqual(pid, res.si_pid)
210
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200211 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700212 def test_register_at_fork(self):
213 with self.assertRaises(TypeError, msg="Positional args not allowed"):
214 os.register_at_fork(lambda: None)
215 with self.assertRaises(TypeError, msg="Args must be callable"):
216 os.register_at_fork(before=2)
217 with self.assertRaises(TypeError, msg="Args must be callable"):
218 os.register_at_fork(after_in_child="three")
219 with self.assertRaises(TypeError, msg="Args must be callable"):
220 os.register_at_fork(after_in_parent=b"Five")
221 with self.assertRaises(TypeError, msg="Args must not be None"):
222 os.register_at_fork(before=None)
223 with self.assertRaises(TypeError, msg="Args must not be None"):
224 os.register_at_fork(after_in_child=None)
225 with self.assertRaises(TypeError, msg="Args must not be None"):
226 os.register_at_fork(after_in_parent=None)
227 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
228 # Ensure a combination of valid and invalid is an error.
229 os.register_at_fork(before=None, after_in_parent=lambda: 3)
230 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
231 # Ensure a combination of valid and invalid is an error.
232 os.register_at_fork(before=lambda: None, after_in_child='')
233 # We test actual registrations in their own process so as not to
234 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200235 code = """if 1:
236 import os
237
238 r, w = os.pipe()
239 fin_r, fin_w = os.pipe()
240
Gregory P. Smith163468a2017-05-29 10:03:41 -0700241 os.register_at_fork(before=lambda: os.write(w, b'A'))
242 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
243 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
244 os.register_at_fork(before=lambda: os.write(w, b'B'),
245 after_in_parent=lambda: os.write(w, b'D'),
246 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200247
248 pid = os.fork()
249 if pid == 0:
250 # At this point, after-forkers have already been executed
251 os.close(w)
252 # Wait for parent to tell us to exit
253 os.read(fin_r, 1)
254 os._exit(0)
255 else:
256 try:
257 os.close(w)
258 with open(r, "rb") as f:
259 data = f.read()
260 assert len(data) == 6, data
261 # Check before-fork callbacks
262 assert data[:2] == b'BA', data
263 # Check after-fork callbacks
264 assert sorted(data[2:]) == list(b'CDEF'), data
265 assert data.index(b'C') < data.index(b'D'), data
266 assert data.index(b'E') < data.index(b'F'), data
267 finally:
268 os.write(fin_w, b'!')
269 """
270 assert_python_ok('-c', code)
271
Ross Lagerwall7807c352011-03-17 20:20:30 +0200272 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
273 def test_lockf(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800274 fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200275 try:
276 os.write(fd, b'test')
277 os.lseek(fd, 0, os.SEEK_SET)
278 posix.lockf(fd, posix.F_LOCK, 4)
279 # section is locked
280 posix.lockf(fd, posix.F_ULOCK, 4)
281 finally:
282 os.close(fd)
283
284 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
285 def test_pread(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800286 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200287 try:
288 os.write(fd, b'test')
289 os.lseek(fd, 0, os.SEEK_SET)
290 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100291 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200292 self.assertEqual(b'te', posix.read(fd, 2))
293 finally:
294 os.close(fd)
295
Pablo Galindo4defba32018-01-27 16:16:37 +0000296 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
297 def test_preadv(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800298 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000299 try:
300 os.write(fd, b'test1tt2t3t5t6t6t8')
301 buf = [bytearray(i) for i in [5, 3, 2]]
302 self.assertEqual(posix.preadv(fd, buf, 3), 10)
303 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
304 finally:
305 os.close(fd)
306
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300307 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000308 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
309 def test_preadv_flags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800310 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000311 try:
312 os.write(fd, b'test1tt2t3t5t6t6t8')
313 buf = [bytearray(i) for i in [5, 3, 2]]
314 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
315 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
Benjamin Peterson44867bb2019-06-11 10:15:31 -0700316 except NotImplementedError:
317 self.skipTest("preadv2 not available")
Pablo Galindo46544f62019-04-13 17:06:03 +0100318 except OSError as inst:
319 # Is possible that the macro RWF_HIPRI was defined at compilation time
320 # but the option is not supported by the kernel or the runtime libc shared
321 # library.
322 if inst.errno in {errno.EINVAL, errno.ENOTSUP}:
323 raise unittest.SkipTest("RWF_HIPRI is not supported by the current system")
324 else:
325 raise
Pablo Galindo4defba32018-01-27 16:16:37 +0000326 finally:
327 os.close(fd)
328
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300329 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
330 @requires_32b
331 def test_preadv_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800332 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300333 try:
334 buf = [bytearray(2**16)] * 2**15
335 with self.assertRaises(OSError) as cm:
336 os.preadv(fd, buf, 0)
337 self.assertEqual(cm.exception.errno, errno.EINVAL)
338 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
339 finally:
340 os.close(fd)
341
Ross Lagerwall7807c352011-03-17 20:20:30 +0200342 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
343 def test_pwrite(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800344 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200345 try:
346 os.write(fd, b'test')
347 os.lseek(fd, 0, os.SEEK_SET)
348 posix.pwrite(fd, b'xx', 1)
349 self.assertEqual(b'txxt', posix.read(fd, 4))
350 finally:
351 os.close(fd)
352
Pablo Galindo4defba32018-01-27 16:16:37 +0000353 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
354 def test_pwritev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800355 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000356 try:
357 os.write(fd, b"xx")
358 os.lseek(fd, 0, os.SEEK_SET)
359 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
360 self.assertEqual(n, 10)
361
362 os.lseek(fd, 0, os.SEEK_SET)
363 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
364 finally:
365 os.close(fd)
366
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300367 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000368 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
369 def test_pwritev_flags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800370 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000371 try:
372 os.write(fd,b"xx")
373 os.lseek(fd, 0, os.SEEK_SET)
374 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
375 self.assertEqual(n, 10)
376
377 os.lseek(fd, 0, os.SEEK_SET)
378 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
379 finally:
380 os.close(fd)
381
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300382 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
383 @requires_32b
384 def test_pwritev_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800385 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300386 try:
387 with self.assertRaises(OSError) as cm:
388 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
389 self.assertEqual(cm.exception.errno, errno.EINVAL)
390 finally:
391 os.close(fd)
392
Ross Lagerwall7807c352011-03-17 20:20:30 +0200393 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
394 "test needs posix.posix_fallocate()")
395 def test_posix_fallocate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800396 fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200397 try:
398 posix.posix_fallocate(fd, 0, 10)
399 except OSError as inst:
400 # issue10812, ZFS doesn't appear to support posix_fallocate,
401 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400402 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
403 # often used there.
404 if inst.errno == errno.EINVAL and sys.platform.startswith(
405 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
406 raise unittest.SkipTest("test may fail on ZFS filesystems")
407 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200408 raise
409 finally:
410 os.close(fd)
411
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500412 # issue31106 - posix_fallocate() does not set error in errno.
413 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
414 "test needs posix.posix_fallocate()")
415 def test_posix_fallocate_errno(self):
416 try:
417 posix.posix_fallocate(-42, 0, 10)
418 except OSError as inst:
419 if inst.errno != errno.EBADF:
420 raise
421
Ross Lagerwall7807c352011-03-17 20:20:30 +0200422 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
423 "test needs posix.posix_fadvise()")
424 def test_posix_fadvise(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800425 fd = os.open(os_helper.TESTFN, os.O_RDONLY)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200426 try:
427 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
428 finally:
429 os.close(fd)
430
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500431 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
432 "test needs posix.posix_fadvise()")
433 def test_posix_fadvise_errno(self):
434 try:
435 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
436 except OSError as inst:
437 if inst.errno != errno.EBADF:
438 raise
439
Larry Hastings9cf065c2012-06-22 16:30:09 -0700440 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
441 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200442 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800443 fd = os.open(os_helper.TESTFN, os.O_RDONLY)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200444 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700445 posix.utime(fd)
446 posix.utime(fd, None)
447 self.assertRaises(TypeError, posix.utime, fd, (None, None))
448 self.assertRaises(TypeError, posix.utime, fd, (now, None))
449 self.assertRaises(TypeError, posix.utime, fd, (None, now))
450 posix.utime(fd, (int(now), int(now)))
451 posix.utime(fd, (now, now))
452 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
453 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
454 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
455 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
456 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
457
Ross Lagerwall7807c352011-03-17 20:20:30 +0200458 finally:
459 os.close(fd)
460
Larry Hastings9cf065c2012-06-22 16:30:09 -0700461 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
462 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200463 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800464 posix.utime(os_helper.TESTFN, None, follow_symlinks=False)
465 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
466 (None, None), follow_symlinks=False)
467 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
468 (now, None), follow_symlinks=False)
469 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
470 (None, now), follow_symlinks=False)
471 posix.utime(os_helper.TESTFN, (int(now), int(now)),
472 follow_symlinks=False)
473 posix.utime(os_helper.TESTFN, (now, now), follow_symlinks=False)
474 posix.utime(os_helper.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200475
476 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
477 def test_writev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800478 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200479 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100480 n = os.writev(fd, (b'test1', b'tt2', b't3'))
481 self.assertEqual(n, 10)
482
Ross Lagerwall7807c352011-03-17 20:20:30 +0200483 os.lseek(fd, 0, os.SEEK_SET)
484 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100485
486 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100487 try:
488 size = posix.writev(fd, [])
489 except OSError:
490 # writev(fd, []) raises OSError(22, "Invalid argument")
491 # on OpenIndiana
492 pass
493 else:
494 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200495 finally:
496 os.close(fd)
497
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300498 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
499 @requires_32b
500 def test_writev_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800501 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300502 try:
503 with self.assertRaises(OSError) as cm:
504 os.writev(fd, [b"x" * 2**16] * 2**15)
505 self.assertEqual(cm.exception.errno, errno.EINVAL)
506 finally:
507 os.close(fd)
508
Ross Lagerwall7807c352011-03-17 20:20:30 +0200509 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
510 def test_readv(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800511 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200512 try:
513 os.write(fd, b'test1tt2t3')
514 os.lseek(fd, 0, os.SEEK_SET)
515 buf = [bytearray(i) for i in [5, 3, 2]]
516 self.assertEqual(posix.readv(fd, buf), 10)
517 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100518
519 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100520 try:
521 size = posix.readv(fd, [])
522 except OSError:
523 # readv(fd, []) raises OSError(22, "Invalid argument")
524 # on OpenIndiana
525 pass
526 else:
527 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200528 finally:
529 os.close(fd)
530
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300531 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
532 @requires_32b
533 def test_readv_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800534 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300535 try:
536 buf = [bytearray(2**16)] * 2**15
537 with self.assertRaises(OSError) as cm:
538 os.readv(fd, buf)
539 self.assertEqual(cm.exception.errno, errno.EINVAL)
540 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
541 finally:
542 os.close(fd)
543
Serhiy Storchaka43767632013-11-03 21:31:38 +0200544 @unittest.skipUnless(hasattr(posix, 'dup'),
545 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000546 def test_dup(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800547 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200548 try:
549 fd = posix.dup(fp.fileno())
550 self.assertIsInstance(fd, int)
551 os.close(fd)
552 finally:
553 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000554
Serhiy Storchaka43767632013-11-03 21:31:38 +0200555 @unittest.skipUnless(hasattr(posix, 'confstr'),
556 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000557 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200558 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
559 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000560
Serhiy Storchaka43767632013-11-03 21:31:38 +0200561 @unittest.skipUnless(hasattr(posix, 'dup2'),
562 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000563 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800564 fp1 = open(os_helper.TESTFN)
565 fp2 = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200566 try:
567 posix.dup2(fp1.fileno(), fp2.fileno())
568 finally:
569 fp1.close()
570 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000571
Charles-François Natali1e045b12011-05-22 20:42:32 +0200572 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200573 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200574 def test_oscloexec(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800575 fd = os.open(os_helper.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200576 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200577 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200578
Serhiy Storchaka43767632013-11-03 21:31:38 +0200579 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
580 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000581 def test_osexlock(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800582 fd = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200583 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800584 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200585 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
586 os.close(fd)
587
588 if hasattr(posix, "O_SHLOCK"):
Hai Shibb0424b2020-08-04 00:47:42 +0800589 fd = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200590 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800591 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000592 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
593 os.close(fd)
594
Serhiy Storchaka43767632013-11-03 21:31:38 +0200595 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
596 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000597 def test_osshlock(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800598 fd1 = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200599 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800600 fd2 = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200601 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
602 os.close(fd2)
603 os.close(fd1)
604
605 if hasattr(posix, "O_EXLOCK"):
Hai Shibb0424b2020-08-04 00:47:42 +0800606 fd = os.open(os_helper.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000607 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800608 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200609 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
610 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000611
Serhiy Storchaka43767632013-11-03 21:31:38 +0200612 @unittest.skipUnless(hasattr(posix, 'fstat'),
613 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000614 def test_fstat(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800615 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200616 try:
617 self.assertTrue(posix.fstat(fp.fileno()))
618 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200619
Serhiy Storchaka43767632013-11-03 21:31:38 +0200620 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700621 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200622 posix.stat, float(fp.fileno()))
623 finally:
624 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000625
626 def test_stat(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800627 self.assertTrue(posix.stat(os_helper.TESTFN))
628 self.assertTrue(posix.stat(os.fsencode(os_helper.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200629
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300630 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700631 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800632 posix.stat, bytearray(os.fsencode(os_helper.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200633 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700634 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200635 posix.stat, None)
636 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700637 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800638 posix.stat, list(os_helper.TESTFN))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200639 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700640 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800641 posix.stat, list(os.fsencode(os_helper.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000642
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000643 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
644 def test_mkfifo(self):
pxinwrb2d0c662020-12-01 16:20:50 +0800645 if sys.platform == "vxworks":
646 fifo_path = os.path.join("/fifos/", os_helper.TESTFN)
647 else:
648 fifo_path = os_helper.TESTFN
649 os_helper.unlink(fifo_path)
650 self.addCleanup(os_helper.unlink, fifo_path)
xdegaye92c2ca72017-11-12 17:31:07 +0100651 try:
pxinwrb2d0c662020-12-01 16:20:50 +0800652 posix.mkfifo(fifo_path, stat.S_IRUSR | stat.S_IWUSR)
xdegaye92c2ca72017-11-12 17:31:07 +0100653 except PermissionError as e:
654 self.skipTest('posix.mkfifo(): %s' % e)
pxinwrb2d0c662020-12-01 16:20:50 +0800655 self.assertTrue(stat.S_ISFIFO(posix.stat(fifo_path).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000656
657 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
658 "don't have mknod()/S_IFIFO")
659 def test_mknod(self):
660 # Test using mknod() to create a FIFO (the only use specified
661 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +0800662 os_helper.unlink(os_helper.TESTFN)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000663 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
664 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800665 posix.mknod(os_helper.TESTFN, mode, 0)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000666 except OSError as e:
667 # Some old systems don't allow unprivileged users to use
668 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100669 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000670 else:
Hai Shibb0424b2020-08-04 00:47:42 +0800671 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000672
Martin Panterbf19d162015-09-09 01:01:13 +0000673 # Keyword arguments are also supported
Hai Shibb0424b2020-08-04 00:47:42 +0800674 os_helper.unlink(os_helper.TESTFN)
Martin Panterbf19d162015-09-09 01:01:13 +0000675 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800676 posix.mknod(path=os_helper.TESTFN, mode=mode, device=0,
Martin Panterbf19d162015-09-09 01:01:13 +0000677 dir_fd=None)
678 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100679 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000680
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300681 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
682 def test_makedev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800683 st = posix.stat(os_helper.TESTFN)
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300684 dev = st.st_dev
685 self.assertIsInstance(dev, int)
686 self.assertGreaterEqual(dev, 0)
687
688 major = posix.major(dev)
689 self.assertIsInstance(major, int)
690 self.assertGreaterEqual(major, 0)
691 self.assertEqual(posix.major(dev), major)
692 self.assertRaises(TypeError, posix.major, float(dev))
693 self.assertRaises(TypeError, posix.major)
694 self.assertRaises((ValueError, OverflowError), posix.major, -1)
695
696 minor = posix.minor(dev)
697 self.assertIsInstance(minor, int)
698 self.assertGreaterEqual(minor, 0)
699 self.assertEqual(posix.minor(dev), minor)
700 self.assertRaises(TypeError, posix.minor, float(dev))
701 self.assertRaises(TypeError, posix.minor)
702 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
703
704 self.assertEqual(posix.makedev(major, minor), dev)
705 self.assertRaises(TypeError, posix.makedev, float(major), minor)
706 self.assertRaises(TypeError, posix.makedev, major, float(minor))
707 self.assertRaises(TypeError, posix.makedev, major)
708 self.assertRaises(TypeError, posix.makedev)
709
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200710 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000711 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200712 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 if stat_func is not None:
714 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200715 self.assertEqual(stat.st_uid, uid)
716 self.assertEqual(stat.st_gid, gid)
717 uid = os.getuid()
718 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200719 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200720 chown_func(first_param, uid, gid)
721 check_stat(uid, gid)
722 chown_func(first_param, -1, gid)
723 check_stat(uid, gid)
724 chown_func(first_param, uid, -1)
725 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200726
pxinwr9a0dea62020-12-16 05:21:53 +0800727 if sys.platform == "vxworks":
728 # On VxWorks, root user id is 1 and 0 means no login user:
729 # both are super users.
730 is_root = (uid in (0, 1))
731 else:
732 is_root = (uid == 0)
733 if is_root:
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200734 # Try an amusingly large uid/gid to make sure we handle
735 # large unsigned values. (chown lets you use any
736 # uid/gid you like, even if they aren't defined.)
737 #
pxinwr9a0dea62020-12-16 05:21:53 +0800738 # On VxWorks uid_t is defined as unsigned short. A big
739 # value greater than 65535 will result in underflow error.
740 #
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200741 # This problem keeps coming up:
742 # http://bugs.python.org/issue1747858
743 # http://bugs.python.org/issue4591
744 # http://bugs.python.org/issue15301
745 # Hopefully the fix in 4591 fixes it for good!
746 #
747 # This part of the test only runs when run as root.
748 # Only scary people run their tests as root.
749
pxinwr9a0dea62020-12-16 05:21:53 +0800750 big_value = (2**31 if sys.platform != "vxworks" else 2**15)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200751 chown_func(first_param, big_value, big_value)
752 check_stat(big_value, big_value)
753 chown_func(first_param, -1, -1)
754 check_stat(big_value, big_value)
755 chown_func(first_param, uid, gid)
756 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200757 elif platform.system() in ('HP-UX', 'SunOS'):
758 # HP-UX and Solaris can allow a non-root user to chown() to root
759 # (issue #5113)
760 raise unittest.SkipTest("Skipping because of non-standard chown() "
761 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000762 else:
763 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200764 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200765 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200766 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200767 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200768 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200769 self.assertRaises(OSError, chown_func, first_param, -1, 0)
770 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200771 # test illegal types
772 for t in str, float:
773 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
774 check_stat(uid, gid)
775 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
776 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000777
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000778 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
779 def test_chown(self):
780 # raise an OSError if the file does not exist
Hai Shibb0424b2020-08-04 00:47:42 +0800781 os.unlink(os_helper.TESTFN)
782 self.assertRaises(OSError, posix.chown, os_helper.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000783
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000784 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800785 os_helper.create_empty_file(os_helper.TESTFN)
786 self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000787
788 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
789 def test_fchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800790 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000791
792 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800793 test_file = open(os_helper.TESTFN, 'w')
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000794 try:
795 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200796 self._test_all_chown_common(posix.fchown, fd,
797 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000798 finally:
799 test_file.close()
800
801 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
802 def test_lchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800803 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000804 # create a symlink
Hai Shibb0424b2020-08-04 00:47:42 +0800805 os.symlink(_DUMMY_SYMLINK, os_helper.TESTFN)
806 self._test_all_chown_common(posix.lchown, os_helper.TESTFN,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200807 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000808
Serhiy Storchaka43767632013-11-03 21:31:38 +0200809 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000810 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200811 posix.chdir(os.curdir)
Hai Shibb0424b2020-08-04 00:47:42 +0800812 self.assertRaises(OSError, posix.chdir, os_helper.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000813
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000814 def test_listdir(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800815 self.assertIn(os_helper.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000816
817 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700818 # When listdir is called without argument,
819 # it's the same as listdir(os.curdir).
Hai Shibb0424b2020-08-04 00:47:42 +0800820 self.assertIn(os_helper.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000821
Larry Hastingsfdaea062012-06-25 04:42:23 -0700822 def test_listdir_bytes(self):
823 # When listdir is called with a bytes object,
824 # the returned strings are of type bytes.
Hai Shibb0424b2020-08-04 00:47:42 +0800825 self.assertIn(os.fsencode(os_helper.TESTFN), posix.listdir(b'.'))
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300826
827 def test_listdir_bytes_like(self):
828 for cls in bytearray, memoryview:
829 with self.assertWarns(DeprecationWarning):
830 names = posix.listdir(cls(b'.'))
Hai Shibb0424b2020-08-04 00:47:42 +0800831 self.assertIn(os.fsencode(os_helper.TESTFN), names)
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300832 for name in names:
833 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700834
835 @unittest.skipUnless(posix.listdir in os.supports_fd,
836 "test needs fd support for posix.listdir()")
837 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000838 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100839 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000840 self.assertEqual(
841 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000843 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100844 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100845 self.assertEqual(
846 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700847 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100848 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000849
Serhiy Storchaka43767632013-11-03 21:31:38 +0200850 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000851 def test_access(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800852 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000853
Serhiy Storchaka43767632013-11-03 21:31:38 +0200854 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000855 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200856 old_mask = posix.umask(0)
857 self.assertIsInstance(old_mask, int)
858 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000859
Serhiy Storchaka43767632013-11-03 21:31:38 +0200860 @unittest.skipUnless(hasattr(posix, 'strerror'),
861 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000862 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200863 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000864
Serhiy Storchaka43767632013-11-03 21:31:38 +0200865 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000866 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200867 reader, writer = posix.pipe()
868 os.close(reader)
869 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000870
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200871 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200872 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200873 def test_pipe2(self):
874 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
875 self.assertRaises(TypeError, os.pipe2, 0, 0)
876
Charles-François Natali368f34b2011-06-06 19:49:47 +0200877 # try calling with flags = 0, like os.pipe()
878 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200879 os.close(r)
880 os.close(w)
881
882 # test flags
883 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
884 self.addCleanup(os.close, r)
885 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200886 self.assertFalse(os.get_inheritable(r))
887 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200888 self.assertFalse(os.get_blocking(r))
889 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200890 # try reading from an empty pipe: this should fail, not block
891 self.assertRaises(OSError, os.read, r, 1)
892 # try a write big enough to fill-up the pipe: this should either
893 # fail or perform a partial write, not block
894 try:
895 os.write(w, b'x' * support.PIPE_MAX_SIZE)
896 except OSError:
897 pass
898
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200899 @support.cpython_only
900 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
901 @support.requires_linux_version(2, 6, 27)
902 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200903 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200904 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200905 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
906 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
907
Serhiy Storchaka43767632013-11-03 21:31:38 +0200908 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000909 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200910 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800911 posix.utime(os_helper.TESTFN, None)
912 self.assertRaises(TypeError, posix.utime,
913 os_helper.TESTFN, (None, None))
914 self.assertRaises(TypeError, posix.utime,
915 os_helper.TESTFN, (now, None))
916 self.assertRaises(TypeError, posix.utime,
917 os_helper.TESTFN, (None, now))
918 posix.utime(os_helper.TESTFN, (int(now), int(now)))
919 posix.utime(os_helper.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000920
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700922 st = os.stat(target_file)
923 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000924
925 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
926 flags = st.st_flags | stat.UF_IMMUTABLE
927 try:
928 chflags_func(target_file, flags, **kwargs)
929 except OSError as err:
930 if err.errno != errno.EOPNOTSUPP:
931 raise
932 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
933 self.skipTest(msg)
934
Ned Deily3eb67d52011-06-28 00:00:28 -0700935 try:
936 new_st = os.stat(target_file)
937 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
938 try:
939 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200940 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700941 self.assertEqual(e.errno, errno.EPERM)
942 finally:
943 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000944
Ned Deily3eb67d52011-06-28 00:00:28 -0700945 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
946 def test_chflags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800947 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700948
949 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
950 def test_lchflags_regular_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800951 self._test_chflags_regular_file(posix.lchflags, os_helper.TESTFN)
952 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN,
953 follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700954
955 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
956 def test_lchflags_symlink(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800957 testfn_st = os.stat(os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700958
959 self.assertTrue(hasattr(testfn_st, 'st_flags'))
960
Hai Shibb0424b2020-08-04 00:47:42 +0800961 os.symlink(os_helper.TESTFN, _DUMMY_SYMLINK)
Ned Deily3eb67d52011-06-28 00:00:28 -0700962 self.teardown_files.append(_DUMMY_SYMLINK)
963 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
964
Larry Hastings9cf065c2012-06-22 16:30:09 -0700965 def chflags_nofollow(path, flags):
966 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700967
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000969 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
970 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
971 try:
972 fn(_DUMMY_SYMLINK, flags)
973 except OSError as err:
974 if err.errno != errno.EOPNOTSUPP:
975 raise
976 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
977 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800979 new_testfn_st = os.stat(os_helper.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700980 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
981
982 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
983 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
984 new_dummy_symlink_st.st_flags)
985 finally:
986 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000987
Guido van Rossum98297ee2007-11-06 21:34:58 +0000988 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000989 if os.name == "nt":
990 item_type = str
991 else:
992 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000993 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000994 self.assertEqual(type(k), item_type)
995 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000996
Serhiy Storchaka77703942017-06-25 07:33:01 +0300997 def test_putenv(self):
998 with self.assertRaises(ValueError):
999 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
1000 with self.assertRaises(ValueError):
1001 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
1002 with self.assertRaises(ValueError):
1003 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
1004 with self.assertRaises(ValueError):
1005 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
1006 with self.assertRaises(ValueError):
1007 os.putenv('FRUIT=ORANGE', 'lemon')
1008 with self.assertRaises(ValueError):
1009 os.putenv(b'FRUIT=ORANGE', b'lemon')
1010
Serhiy Storchaka43767632013-11-03 21:31:38 +02001011 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001012 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001013 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
1014 curdir = os.getcwd()
Hai Shibb0424b2020-08-04 00:47:42 +08001015 base_path = os.path.abspath(os_helper.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001017 try:
1018 os.mkdir(base_path)
1019 os.chdir(base_path)
1020 except:
1021 # Just returning nothing instead of the SkipTest exception, because
1022 # the test results in Error in that case. Is that ok?
1023 # raise unittest.SkipTest("cannot create directory for testing")
1024 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001025
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001026 def _create_and_do_getcwd(dirname, current_path_length = 0):
1027 try:
1028 os.mkdir(dirname)
1029 except:
1030 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001031
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001032 os.chdir(dirname)
1033 try:
1034 os.getcwd()
1035 if current_path_length < 1027:
1036 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1037 finally:
1038 os.chdir('..')
1039 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001040
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001041 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001042
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001043 finally:
1044 os.chdir(curdir)
Hai Shibb0424b2020-08-04 00:47:42 +08001045 os_helper.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001046
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001047 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1048 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1049 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1050 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001051 user = pwd.getpwuid(os.getuid())[0]
1052 group = pwd.getpwuid(os.getuid())[3]
1053 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001054
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001055
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001056 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
pxinwre1e3c2d2020-12-16 05:20:07 +08001057 @unittest.skipUnless(hasattr(os, 'popen'), "test needs os.popen()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001058 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001059 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001060 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001061 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001062
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001063 try:
1064 idg_groups = set(int(g) for g in groups.split())
1065 except ValueError:
1066 idg_groups = set()
1067 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001068 raise unittest.SkipTest("need working 'id -G'")
1069
Ned Deily028915e2013-02-02 15:08:52 -08001070 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1071 if sys.platform == 'darwin':
1072 import sysconfig
1073 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ronald Oussoren49926cf2021-02-01 04:29:44 +01001074 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001075 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1076
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001077 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001078 # groups, ignoring order, duplicates, and the effective gid.
1079 # #10822/#26944 - It is implementation defined whether
1080 # posix.getgroups() includes the effective gid.
1081 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1082 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001083
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001084 # tests for the posix *at functions follow
1085
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1087 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001088 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1089 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001090 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001091 finally:
1092 posix.close(f)
1093
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1095 def test_chmod_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001096 os.chmod(os_helper.TESTFN, stat.S_IRUSR)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001097
1098 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1099 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001100 posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001101
Hai Shibb0424b2020-08-04 00:47:42 +08001102 s = posix.stat(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001103 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1104 finally:
1105 posix.close(f)
1106
pxinwreb7594f2020-12-09 07:18:37 +08001107 @unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd),
1108 "test needs dir_fd support in os.chown()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 def test_chown_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001110 os_helper.unlink(os_helper.TESTFN)
1111 os_helper.create_empty_file(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001112
1113 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1114 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001115 posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001116 finally:
1117 posix.close(f)
1118
Larry Hastings9cf065c2012-06-22 16:30:09 -07001119 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1120 def test_stat_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001121 os_helper.unlink(os_helper.TESTFN)
1122 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001123 outfile.write("testline\n")
1124
1125 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1126 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001127 s1 = posix.stat(os_helper.TESTFN)
1128 s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001129 self.assertEqual(s1, s2)
Hai Shibb0424b2020-08-04 00:47:42 +08001130 s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001131 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001132 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001133 posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001134 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001135 posix.stat, os_helper.TESTFN, dir_fd=float(f))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001136 self.assertRaises(OverflowError,
Hai Shibb0424b2020-08-04 00:47:42 +08001137 posix.stat, os_helper.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001138 finally:
1139 posix.close(f)
1140
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1142 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001143 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1144 try:
1145 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +08001146 posix.utime(os_helper.TESTFN, None, dir_fd=f)
1147 posix.utime(os_helper.TESTFN, dir_fd=f)
1148 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1149 now, dir_fd=f)
1150 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1151 (None, None), dir_fd=f)
1152 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1153 (now, None), dir_fd=f)
1154 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1155 (None, now), dir_fd=f)
1156 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1157 (now, "x"), dir_fd=f)
1158 posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
1159 posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
1160 posix.utime(os_helper.TESTFN,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
Hai Shibb0424b2020-08-04 00:47:42 +08001162 posix.utime(os_helper.TESTFN, dir_fd=f,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163 times=(int(now), int((now - int(now)) * 1e9)))
1164
Larry Hastings90867a52012-06-22 17:01:41 -07001165 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001167 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001168 posix.utime(os_helper.TESTFN, follow_symlinks=False,
1169 dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001170 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001171 # whoops! using both together not supported on this platform.
1172 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001173
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001174 finally:
1175 posix.close(f)
1176
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1178 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001179 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1180 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001181 posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link',
1182 src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001183 except PermissionError as e:
1184 self.skipTest('posix.link(): %s' % e)
1185 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001186 # should have same inodes
Hai Shibb0424b2020-08-04 00:47:42 +08001187 self.assertEqual(posix.stat(os_helper.TESTFN)[1],
1188 posix.stat(os_helper.TESTFN + 'link')[1])
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001189 finally:
1190 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001191 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001192
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1194 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001195 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1196 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001197 posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
1198 posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001199 finally:
1200 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001201 os_helper.rmtree(os_helper.TESTFN + 'dir')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001202
pxinwreb7594f2020-12-09 07:18:37 +08001203 @unittest.skipUnless(hasattr(os, 'mknod')
1204 and (os.mknod in os.supports_dir_fd)
1205 and hasattr(stat, 'S_IFIFO'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1207 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001208 # Test using mknodat() to create a FIFO (the only use specified
1209 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +08001210 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001211 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1212 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1213 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001214 posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001215 except OSError as e:
1216 # Some old systems don't allow unprivileged users to use
1217 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001218 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001219 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001220 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001221 finally:
1222 posix.close(f)
1223
Larry Hastings9cf065c2012-06-22 16:30:09 -07001224 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1225 def test_open_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001226 os_helper.unlink(os_helper.TESTFN)
1227 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001228 outfile.write("testline\n")
1229 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001230 b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001231 try:
1232 res = posix.read(b, 9).decode(encoding="utf-8")
1233 self.assertEqual("testline\n", res)
1234 finally:
1235 posix.close(a)
1236 posix.close(b)
1237
pxinwreb7594f2020-12-09 07:18:37 +08001238 @unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd),
1239 "test needs dir_fd support in os.readlink()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001240 def test_readlink_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001241 os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001242 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1243 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001244 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1245 posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001246 finally:
Hai Shibb0424b2020-08-04 00:47:42 +08001247 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001248 posix.close(f)
1249
Larry Hastings9cf065c2012-06-22 16:30:09 -07001250 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1251 def test_rename_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001252 os_helper.unlink(os_helper.TESTFN)
1253 os_helper.create_empty_file(os_helper.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001254 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1255 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001256 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001257 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001258 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001259 raise
1260 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001261 posix.stat(os_helper.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001262 finally:
1263 posix.close(f)
1264
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001265 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1266 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1267 def test_cld_xxxx_constants(self):
1268 os.CLD_EXITED
1269 os.CLD_KILLED
1270 os.CLD_DUMPED
1271 os.CLD_TRAPPED
1272 os.CLD_STOPPED
1273 os.CLD_CONTINUED
1274
Larry Hastings9cf065c2012-06-22 16:30:09 -07001275 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1276 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001277 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1278 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001279 posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link',
1280 dir_fd=f)
1281 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1282 os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001283 finally:
1284 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001285 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001286
Larry Hastings9cf065c2012-06-22 16:30:09 -07001287 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1288 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001289 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001290 os_helper.create_empty_file(os_helper.TESTFN + 'del')
1291 posix.stat(os_helper.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001292 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001293 posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001294 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001295 os_helper.unlink(os_helper.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001296 raise
1297 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001298 self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001299 finally:
1300 posix.close(f)
1301
Larry Hastings9cf065c2012-06-22 16:30:09 -07001302 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1303 def test_mkfifo_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001304 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001305 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1306 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001307 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001308 posix.mkfifo(os_helper.TESTFN,
xdegaye92c2ca72017-11-12 17:31:07 +01001309 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1310 except PermissionError as e:
1311 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +08001312 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001313 finally:
1314 posix.close(f)
1315
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001316 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1317 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001318 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001319 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001320
1321 @requires_sched_h
1322 def test_sched_yield(self):
1323 # This has no error conditions (at least on Linux).
1324 posix.sched_yield()
1325
1326 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001327 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1328 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001329 def test_sched_priority(self):
1330 # Round-robin usually has interesting priorities.
1331 pol = posix.SCHED_RR
1332 lo = posix.sched_get_priority_min(pol)
1333 hi = posix.sched_get_priority_max(pol)
1334 self.assertIsInstance(lo, int)
1335 self.assertIsInstance(hi, int)
1336 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001337 # OSX evidently just returns 15 without checking the argument.
1338 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001339 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1340 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001341
Benjamin Petersonc7042222018-09-12 15:12:24 -07001342 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001343 def test_get_and_set_scheduler_and_param(self):
1344 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1345 if name.startswith("SCHED_")]
1346 mine = posix.sched_getscheduler(0)
1347 self.assertIn(mine, possible_schedulers)
1348 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001349 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001350 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001351 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001352 raise
1353 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001354 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001355 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1356 self.assertRaises(OSError, posix.sched_getparam, -1)
1357 param = posix.sched_getparam(0)
1358 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001359
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001360 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1361 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1362 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1363 if not sys.platform.startswith(('freebsd', 'netbsd')):
1364 try:
1365 posix.sched_setscheduler(0, mine, param)
1366 posix.sched_setparam(0, param)
1367 except OSError as e:
1368 if e.errno != errno.EPERM:
1369 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001370 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1371
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001372 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1373 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1374 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1375 param = posix.sched_param(None)
1376 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1377 large = 214748364700
1378 param = posix.sched_param(large)
1379 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1380 param = posix.sched_param(sched_priority=-large)
1381 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1382
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001383 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001384 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001385 try:
1386 interval = posix.sched_rr_get_interval(0)
1387 except OSError as e:
1388 # This likely means that sched_rr_get_interval is only valid for
1389 # processes with the SCHED_RR scheduler in effect.
1390 if e.errno != errno.EINVAL:
1391 raise
1392 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001393 self.assertIsInstance(interval, float)
1394 # Reasonable constraints, I think.
1395 self.assertGreaterEqual(interval, 0.)
1396 self.assertLess(interval, 1.)
1397
Benjamin Peterson2740af82011-08-02 17:41:34 -05001398 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001399 def test_sched_getaffinity(self):
1400 mask = posix.sched_getaffinity(0)
1401 self.assertIsInstance(mask, set)
1402 self.assertGreaterEqual(len(mask), 1)
1403 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1404 for cpu in mask:
1405 self.assertIsInstance(cpu, int)
1406 self.assertGreaterEqual(cpu, 0)
1407 self.assertLess(cpu, 1 << 32)
1408
1409 @requires_sched_affinity
1410 def test_sched_setaffinity(self):
1411 mask = posix.sched_getaffinity(0)
1412 if len(mask) > 1:
1413 # Empty masks are forbidden
1414 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001415 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001416 self.assertEqual(posix.sched_getaffinity(0), mask)
1417 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1418 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001419 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001420 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001421 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1422
Victor Stinner8b905bd2011-10-25 13:34:04 +02001423 def test_rtld_constants(self):
1424 # check presence of major RTLD_* constants
1425 posix.RTLD_LAZY
1426 posix.RTLD_NOW
1427 posix.RTLD_GLOBAL
1428 posix.RTLD_LOCAL
1429
Jesus Cea60c13dd2012-06-23 02:58:14 +02001430 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1431 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001432 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001433 # Even if the filesystem doesn't report holes,
1434 # if the OS supports it the SEEK_* constants
1435 # will be defined and will have a consistent
1436 # behaviour:
1437 # os.SEEK_DATA = current position
1438 # os.SEEK_HOLE = end of file position
Hai Shibb0424b2020-08-04 00:47:42 +08001439 with open(os_helper.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001440 fp.write(b"hello")
1441 fp.flush()
1442 size = fp.tell()
1443 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001444 try :
1445 for i in range(size):
1446 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1447 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1448 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1449 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1450 except OSError :
1451 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1452 # but it is not true.
1453 # For instance:
1454 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1455 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001456
Larry Hastingsb0827312014-02-09 22:05:19 -08001457 def test_path_error2(self):
1458 """
1459 Test functions that call path_error2(), providing two filenames in their exceptions.
1460 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001461 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001462 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001463 if function is None:
1464 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001465
Hai Shibb0424b2020-08-04 00:47:42 +08001466 for dst in ("noodly2", os_helper.TESTFN):
Victor Stinnerbed04a72014-10-05 17:37:59 +02001467 try:
1468 function('doesnotexistfilename', dst)
1469 except OSError as e:
1470 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1471 break
1472 else:
1473 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001474
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001475 def test_path_with_null_character(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001476 fn = os_helper.TESTFN
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001477 fn_with_NUL = fn + '\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001478 self.addCleanup(os_helper.unlink, fn)
1479 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001480 fd = None
1481 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001482 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001483 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1484 finally:
1485 if fd is not None:
1486 os.close(fd)
1487 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001488 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001489 self.assertFalse(os.path.exists(fn))
1490 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001491 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001492
1493 def test_path_with_null_byte(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001494 fn = os.fsencode(os_helper.TESTFN)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001495 fn_with_NUL = fn + b'\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001496 self.addCleanup(os_helper.unlink, fn)
1497 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001498 fd = None
1499 try:
1500 with self.assertRaises(ValueError):
1501 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1502 finally:
1503 if fd is not None:
1504 os.close(fd)
1505 self.assertFalse(os.path.exists(fn))
1506 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1507 self.assertFalse(os.path.exists(fn))
1508 open(fn, 'wb').close()
1509 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1510
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001511 @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1512 def test_pidfd_open(self):
1513 with self.assertRaises(OSError) as cm:
1514 os.pidfd_open(-1)
1515 if cm.exception.errno == errno.ENOSYS:
1516 self.skipTest("system does not support pidfd_open")
Victor Stinner3ab479a2019-11-21 12:54:54 +01001517 if isinstance(cm.exception, PermissionError):
1518 self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}")
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001519 self.assertEqual(cm.exception.errno, errno.EINVAL)
1520 os.close(os.pidfd_open(os.getpid(), 0))
1521
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001522class PosixGroupsTester(unittest.TestCase):
1523
1524 def setUp(self):
1525 if posix.getuid() != 0:
1526 raise unittest.SkipTest("not enough privileges")
1527 if not hasattr(posix, 'getgroups'):
1528 raise unittest.SkipTest("need posix.getgroups")
1529 if sys.platform == 'darwin':
1530 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1531 self.saved_groups = posix.getgroups()
1532
1533 def tearDown(self):
1534 if hasattr(posix, 'setgroups'):
1535 posix.setgroups(self.saved_groups)
1536 elif hasattr(posix, 'initgroups'):
1537 name = pwd.getpwuid(posix.getuid()).pw_name
1538 posix.initgroups(name, self.saved_groups[0])
1539
1540 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1541 "test needs posix.initgroups()")
1542 def test_initgroups(self):
1543 # find missing group
1544
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001545 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001546 name = pwd.getpwuid(posix.getuid()).pw_name
1547 posix.initgroups(name, g)
1548 self.assertIn(g, posix.getgroups())
1549
1550 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1551 "test needs posix.setgroups()")
1552 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001553 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001554 posix.setgroups(groups)
1555 self.assertListEqual(groups, posix.getgroups())
1556
Serhiy Storchakaef347532018-05-01 16:45:04 +03001557
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001558class _PosixSpawnMixin:
1559 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001560 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001561 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001562
1563 def python_args(self, *args):
1564 # Disable site module to avoid side effects. For example,
1565 # on Fedora 28, if the HOME environment variable is not set,
1566 # site._getuserbase() calls pwd.getpwuid() which opens
1567 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1568 # test_close_file() to fail.
1569 return (sys.executable, '-I', '-S', *args)
1570
Serhiy Storchakaef347532018-05-01 16:45:04 +03001571 def test_returns_pid(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001572 pidfile = os_helper.TESTFN
1573 self.addCleanup(os_helper.unlink, pidfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001574 script = f"""if 1:
1575 import os
1576 with open({pidfile!r}, "w") as pidfile:
1577 pidfile.write(str(os.getpid()))
1578 """
Victor Stinner03824062018-08-30 01:21:11 +02001579 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001580 pid = self.spawn_func(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001581 support.wait_process(pid, exitcode=0)
Inada Naoki4663e5f2021-04-06 13:02:22 +09001582 with open(pidfile, encoding="utf-8") as f:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001583 self.assertEqual(f.read(), str(pid))
1584
1585 def test_no_such_executable(self):
1586 no_such_executable = 'no_such_executable'
1587 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001588 pid = self.spawn_func(no_such_executable,
1589 [no_such_executable],
1590 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001591 # bpo-35794: PermissionError can be raised if there are
1592 # directories in the $PATH that are not accessible.
1593 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001594 self.assertEqual(exc.filename, no_such_executable)
1595 else:
1596 pid2, status = os.waitpid(pid, 0)
1597 self.assertEqual(pid2, pid)
1598 self.assertNotEqual(status, 0)
1599
1600 def test_specify_environment(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001601 envfile = os_helper.TESTFN
1602 self.addCleanup(os_helper.unlink, envfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001603 script = f"""if 1:
1604 import os
Inada Naoki4663e5f2021-04-06 13:02:22 +09001605 with open({envfile!r}, "w", encoding="utf-8") as envfile:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001606 envfile.write(os.environ['foo'])
1607 """
Victor Stinner03824062018-08-30 01:21:11 +02001608 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001609 pid = self.spawn_func(args[0], args,
1610 {**os.environ, 'foo': 'bar'})
Victor Stinner278c1e12020-03-31 20:08:12 +02001611 support.wait_process(pid, exitcode=0)
Inada Naoki4663e5f2021-04-06 13:02:22 +09001612 with open(envfile, encoding="utf-8") as f:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001613 self.assertEqual(f.read(), 'bar')
1614
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001615 def test_none_file_actions(self):
1616 pid = self.spawn_func(
1617 self.NOOP_PROGRAM[0],
1618 self.NOOP_PROGRAM,
1619 os.environ,
1620 file_actions=None
1621 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001622 support.wait_process(pid, exitcode=0)
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001623
Serhiy Storchakaef347532018-05-01 16:45:04 +03001624 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001625 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001626 self.NOOP_PROGRAM[0],
1627 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001628 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001629 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001630 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001631 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001632
Pablo Galindo254a4662018-09-07 16:44:24 +01001633 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001634 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001635 sys.executable,
1636 [sys.executable, '-c', 'pass'],
1637 os.environ,
1638 resetids=False
1639 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001640 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001641
1642 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001643 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001644 sys.executable,
1645 [sys.executable, '-c', 'pass'],
1646 os.environ,
1647 resetids=True
1648 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001649 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001650
1651 def test_resetids_wrong_type(self):
1652 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001653 self.spawn_func(sys.executable,
1654 [sys.executable, "-c", "pass"],
1655 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001656
1657 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001658 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001659 sys.executable,
1660 [sys.executable, '-c', 'pass'],
1661 os.environ,
1662 setpgroup=os.getpgrp()
1663 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001664 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001665
1666 def test_setpgroup_wrong_type(self):
1667 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001668 self.spawn_func(sys.executable,
1669 [sys.executable, "-c", "pass"],
1670 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001671
1672 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1673 'need signal.pthread_sigmask()')
1674 def test_setsigmask(self):
1675 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001676 import signal
1677 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001678
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001679 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001680 sys.executable,
1681 [sys.executable, '-c', code],
1682 os.environ,
1683 setsigmask=[signal.SIGUSR1]
1684 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001685 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001686
1687 def test_setsigmask_wrong_type(self):
1688 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001689 self.spawn_func(sys.executable,
1690 [sys.executable, "-c", "pass"],
1691 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001692 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001693 self.spawn_func(sys.executable,
1694 [sys.executable, "-c", "pass"],
1695 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001696 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001697 self.spawn_func(sys.executable,
1698 [sys.executable, "-c", "pass"],
1699 os.environ, setsigmask=[signal.NSIG,
1700 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001701
Victor Stinner58840432019-06-14 19:31:43 +02001702 def test_setsid(self):
1703 rfd, wfd = os.pipe()
1704 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001705 try:
Victor Stinner58840432019-06-14 19:31:43 +02001706 os.set_inheritable(wfd, True)
1707
1708 code = textwrap.dedent(f"""
1709 import os
1710 fd = {wfd}
1711 sid = os.getsid(0)
1712 os.write(fd, str(sid).encode())
1713 """)
1714
1715 try:
1716 pid = self.spawn_func(sys.executable,
1717 [sys.executable, "-c", code],
1718 os.environ, setsid=True)
1719 except NotImplementedError as exc:
1720 self.skipTest(f"setsid is not supported: {exc!r}")
1721 except PermissionError as exc:
1722 self.skipTest(f"setsid failed with: {exc!r}")
1723 finally:
1724 os.close(wfd)
1725
Victor Stinner278c1e12020-03-31 20:08:12 +02001726 support.wait_process(pid, exitcode=0)
1727
Victor Stinner58840432019-06-14 19:31:43 +02001728 output = os.read(rfd, 100)
1729 child_sid = int(output)
1730 parent_sid = os.getsid(os.getpid())
1731 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001732
Pablo Galindo254a4662018-09-07 16:44:24 +01001733 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1734 'need signal.pthread_sigmask()')
1735 def test_setsigdef(self):
1736 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1737 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001738 import signal
1739 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001740 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001741 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001742 sys.executable,
1743 [sys.executable, '-c', code],
1744 os.environ,
1745 setsigdef=[signal.SIGUSR1]
1746 )
1747 finally:
1748 signal.signal(signal.SIGUSR1, original_handler)
1749
Victor Stinner278c1e12020-03-31 20:08:12 +02001750 support.wait_process(pid, exitcode=-signal.SIGUSR1)
Pablo Galindo254a4662018-09-07 16:44:24 +01001751
1752 def test_setsigdef_wrong_type(self):
1753 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001754 self.spawn_func(sys.executable,
1755 [sys.executable, "-c", "pass"],
1756 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001757 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001758 self.spawn_func(sys.executable,
1759 [sys.executable, "-c", "pass"],
1760 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001761 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001762 self.spawn_func(sys.executable,
1763 [sys.executable, "-c", "pass"],
1764 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001765
Benjamin Petersonc7042222018-09-12 15:12:24 -07001766 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001767 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1768 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001769 def test_setscheduler_only_param(self):
1770 policy = os.sched_getscheduler(0)
1771 priority = os.sched_get_priority_min(policy)
1772 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001773 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001774 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001775 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001776 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001777 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001778 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001779 sys.executable,
1780 [sys.executable, '-c', code],
1781 os.environ,
1782 scheduler=(None, os.sched_param(priority))
1783 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001784 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001785
Benjamin Petersonc7042222018-09-12 15:12:24 -07001786 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001787 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1788 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001789 def test_setscheduler_with_policy(self):
1790 policy = os.sched_getscheduler(0)
1791 priority = os.sched_get_priority_min(policy)
1792 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001793 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001794 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001795 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001796 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001797 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001798 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001799 sys.executable,
1800 [sys.executable, '-c', code],
1801 os.environ,
1802 scheduler=(policy, os.sched_param(priority))
1803 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001804 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001805
Serhiy Storchakaef347532018-05-01 16:45:04 +03001806 def test_multiple_file_actions(self):
1807 file_actions = [
1808 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1809 (os.POSIX_SPAWN_CLOSE, 0),
1810 (os.POSIX_SPAWN_DUP2, 1, 4),
1811 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001812 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1813 self.NOOP_PROGRAM,
1814 os.environ,
1815 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001816 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001817
1818 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001819 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001820 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001821 self.spawn_func(args[0], args, os.environ,
1822 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001823 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001824 self.spawn_func(args[0], args, os.environ,
1825 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001826 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001827 self.spawn_func(args[0], args, os.environ,
1828 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001829 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001830 self.spawn_func(args[0], args, os.environ,
1831 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001832 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001833 self.spawn_func(args[0], args, os.environ,
1834 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001835 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001836 self.spawn_func(args[0], args, os.environ,
1837 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001838 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001839 self.spawn_func(args[0], args, os.environ,
1840 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001841 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001842 self.spawn_func(args[0], args, os.environ,
1843 file_actions=[(os.POSIX_SPAWN_OPEN,
1844 3, __file__ + '\0',
1845 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001846
1847 def test_open_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001848 outfile = os_helper.TESTFN
1849 self.addCleanup(os_helper.unlink, outfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001850 script = """if 1:
1851 import sys
1852 sys.stdout.write("hello")
1853 """
1854 file_actions = [
1855 (os.POSIX_SPAWN_OPEN, 1, outfile,
1856 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1857 stat.S_IRUSR | stat.S_IWUSR),
1858 ]
Victor Stinner03824062018-08-30 01:21:11 +02001859 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001860 pid = self.spawn_func(args[0], args, os.environ,
1861 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001862
1863 support.wait_process(pid, exitcode=0)
Inada Naoki4663e5f2021-04-06 13:02:22 +09001864 with open(outfile, encoding="utf-8") as f:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001865 self.assertEqual(f.read(), 'hello')
1866
1867 def test_close_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001868 closefile = os_helper.TESTFN
1869 self.addCleanup(os_helper.unlink, closefile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001870 script = f"""if 1:
1871 import os
1872 try:
1873 os.fstat(0)
1874 except OSError as e:
Inada Naoki4663e5f2021-04-06 13:02:22 +09001875 with open({closefile!r}, 'w', encoding='utf-8') as closefile:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001876 closefile.write('is closed %d' % e.errno)
1877 """
Victor Stinner03824062018-08-30 01:21:11 +02001878 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001879 pid = self.spawn_func(args[0], args, os.environ,
1880 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Victor Stinner278c1e12020-03-31 20:08:12 +02001881
1882 support.wait_process(pid, exitcode=0)
Inada Naoki4663e5f2021-04-06 13:02:22 +09001883 with open(closefile, encoding="utf-8") as f:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001884 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1885
1886 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001887 dupfile = os_helper.TESTFN
1888 self.addCleanup(os_helper.unlink, dupfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001889 script = """if 1:
1890 import sys
1891 sys.stdout.write("hello")
1892 """
1893 with open(dupfile, "wb") as childfile:
1894 file_actions = [
1895 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1896 ]
Victor Stinner03824062018-08-30 01:21:11 +02001897 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001898 pid = self.spawn_func(args[0], args, os.environ,
1899 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001900 support.wait_process(pid, exitcode=0)
Inada Naoki4663e5f2021-04-06 13:02:22 +09001901 with open(dupfile, encoding="utf-8") as f:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001902 self.assertEqual(f.read(), 'hello')
1903
1904
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001905@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1906class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1907 spawn_func = getattr(posix, 'posix_spawn', None)
1908
1909
1910@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1911class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1912 spawn_func = getattr(posix, 'posix_spawnp', None)
1913
Hai Shibb0424b2020-08-04 00:47:42 +08001914 @os_helper.skip_unless_symlink
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001915 def test_posix_spawnp(self):
1916 # Use a symlink to create a program in its own temporary directory
1917 temp_dir = tempfile.mkdtemp()
Hai Shibb0424b2020-08-04 00:47:42 +08001918 self.addCleanup(os_helper.rmtree, temp_dir)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001919
1920 program = 'posix_spawnp_test_program.exe'
1921 program_fullpath = os.path.join(temp_dir, program)
1922 os.symlink(sys.executable, program_fullpath)
1923
1924 try:
1925 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1926 except KeyError:
1927 path = temp_dir # PATH is not set
1928
1929 spawn_args = (program, '-I', '-S', '-c', 'pass')
1930 code = textwrap.dedent("""
1931 import os
Victor Stinner278c1e12020-03-31 20:08:12 +02001932 from test import support
1933
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001934 args = %a
1935 pid = os.posix_spawnp(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001936
1937 support.wait_process(pid, exitcode=0)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001938 """ % (spawn_args,))
1939
1940 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1941 # environment variable: posix_spawnp() uses the current environment
1942 # to locate the program, not its environment argument.
1943 args = ('-c', code)
1944 assert_python_ok(*args, PATH=path)
1945
1946
Ronald Oussoren41761932020-11-08 10:05:27 +01001947@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
1948class TestPosixWeaklinking(unittest.TestCase):
1949 # These test cases verify that weak linking support on macOS works
1950 # as expected. These cases only test new behaviour introduced by weak linking,
pxinwrb2d0c662020-12-01 16:20:50 +08001951 # regular behaviour is tested by the normal test cases.
Ronald Oussoren41761932020-11-08 10:05:27 +01001952 #
1953 # See the section on Weak Linking in Mac/README.txt for more information.
1954 def setUp(self):
1955 import sysconfig
1956 import platform
1957
1958 config_vars = sysconfig.get_config_vars()
1959 self.available = { nm for nm in config_vars if nm.startswith("HAVE_") and config_vars[nm] }
1960 self.mac_ver = tuple(int(part) for part in platform.mac_ver()[0].split("."))
1961
1962 def _verify_available(self, name):
1963 if name not in self.available:
1964 raise unittest.SkipTest(f"{name} not weak-linked")
1965
1966 def test_pwritev(self):
1967 self._verify_available("HAVE_PWRITEV")
1968 if self.mac_ver >= (10, 16):
1969 self.assertTrue(hasattr(os, "pwritev"), "os.pwritev is not available")
1970 self.assertTrue(hasattr(os, "preadv"), "os.readv is not available")
1971
1972 else:
1973 self.assertFalse(hasattr(os, "pwritev"), "os.pwritev is available")
1974 self.assertFalse(hasattr(os, "preadv"), "os.readv is available")
1975
1976 def test_stat(self):
1977 self._verify_available("HAVE_FSTATAT")
1978 if self.mac_ver >= (10, 10):
1979 self.assertIn("HAVE_FSTATAT", posix._have_functions)
1980
1981 else:
1982 self.assertNotIn("HAVE_FSTATAT", posix._have_functions)
1983
1984 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1985 os.stat("file", dir_fd=0)
1986
1987 def test_access(self):
1988 self._verify_available("HAVE_FACCESSAT")
1989 if self.mac_ver >= (10, 10):
1990 self.assertIn("HAVE_FACCESSAT", posix._have_functions)
1991
1992 else:
1993 self.assertNotIn("HAVE_FACCESSAT", posix._have_functions)
1994
1995 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1996 os.access("file", os.R_OK, dir_fd=0)
1997
1998 with self.assertRaisesRegex(NotImplementedError, "follow_symlinks unavailable"):
1999 os.access("file", os.R_OK, follow_symlinks=False)
2000
2001 with self.assertRaisesRegex(NotImplementedError, "effective_ids unavailable"):
2002 os.access("file", os.R_OK, effective_ids=True)
2003
2004 def test_chmod(self):
2005 self._verify_available("HAVE_FCHMODAT")
2006 if self.mac_ver >= (10, 10):
2007 self.assertIn("HAVE_FCHMODAT", posix._have_functions)
2008
2009 else:
2010 self.assertNotIn("HAVE_FCHMODAT", posix._have_functions)
2011 self.assertIn("HAVE_LCHMOD", posix._have_functions)
2012
2013 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2014 os.chmod("file", 0o644, dir_fd=0)
2015
2016 def test_chown(self):
2017 self._verify_available("HAVE_FCHOWNAT")
2018 if self.mac_ver >= (10, 10):
2019 self.assertIn("HAVE_FCHOWNAT", posix._have_functions)
2020
2021 else:
2022 self.assertNotIn("HAVE_FCHOWNAT", posix._have_functions)
2023 self.assertIn("HAVE_LCHOWN", posix._have_functions)
2024
2025 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2026 os.chown("file", 0, 0, dir_fd=0)
2027
2028 def test_link(self):
2029 self._verify_available("HAVE_LINKAT")
2030 if self.mac_ver >= (10, 10):
2031 self.assertIn("HAVE_LINKAT", posix._have_functions)
2032
2033 else:
2034 self.assertNotIn("HAVE_LINKAT", posix._have_functions)
2035
2036 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2037 os.link("source", "target", src_dir_fd=0)
2038
2039 with self.assertRaisesRegex(NotImplementedError, "dst_dir_fd unavailable"):
2040 os.link("source", "target", dst_dir_fd=0)
2041
2042 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2043 os.link("source", "target", src_dir_fd=0, dst_dir_fd=0)
2044
2045 # issue 41355: !HAVE_LINKAT code path ignores the follow_symlinks flag
2046 with os_helper.temp_dir() as base_path:
2047 link_path = os.path.join(base_path, "link")
2048 target_path = os.path.join(base_path, "target")
2049 source_path = os.path.join(base_path, "source")
2050
2051 with open(source_path, "w") as fp:
2052 fp.write("data")
2053
2054 os.symlink("target", link_path)
2055
2056 # Calling os.link should fail in the link(2) call, and
2057 # should not reject *follow_symlinks* (to match the
2058 # behaviour you'd get when building on a platform without
2059 # linkat)
2060 with self.assertRaises(FileExistsError):
2061 os.link(source_path, link_path, follow_symlinks=True)
2062
2063 with self.assertRaises(FileExistsError):
2064 os.link(source_path, link_path, follow_symlinks=False)
2065
2066
2067 def test_listdir_scandir(self):
2068 self._verify_available("HAVE_FDOPENDIR")
2069 if self.mac_ver >= (10, 10):
2070 self.assertIn("HAVE_FDOPENDIR", posix._have_functions)
2071
2072 else:
2073 self.assertNotIn("HAVE_FDOPENDIR", posix._have_functions)
2074
2075 with self.assertRaisesRegex(TypeError, "listdir: path should be string, bytes, os.PathLike or None, not int"):
2076 os.listdir(0)
2077
2078 with self.assertRaisesRegex(TypeError, "scandir: path should be string, bytes, os.PathLike or None, not int"):
2079 os.scandir(0)
2080
2081 def test_mkdir(self):
2082 self._verify_available("HAVE_MKDIRAT")
2083 if self.mac_ver >= (10, 10):
2084 self.assertIn("HAVE_MKDIRAT", posix._have_functions)
2085
2086 else:
2087 self.assertNotIn("HAVE_MKDIRAT", posix._have_functions)
2088
2089 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2090 os.mkdir("dir", dir_fd=0)
2091
2092 def test_rename_replace(self):
2093 self._verify_available("HAVE_RENAMEAT")
2094 if self.mac_ver >= (10, 10):
2095 self.assertIn("HAVE_RENAMEAT", posix._have_functions)
2096
2097 else:
2098 self.assertNotIn("HAVE_RENAMEAT", posix._have_functions)
2099
2100 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2101 os.rename("a", "b", src_dir_fd=0)
2102
2103 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2104 os.rename("a", "b", dst_dir_fd=0)
2105
2106 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2107 os.replace("a", "b", src_dir_fd=0)
2108
2109 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2110 os.replace("a", "b", dst_dir_fd=0)
2111
2112 def test_unlink_rmdir(self):
2113 self._verify_available("HAVE_UNLINKAT")
2114 if self.mac_ver >= (10, 10):
2115 self.assertIn("HAVE_UNLINKAT", posix._have_functions)
2116
2117 else:
2118 self.assertNotIn("HAVE_UNLINKAT", posix._have_functions)
2119
2120 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2121 os.unlink("path", dir_fd=0)
2122
2123 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2124 os.rmdir("path", dir_fd=0)
2125
2126 def test_open(self):
2127 self._verify_available("HAVE_OPENAT")
2128 if self.mac_ver >= (10, 10):
2129 self.assertIn("HAVE_OPENAT", posix._have_functions)
2130
2131 else:
2132 self.assertNotIn("HAVE_OPENAT", posix._have_functions)
2133
2134 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2135 os.open("path", os.O_RDONLY, dir_fd=0)
2136
2137 def test_readlink(self):
2138 self._verify_available("HAVE_READLINKAT")
2139 if self.mac_ver >= (10, 10):
2140 self.assertIn("HAVE_READLINKAT", posix._have_functions)
2141
2142 else:
2143 self.assertNotIn("HAVE_READLINKAT", posix._have_functions)
2144
2145 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2146 os.readlink("path", dir_fd=0)
2147
2148 def test_symlink(self):
2149 self._verify_available("HAVE_SYMLINKAT")
2150 if self.mac_ver >= (10, 10):
2151 self.assertIn("HAVE_SYMLINKAT", posix._have_functions)
2152
2153 else:
2154 self.assertNotIn("HAVE_SYMLINKAT", posix._have_functions)
2155
2156 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2157 os.symlink("a", "b", dir_fd=0)
2158
2159 def test_utime(self):
2160 self._verify_available("HAVE_FUTIMENS")
2161 self._verify_available("HAVE_UTIMENSAT")
2162 if self.mac_ver >= (10, 13):
2163 self.assertIn("HAVE_FUTIMENS", posix._have_functions)
2164 self.assertIn("HAVE_UTIMENSAT", posix._have_functions)
2165
2166 else:
2167 self.assertNotIn("HAVE_FUTIMENS", posix._have_functions)
2168 self.assertNotIn("HAVE_UTIMENSAT", posix._have_functions)
2169
2170 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2171 os.utime("path", dir_fd=0)
2172
2173
Neal Norwitze241ce82003-02-17 18:17:05 +00002174def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01002175 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002176 support.run_unittest(
2177 PosixTester,
2178 PosixGroupsTester,
2179 TestPosixSpawn,
2180 TestPosixSpawnP,
Ronald Oussoren41761932020-11-08 10:05:27 +01002181 TestPosixWeaklinking
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002182 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01002183 finally:
2184 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00002185
2186if __name__ == '__main__':
2187 test_main()