blob: cd18a4972fa2c73f24eecf1325f04b8b56310796 [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
Hai Shibb0424b2020-08-04 00:47:42 +080048 fp = open(os_helper.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000049 fp.close()
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
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200727 if uid == 0:
728 # Try an amusingly large uid/gid to make sure we handle
729 # large unsigned values. (chown lets you use any
730 # uid/gid you like, even if they aren't defined.)
731 #
732 # This problem keeps coming up:
733 # http://bugs.python.org/issue1747858
734 # http://bugs.python.org/issue4591
735 # http://bugs.python.org/issue15301
736 # Hopefully the fix in 4591 fixes it for good!
737 #
738 # This part of the test only runs when run as root.
739 # Only scary people run their tests as root.
740
741 big_value = 2**31
742 chown_func(first_param, big_value, big_value)
743 check_stat(big_value, big_value)
744 chown_func(first_param, -1, -1)
745 check_stat(big_value, big_value)
746 chown_func(first_param, uid, gid)
747 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200748 elif platform.system() in ('HP-UX', 'SunOS'):
749 # HP-UX and Solaris can allow a non-root user to chown() to root
750 # (issue #5113)
751 raise unittest.SkipTest("Skipping because of non-standard chown() "
752 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000753 else:
754 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200755 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200756 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200757 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200758 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200759 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200760 self.assertRaises(OSError, chown_func, first_param, -1, 0)
761 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200762 # test illegal types
763 for t in str, float:
764 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
765 check_stat(uid, gid)
766 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
767 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000768
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000769 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
770 def test_chown(self):
771 # raise an OSError if the file does not exist
Hai Shibb0424b2020-08-04 00:47:42 +0800772 os.unlink(os_helper.TESTFN)
773 self.assertRaises(OSError, posix.chown, os_helper.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000774
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000775 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800776 os_helper.create_empty_file(os_helper.TESTFN)
777 self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000778
779 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
780 def test_fchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800781 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000782
783 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800784 test_file = open(os_helper.TESTFN, 'w')
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000785 try:
786 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200787 self._test_all_chown_common(posix.fchown, fd,
788 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000789 finally:
790 test_file.close()
791
792 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
793 def test_lchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800794 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000795 # create a symlink
Hai Shibb0424b2020-08-04 00:47:42 +0800796 os.symlink(_DUMMY_SYMLINK, os_helper.TESTFN)
797 self._test_all_chown_common(posix.lchown, os_helper.TESTFN,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200798 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000799
Serhiy Storchaka43767632013-11-03 21:31:38 +0200800 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000801 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200802 posix.chdir(os.curdir)
Hai Shibb0424b2020-08-04 00:47:42 +0800803 self.assertRaises(OSError, posix.chdir, os_helper.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000804
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000805 def test_listdir(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800806 self.assertIn(os_helper.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000807
808 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700809 # When listdir is called without argument,
810 # it's the same as listdir(os.curdir).
Hai Shibb0424b2020-08-04 00:47:42 +0800811 self.assertIn(os_helper.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000812
Larry Hastingsfdaea062012-06-25 04:42:23 -0700813 def test_listdir_bytes(self):
814 # When listdir is called with a bytes object,
815 # the returned strings are of type bytes.
Hai Shibb0424b2020-08-04 00:47:42 +0800816 self.assertIn(os.fsencode(os_helper.TESTFN), posix.listdir(b'.'))
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300817
818 def test_listdir_bytes_like(self):
819 for cls in bytearray, memoryview:
820 with self.assertWarns(DeprecationWarning):
821 names = posix.listdir(cls(b'.'))
Hai Shibb0424b2020-08-04 00:47:42 +0800822 self.assertIn(os.fsencode(os_helper.TESTFN), names)
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300823 for name in names:
824 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700825
826 @unittest.skipUnless(posix.listdir in os.supports_fd,
827 "test needs fd support for posix.listdir()")
828 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000829 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100830 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000831 self.assertEqual(
832 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700833 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000834 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100835 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100836 self.assertEqual(
837 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100839 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000840
Serhiy Storchaka43767632013-11-03 21:31:38 +0200841 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000842 def test_access(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800843 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000844
Serhiy Storchaka43767632013-11-03 21:31:38 +0200845 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000846 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200847 old_mask = posix.umask(0)
848 self.assertIsInstance(old_mask, int)
849 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000850
Serhiy Storchaka43767632013-11-03 21:31:38 +0200851 @unittest.skipUnless(hasattr(posix, 'strerror'),
852 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000853 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200854 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000855
Serhiy Storchaka43767632013-11-03 21:31:38 +0200856 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000857 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200858 reader, writer = posix.pipe()
859 os.close(reader)
860 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000861
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200862 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200863 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200864 def test_pipe2(self):
865 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
866 self.assertRaises(TypeError, os.pipe2, 0, 0)
867
Charles-François Natali368f34b2011-06-06 19:49:47 +0200868 # try calling with flags = 0, like os.pipe()
869 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200870 os.close(r)
871 os.close(w)
872
873 # test flags
874 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
875 self.addCleanup(os.close, r)
876 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200877 self.assertFalse(os.get_inheritable(r))
878 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200879 self.assertFalse(os.get_blocking(r))
880 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200881 # try reading from an empty pipe: this should fail, not block
882 self.assertRaises(OSError, os.read, r, 1)
883 # try a write big enough to fill-up the pipe: this should either
884 # fail or perform a partial write, not block
885 try:
886 os.write(w, b'x' * support.PIPE_MAX_SIZE)
887 except OSError:
888 pass
889
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200890 @support.cpython_only
891 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
892 @support.requires_linux_version(2, 6, 27)
893 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200894 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200895 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200896 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
897 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
898
Serhiy Storchaka43767632013-11-03 21:31:38 +0200899 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000900 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200901 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800902 posix.utime(os_helper.TESTFN, None)
903 self.assertRaises(TypeError, posix.utime,
904 os_helper.TESTFN, (None, None))
905 self.assertRaises(TypeError, posix.utime,
906 os_helper.TESTFN, (now, None))
907 self.assertRaises(TypeError, posix.utime,
908 os_helper.TESTFN, (None, now))
909 posix.utime(os_helper.TESTFN, (int(now), int(now)))
910 posix.utime(os_helper.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000911
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700913 st = os.stat(target_file)
914 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000915
916 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
917 flags = st.st_flags | stat.UF_IMMUTABLE
918 try:
919 chflags_func(target_file, flags, **kwargs)
920 except OSError as err:
921 if err.errno != errno.EOPNOTSUPP:
922 raise
923 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
924 self.skipTest(msg)
925
Ned Deily3eb67d52011-06-28 00:00:28 -0700926 try:
927 new_st = os.stat(target_file)
928 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
929 try:
930 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200931 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700932 self.assertEqual(e.errno, errno.EPERM)
933 finally:
934 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000935
Ned Deily3eb67d52011-06-28 00:00:28 -0700936 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
937 def test_chflags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800938 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700939
940 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
941 def test_lchflags_regular_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800942 self._test_chflags_regular_file(posix.lchflags, os_helper.TESTFN)
943 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN,
944 follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700945
946 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
947 def test_lchflags_symlink(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800948 testfn_st = os.stat(os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700949
950 self.assertTrue(hasattr(testfn_st, 'st_flags'))
951
Hai Shibb0424b2020-08-04 00:47:42 +0800952 os.symlink(os_helper.TESTFN, _DUMMY_SYMLINK)
Ned Deily3eb67d52011-06-28 00:00:28 -0700953 self.teardown_files.append(_DUMMY_SYMLINK)
954 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
955
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956 def chflags_nofollow(path, flags):
957 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700958
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000960 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
961 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
962 try:
963 fn(_DUMMY_SYMLINK, flags)
964 except OSError as err:
965 if err.errno != errno.EOPNOTSUPP:
966 raise
967 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
968 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800970 new_testfn_st = os.stat(os_helper.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700971 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
972
973 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
974 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
975 new_dummy_symlink_st.st_flags)
976 finally:
977 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000978
Guido van Rossum98297ee2007-11-06 21:34:58 +0000979 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000980 if os.name == "nt":
981 item_type = str
982 else:
983 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000984 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000985 self.assertEqual(type(k), item_type)
986 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000987
Serhiy Storchaka77703942017-06-25 07:33:01 +0300988 def test_putenv(self):
989 with self.assertRaises(ValueError):
990 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
991 with self.assertRaises(ValueError):
992 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
993 with self.assertRaises(ValueError):
994 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
995 with self.assertRaises(ValueError):
996 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
997 with self.assertRaises(ValueError):
998 os.putenv('FRUIT=ORANGE', 'lemon')
999 with self.assertRaises(ValueError):
1000 os.putenv(b'FRUIT=ORANGE', b'lemon')
1001
Serhiy Storchaka43767632013-11-03 21:31:38 +02001002 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001003 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001004 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
1005 curdir = os.getcwd()
Hai Shibb0424b2020-08-04 00:47:42 +08001006 base_path = os.path.abspath(os_helper.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001007
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001008 try:
1009 os.mkdir(base_path)
1010 os.chdir(base_path)
1011 except:
1012 # Just returning nothing instead of the SkipTest exception, because
1013 # the test results in Error in that case. Is that ok?
1014 # raise unittest.SkipTest("cannot create directory for testing")
1015 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001017 def _create_and_do_getcwd(dirname, current_path_length = 0):
1018 try:
1019 os.mkdir(dirname)
1020 except:
1021 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001022
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001023 os.chdir(dirname)
1024 try:
1025 os.getcwd()
1026 if current_path_length < 1027:
1027 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1028 finally:
1029 os.chdir('..')
1030 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001031
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001032 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001033
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001034 finally:
1035 os.chdir(curdir)
Hai Shibb0424b2020-08-04 00:47:42 +08001036 os_helper.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001037
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001038 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1039 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1040 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1041 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001042 user = pwd.getpwuid(os.getuid())[0]
1043 group = pwd.getpwuid(os.getuid())[3]
1044 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001045
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001046
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001047 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
pxinwre1e3c2d2020-12-16 05:20:07 +08001048 @unittest.skipUnless(hasattr(os, 'popen'), "test needs os.popen()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001049 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001050 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001051 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001052 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001053
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001054 try:
1055 idg_groups = set(int(g) for g in groups.split())
1056 except ValueError:
1057 idg_groups = set()
1058 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001059 raise unittest.SkipTest("need working 'id -G'")
1060
Ned Deily028915e2013-02-02 15:08:52 -08001061 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1062 if sys.platform == 'darwin':
1063 import sysconfig
1064 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
FX Coudert52916392020-12-03 04:20:18 +01001065 if tuple(int(n) for n in str(dt).split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001066 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1067
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001068 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001069 # groups, ignoring order, duplicates, and the effective gid.
1070 # #10822/#26944 - It is implementation defined whether
1071 # posix.getgroups() includes the effective gid.
1072 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1073 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001074
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001075 # tests for the posix *at functions follow
1076
Larry Hastings9cf065c2012-06-22 16:30:09 -07001077 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1078 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001079 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1080 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001081 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001082 finally:
1083 posix.close(f)
1084
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1086 def test_chmod_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001087 os.chmod(os_helper.TESTFN, stat.S_IRUSR)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001088
1089 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1090 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001091 posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001092
Hai Shibb0424b2020-08-04 00:47:42 +08001093 s = posix.stat(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001094 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1095 finally:
1096 posix.close(f)
1097
pxinwreb7594f2020-12-09 07:18:37 +08001098 @unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd),
1099 "test needs dir_fd support in os.chown()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 def test_chown_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001101 os_helper.unlink(os_helper.TESTFN)
1102 os_helper.create_empty_file(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001103
1104 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1105 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001106 posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001107 finally:
1108 posix.close(f)
1109
Larry Hastings9cf065c2012-06-22 16:30:09 -07001110 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1111 def test_stat_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001112 os_helper.unlink(os_helper.TESTFN)
1113 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001114 outfile.write("testline\n")
1115
1116 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1117 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001118 s1 = posix.stat(os_helper.TESTFN)
1119 s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001120 self.assertEqual(s1, s2)
Hai Shibb0424b2020-08-04 00:47:42 +08001121 s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001122 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001123 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001124 posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001125 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001126 posix.stat, os_helper.TESTFN, dir_fd=float(f))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001127 self.assertRaises(OverflowError,
Hai Shibb0424b2020-08-04 00:47:42 +08001128 posix.stat, os_helper.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001129 finally:
1130 posix.close(f)
1131
Larry Hastings9cf065c2012-06-22 16:30:09 -07001132 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1133 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001134 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1135 try:
1136 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +08001137 posix.utime(os_helper.TESTFN, None, dir_fd=f)
1138 posix.utime(os_helper.TESTFN, dir_fd=f)
1139 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1140 now, dir_fd=f)
1141 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1142 (None, None), dir_fd=f)
1143 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1144 (now, None), dir_fd=f)
1145 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1146 (None, now), dir_fd=f)
1147 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1148 (now, "x"), dir_fd=f)
1149 posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
1150 posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
1151 posix.utime(os_helper.TESTFN,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001152 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
Hai Shibb0424b2020-08-04 00:47:42 +08001153 posix.utime(os_helper.TESTFN, dir_fd=f,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 times=(int(now), int((now - int(now)) * 1e9)))
1155
Larry Hastings90867a52012-06-22 17:01:41 -07001156 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001158 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001159 posix.utime(os_helper.TESTFN, follow_symlinks=False,
1160 dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001161 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001162 # whoops! using both together not supported on this platform.
1163 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001164
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001165 finally:
1166 posix.close(f)
1167
Larry Hastings9cf065c2012-06-22 16:30:09 -07001168 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1169 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001170 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1171 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001172 posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link',
1173 src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001174 except PermissionError as e:
1175 self.skipTest('posix.link(): %s' % e)
1176 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001177 # should have same inodes
Hai Shibb0424b2020-08-04 00:47:42 +08001178 self.assertEqual(posix.stat(os_helper.TESTFN)[1],
1179 posix.stat(os_helper.TESTFN + 'link')[1])
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001180 finally:
1181 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001182 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001183
Larry Hastings9cf065c2012-06-22 16:30:09 -07001184 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1185 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001186 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1187 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001188 posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
1189 posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001190 finally:
1191 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001192 os_helper.rmtree(os_helper.TESTFN + 'dir')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001193
pxinwreb7594f2020-12-09 07:18:37 +08001194 @unittest.skipUnless(hasattr(os, 'mknod')
1195 and (os.mknod in os.supports_dir_fd)
1196 and hasattr(stat, 'S_IFIFO'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1198 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001199 # Test using mknodat() to create a FIFO (the only use specified
1200 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +08001201 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001202 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1203 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1204 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001205 posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001206 except OSError as e:
1207 # Some old systems don't allow unprivileged users to use
1208 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001209 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001210 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001211 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001212 finally:
1213 posix.close(f)
1214
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1216 def test_open_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001217 os_helper.unlink(os_helper.TESTFN)
1218 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001219 outfile.write("testline\n")
1220 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001221 b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001222 try:
1223 res = posix.read(b, 9).decode(encoding="utf-8")
1224 self.assertEqual("testline\n", res)
1225 finally:
1226 posix.close(a)
1227 posix.close(b)
1228
pxinwreb7594f2020-12-09 07:18:37 +08001229 @unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd),
1230 "test needs dir_fd support in os.readlink()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 def test_readlink_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001232 os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001233 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1234 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001235 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1236 posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001237 finally:
Hai Shibb0424b2020-08-04 00:47:42 +08001238 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001239 posix.close(f)
1240
Larry Hastings9cf065c2012-06-22 16:30:09 -07001241 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1242 def test_rename_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001243 os_helper.unlink(os_helper.TESTFN)
1244 os_helper.create_empty_file(os_helper.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001245 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1246 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001247 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001248 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001249 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001250 raise
1251 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001252 posix.stat(os_helper.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001253 finally:
1254 posix.close(f)
1255
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001256 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1257 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1258 def test_cld_xxxx_constants(self):
1259 os.CLD_EXITED
1260 os.CLD_KILLED
1261 os.CLD_DUMPED
1262 os.CLD_TRAPPED
1263 os.CLD_STOPPED
1264 os.CLD_CONTINUED
1265
Larry Hastings9cf065c2012-06-22 16:30:09 -07001266 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1267 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001268 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1269 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001270 posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link',
1271 dir_fd=f)
1272 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1273 os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001274 finally:
1275 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001276 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001277
Larry Hastings9cf065c2012-06-22 16:30:09 -07001278 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1279 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001280 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001281 os_helper.create_empty_file(os_helper.TESTFN + 'del')
1282 posix.stat(os_helper.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001283 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001284 posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001285 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001286 os_helper.unlink(os_helper.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001287 raise
1288 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001289 self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001290 finally:
1291 posix.close(f)
1292
Larry Hastings9cf065c2012-06-22 16:30:09 -07001293 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1294 def test_mkfifo_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001295 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001296 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1297 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001298 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001299 posix.mkfifo(os_helper.TESTFN,
xdegaye92c2ca72017-11-12 17:31:07 +01001300 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1301 except PermissionError as e:
1302 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +08001303 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001304 finally:
1305 posix.close(f)
1306
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001307 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1308 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001309 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001310 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001311
1312 @requires_sched_h
1313 def test_sched_yield(self):
1314 # This has no error conditions (at least on Linux).
1315 posix.sched_yield()
1316
1317 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001318 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1319 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001320 def test_sched_priority(self):
1321 # Round-robin usually has interesting priorities.
1322 pol = posix.SCHED_RR
1323 lo = posix.sched_get_priority_min(pol)
1324 hi = posix.sched_get_priority_max(pol)
1325 self.assertIsInstance(lo, int)
1326 self.assertIsInstance(hi, int)
1327 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001328 # OSX evidently just returns 15 without checking the argument.
1329 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001330 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1331 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001332
Benjamin Petersonc7042222018-09-12 15:12:24 -07001333 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001334 def test_get_and_set_scheduler_and_param(self):
1335 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1336 if name.startswith("SCHED_")]
1337 mine = posix.sched_getscheduler(0)
1338 self.assertIn(mine, possible_schedulers)
1339 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001340 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001341 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001342 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001343 raise
1344 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001345 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001346 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1347 self.assertRaises(OSError, posix.sched_getparam, -1)
1348 param = posix.sched_getparam(0)
1349 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001350
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001351 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1352 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1353 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1354 if not sys.platform.startswith(('freebsd', 'netbsd')):
1355 try:
1356 posix.sched_setscheduler(0, mine, param)
1357 posix.sched_setparam(0, param)
1358 except OSError as e:
1359 if e.errno != errno.EPERM:
1360 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001361 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1362
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001363 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1364 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1365 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1366 param = posix.sched_param(None)
1367 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1368 large = 214748364700
1369 param = posix.sched_param(large)
1370 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1371 param = posix.sched_param(sched_priority=-large)
1372 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1373
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001374 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001375 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001376 try:
1377 interval = posix.sched_rr_get_interval(0)
1378 except OSError as e:
1379 # This likely means that sched_rr_get_interval is only valid for
1380 # processes with the SCHED_RR scheduler in effect.
1381 if e.errno != errno.EINVAL:
1382 raise
1383 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001384 self.assertIsInstance(interval, float)
1385 # Reasonable constraints, I think.
1386 self.assertGreaterEqual(interval, 0.)
1387 self.assertLess(interval, 1.)
1388
Benjamin Peterson2740af82011-08-02 17:41:34 -05001389 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001390 def test_sched_getaffinity(self):
1391 mask = posix.sched_getaffinity(0)
1392 self.assertIsInstance(mask, set)
1393 self.assertGreaterEqual(len(mask), 1)
1394 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1395 for cpu in mask:
1396 self.assertIsInstance(cpu, int)
1397 self.assertGreaterEqual(cpu, 0)
1398 self.assertLess(cpu, 1 << 32)
1399
1400 @requires_sched_affinity
1401 def test_sched_setaffinity(self):
1402 mask = posix.sched_getaffinity(0)
1403 if len(mask) > 1:
1404 # Empty masks are forbidden
1405 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001406 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001407 self.assertEqual(posix.sched_getaffinity(0), mask)
1408 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1409 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001410 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001411 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001412 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1413
Victor Stinner8b905bd2011-10-25 13:34:04 +02001414 def test_rtld_constants(self):
1415 # check presence of major RTLD_* constants
1416 posix.RTLD_LAZY
1417 posix.RTLD_NOW
1418 posix.RTLD_GLOBAL
1419 posix.RTLD_LOCAL
1420
Jesus Cea60c13dd2012-06-23 02:58:14 +02001421 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1422 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001423 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001424 # Even if the filesystem doesn't report holes,
1425 # if the OS supports it the SEEK_* constants
1426 # will be defined and will have a consistent
1427 # behaviour:
1428 # os.SEEK_DATA = current position
1429 # os.SEEK_HOLE = end of file position
Hai Shibb0424b2020-08-04 00:47:42 +08001430 with open(os_helper.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001431 fp.write(b"hello")
1432 fp.flush()
1433 size = fp.tell()
1434 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001435 try :
1436 for i in range(size):
1437 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1438 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1439 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1440 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1441 except OSError :
1442 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1443 # but it is not true.
1444 # For instance:
1445 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1446 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001447
Larry Hastingsb0827312014-02-09 22:05:19 -08001448 def test_path_error2(self):
1449 """
1450 Test functions that call path_error2(), providing two filenames in their exceptions.
1451 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001452 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001453 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001454 if function is None:
1455 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001456
Hai Shibb0424b2020-08-04 00:47:42 +08001457 for dst in ("noodly2", os_helper.TESTFN):
Victor Stinnerbed04a72014-10-05 17:37:59 +02001458 try:
1459 function('doesnotexistfilename', dst)
1460 except OSError as e:
1461 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1462 break
1463 else:
1464 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001465
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001466 def test_path_with_null_character(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001467 fn = os_helper.TESTFN
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001468 fn_with_NUL = fn + '\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001469 self.addCleanup(os_helper.unlink, fn)
1470 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001471 fd = None
1472 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001473 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001474 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1475 finally:
1476 if fd is not None:
1477 os.close(fd)
1478 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001479 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001480 self.assertFalse(os.path.exists(fn))
1481 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001482 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001483
1484 def test_path_with_null_byte(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001485 fn = os.fsencode(os_helper.TESTFN)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001486 fn_with_NUL = fn + b'\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001487 self.addCleanup(os_helper.unlink, fn)
1488 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001489 fd = None
1490 try:
1491 with self.assertRaises(ValueError):
1492 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1493 finally:
1494 if fd is not None:
1495 os.close(fd)
1496 self.assertFalse(os.path.exists(fn))
1497 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1498 self.assertFalse(os.path.exists(fn))
1499 open(fn, 'wb').close()
1500 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1501
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001502 @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1503 def test_pidfd_open(self):
1504 with self.assertRaises(OSError) as cm:
1505 os.pidfd_open(-1)
1506 if cm.exception.errno == errno.ENOSYS:
1507 self.skipTest("system does not support pidfd_open")
Victor Stinner3ab479a2019-11-21 12:54:54 +01001508 if isinstance(cm.exception, PermissionError):
1509 self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}")
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001510 self.assertEqual(cm.exception.errno, errno.EINVAL)
1511 os.close(os.pidfd_open(os.getpid(), 0))
1512
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001513class PosixGroupsTester(unittest.TestCase):
1514
1515 def setUp(self):
1516 if posix.getuid() != 0:
1517 raise unittest.SkipTest("not enough privileges")
1518 if not hasattr(posix, 'getgroups'):
1519 raise unittest.SkipTest("need posix.getgroups")
1520 if sys.platform == 'darwin':
1521 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1522 self.saved_groups = posix.getgroups()
1523
1524 def tearDown(self):
1525 if hasattr(posix, 'setgroups'):
1526 posix.setgroups(self.saved_groups)
1527 elif hasattr(posix, 'initgroups'):
1528 name = pwd.getpwuid(posix.getuid()).pw_name
1529 posix.initgroups(name, self.saved_groups[0])
1530
1531 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1532 "test needs posix.initgroups()")
1533 def test_initgroups(self):
1534 # find missing group
1535
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001536 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001537 name = pwd.getpwuid(posix.getuid()).pw_name
1538 posix.initgroups(name, g)
1539 self.assertIn(g, posix.getgroups())
1540
1541 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1542 "test needs posix.setgroups()")
1543 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001544 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001545 posix.setgroups(groups)
1546 self.assertListEqual(groups, posix.getgroups())
1547
Serhiy Storchakaef347532018-05-01 16:45:04 +03001548
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001549class _PosixSpawnMixin:
1550 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001551 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001552 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001553
1554 def python_args(self, *args):
1555 # Disable site module to avoid side effects. For example,
1556 # on Fedora 28, if the HOME environment variable is not set,
1557 # site._getuserbase() calls pwd.getpwuid() which opens
1558 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1559 # test_close_file() to fail.
1560 return (sys.executable, '-I', '-S', *args)
1561
Serhiy Storchakaef347532018-05-01 16:45:04 +03001562 def test_returns_pid(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001563 pidfile = os_helper.TESTFN
1564 self.addCleanup(os_helper.unlink, pidfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001565 script = f"""if 1:
1566 import os
1567 with open({pidfile!r}, "w") as pidfile:
1568 pidfile.write(str(os.getpid()))
1569 """
Victor Stinner03824062018-08-30 01:21:11 +02001570 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001571 pid = self.spawn_func(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001572 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001573 with open(pidfile) as f:
1574 self.assertEqual(f.read(), str(pid))
1575
1576 def test_no_such_executable(self):
1577 no_such_executable = 'no_such_executable'
1578 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001579 pid = self.spawn_func(no_such_executable,
1580 [no_such_executable],
1581 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001582 # bpo-35794: PermissionError can be raised if there are
1583 # directories in the $PATH that are not accessible.
1584 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001585 self.assertEqual(exc.filename, no_such_executable)
1586 else:
1587 pid2, status = os.waitpid(pid, 0)
1588 self.assertEqual(pid2, pid)
1589 self.assertNotEqual(status, 0)
1590
1591 def test_specify_environment(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001592 envfile = os_helper.TESTFN
1593 self.addCleanup(os_helper.unlink, envfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001594 script = f"""if 1:
1595 import os
1596 with open({envfile!r}, "w") as envfile:
1597 envfile.write(os.environ['foo'])
1598 """
Victor Stinner03824062018-08-30 01:21:11 +02001599 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001600 pid = self.spawn_func(args[0], args,
1601 {**os.environ, 'foo': 'bar'})
Victor Stinner278c1e12020-03-31 20:08:12 +02001602 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001603 with open(envfile) as f:
1604 self.assertEqual(f.read(), 'bar')
1605
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001606 def test_none_file_actions(self):
1607 pid = self.spawn_func(
1608 self.NOOP_PROGRAM[0],
1609 self.NOOP_PROGRAM,
1610 os.environ,
1611 file_actions=None
1612 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001613 support.wait_process(pid, exitcode=0)
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001614
Serhiy Storchakaef347532018-05-01 16:45:04 +03001615 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001616 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001617 self.NOOP_PROGRAM[0],
1618 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001619 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001620 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001621 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001622 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001623
Pablo Galindo254a4662018-09-07 16:44:24 +01001624 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001625 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001626 sys.executable,
1627 [sys.executable, '-c', 'pass'],
1628 os.environ,
1629 resetids=False
1630 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001631 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001632
1633 def test_resetids(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=True
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_wrong_type(self):
1643 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001644 self.spawn_func(sys.executable,
1645 [sys.executable, "-c", "pass"],
1646 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001647
1648 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001649 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001650 sys.executable,
1651 [sys.executable, '-c', 'pass'],
1652 os.environ,
1653 setpgroup=os.getpgrp()
1654 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001655 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001656
1657 def test_setpgroup_wrong_type(self):
1658 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001659 self.spawn_func(sys.executable,
1660 [sys.executable, "-c", "pass"],
1661 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001662
1663 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1664 'need signal.pthread_sigmask()')
1665 def test_setsigmask(self):
1666 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001667 import signal
1668 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001669
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001670 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001671 sys.executable,
1672 [sys.executable, '-c', code],
1673 os.environ,
1674 setsigmask=[signal.SIGUSR1]
1675 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001676 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001677
1678 def test_setsigmask_wrong_type(self):
1679 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001680 self.spawn_func(sys.executable,
1681 [sys.executable, "-c", "pass"],
1682 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001683 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001684 self.spawn_func(sys.executable,
1685 [sys.executable, "-c", "pass"],
1686 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001687 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001688 self.spawn_func(sys.executable,
1689 [sys.executable, "-c", "pass"],
1690 os.environ, setsigmask=[signal.NSIG,
1691 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001692
Victor Stinner58840432019-06-14 19:31:43 +02001693 def test_setsid(self):
1694 rfd, wfd = os.pipe()
1695 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001696 try:
Victor Stinner58840432019-06-14 19:31:43 +02001697 os.set_inheritable(wfd, True)
1698
1699 code = textwrap.dedent(f"""
1700 import os
1701 fd = {wfd}
1702 sid = os.getsid(0)
1703 os.write(fd, str(sid).encode())
1704 """)
1705
1706 try:
1707 pid = self.spawn_func(sys.executable,
1708 [sys.executable, "-c", code],
1709 os.environ, setsid=True)
1710 except NotImplementedError as exc:
1711 self.skipTest(f"setsid is not supported: {exc!r}")
1712 except PermissionError as exc:
1713 self.skipTest(f"setsid failed with: {exc!r}")
1714 finally:
1715 os.close(wfd)
1716
Victor Stinner278c1e12020-03-31 20:08:12 +02001717 support.wait_process(pid, exitcode=0)
1718
Victor Stinner58840432019-06-14 19:31:43 +02001719 output = os.read(rfd, 100)
1720 child_sid = int(output)
1721 parent_sid = os.getsid(os.getpid())
1722 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001723
Pablo Galindo254a4662018-09-07 16:44:24 +01001724 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1725 'need signal.pthread_sigmask()')
1726 def test_setsigdef(self):
1727 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1728 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001729 import signal
1730 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001731 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001732 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001733 sys.executable,
1734 [sys.executable, '-c', code],
1735 os.environ,
1736 setsigdef=[signal.SIGUSR1]
1737 )
1738 finally:
1739 signal.signal(signal.SIGUSR1, original_handler)
1740
Victor Stinner278c1e12020-03-31 20:08:12 +02001741 support.wait_process(pid, exitcode=-signal.SIGUSR1)
Pablo Galindo254a4662018-09-07 16:44:24 +01001742
1743 def test_setsigdef_wrong_type(self):
1744 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001745 self.spawn_func(sys.executable,
1746 [sys.executable, "-c", "pass"],
1747 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001748 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001749 self.spawn_func(sys.executable,
1750 [sys.executable, "-c", "pass"],
1751 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001752 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001753 self.spawn_func(sys.executable,
1754 [sys.executable, "-c", "pass"],
1755 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001756
Benjamin Petersonc7042222018-09-12 15:12:24 -07001757 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001758 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1759 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001760 def test_setscheduler_only_param(self):
1761 policy = os.sched_getscheduler(0)
1762 priority = os.sched_get_priority_min(policy)
1763 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001764 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001765 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001766 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001767 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001768 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001769 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001770 sys.executable,
1771 [sys.executable, '-c', code],
1772 os.environ,
1773 scheduler=(None, os.sched_param(priority))
1774 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001775 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001776
Benjamin Petersonc7042222018-09-12 15:12:24 -07001777 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001778 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1779 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001780 def test_setscheduler_with_policy(self):
1781 policy = os.sched_getscheduler(0)
1782 priority = os.sched_get_priority_min(policy)
1783 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001784 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001785 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001786 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001787 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001788 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001789 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001790 sys.executable,
1791 [sys.executable, '-c', code],
1792 os.environ,
1793 scheduler=(policy, os.sched_param(priority))
1794 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001795 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001796
Serhiy Storchakaef347532018-05-01 16:45:04 +03001797 def test_multiple_file_actions(self):
1798 file_actions = [
1799 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1800 (os.POSIX_SPAWN_CLOSE, 0),
1801 (os.POSIX_SPAWN_DUP2, 1, 4),
1802 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001803 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1804 self.NOOP_PROGRAM,
1805 os.environ,
1806 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001807 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001808
1809 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001810 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001811 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001812 self.spawn_func(args[0], args, os.environ,
1813 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001814 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001815 self.spawn_func(args[0], args, os.environ,
1816 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001817 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001818 self.spawn_func(args[0], args, os.environ,
1819 file_actions=[(None,)])
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=[(12345,)])
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=[(os.POSIX_SPAWN_CLOSE,)])
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=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
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=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001832 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001833 self.spawn_func(args[0], args, os.environ,
1834 file_actions=[(os.POSIX_SPAWN_OPEN,
1835 3, __file__ + '\0',
1836 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001837
1838 def test_open_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001839 outfile = os_helper.TESTFN
1840 self.addCleanup(os_helper.unlink, outfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001841 script = """if 1:
1842 import sys
1843 sys.stdout.write("hello")
1844 """
1845 file_actions = [
1846 (os.POSIX_SPAWN_OPEN, 1, outfile,
1847 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1848 stat.S_IRUSR | stat.S_IWUSR),
1849 ]
Victor Stinner03824062018-08-30 01:21:11 +02001850 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001851 pid = self.spawn_func(args[0], args, os.environ,
1852 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001853
1854 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001855 with open(outfile) as f:
1856 self.assertEqual(f.read(), 'hello')
1857
1858 def test_close_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001859 closefile = os_helper.TESTFN
1860 self.addCleanup(os_helper.unlink, closefile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001861 script = f"""if 1:
1862 import os
1863 try:
1864 os.fstat(0)
1865 except OSError as e:
1866 with open({closefile!r}, 'w') as closefile:
1867 closefile.write('is closed %d' % e.errno)
1868 """
Victor Stinner03824062018-08-30 01:21:11 +02001869 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001870 pid = self.spawn_func(args[0], args, os.environ,
1871 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Victor Stinner278c1e12020-03-31 20:08:12 +02001872
1873 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001874 with open(closefile) as f:
1875 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1876
1877 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001878 dupfile = os_helper.TESTFN
1879 self.addCleanup(os_helper.unlink, dupfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001880 script = """if 1:
1881 import sys
1882 sys.stdout.write("hello")
1883 """
1884 with open(dupfile, "wb") as childfile:
1885 file_actions = [
1886 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1887 ]
Victor Stinner03824062018-08-30 01:21:11 +02001888 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001889 pid = self.spawn_func(args[0], args, os.environ,
1890 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001891 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001892 with open(dupfile) as f:
1893 self.assertEqual(f.read(), 'hello')
1894
1895
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001896@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1897class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1898 spawn_func = getattr(posix, 'posix_spawn', None)
1899
1900
1901@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1902class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1903 spawn_func = getattr(posix, 'posix_spawnp', None)
1904
Hai Shibb0424b2020-08-04 00:47:42 +08001905 @os_helper.skip_unless_symlink
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001906 def test_posix_spawnp(self):
1907 # Use a symlink to create a program in its own temporary directory
1908 temp_dir = tempfile.mkdtemp()
Hai Shibb0424b2020-08-04 00:47:42 +08001909 self.addCleanup(os_helper.rmtree, temp_dir)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001910
1911 program = 'posix_spawnp_test_program.exe'
1912 program_fullpath = os.path.join(temp_dir, program)
1913 os.symlink(sys.executable, program_fullpath)
1914
1915 try:
1916 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1917 except KeyError:
1918 path = temp_dir # PATH is not set
1919
1920 spawn_args = (program, '-I', '-S', '-c', 'pass')
1921 code = textwrap.dedent("""
1922 import os
Victor Stinner278c1e12020-03-31 20:08:12 +02001923 from test import support
1924
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001925 args = %a
1926 pid = os.posix_spawnp(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001927
1928 support.wait_process(pid, exitcode=0)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001929 """ % (spawn_args,))
1930
1931 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1932 # environment variable: posix_spawnp() uses the current environment
1933 # to locate the program, not its environment argument.
1934 args = ('-c', code)
1935 assert_python_ok(*args, PATH=path)
1936
1937
Ronald Oussoren41761932020-11-08 10:05:27 +01001938@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
1939class TestPosixWeaklinking(unittest.TestCase):
1940 # These test cases verify that weak linking support on macOS works
1941 # as expected. These cases only test new behaviour introduced by weak linking,
pxinwrb2d0c662020-12-01 16:20:50 +08001942 # regular behaviour is tested by the normal test cases.
Ronald Oussoren41761932020-11-08 10:05:27 +01001943 #
1944 # See the section on Weak Linking in Mac/README.txt for more information.
1945 def setUp(self):
1946 import sysconfig
1947 import platform
1948
1949 config_vars = sysconfig.get_config_vars()
1950 self.available = { nm for nm in config_vars if nm.startswith("HAVE_") and config_vars[nm] }
1951 self.mac_ver = tuple(int(part) for part in platform.mac_ver()[0].split("."))
1952
1953 def _verify_available(self, name):
1954 if name not in self.available:
1955 raise unittest.SkipTest(f"{name} not weak-linked")
1956
1957 def test_pwritev(self):
1958 self._verify_available("HAVE_PWRITEV")
1959 if self.mac_ver >= (10, 16):
1960 self.assertTrue(hasattr(os, "pwritev"), "os.pwritev is not available")
1961 self.assertTrue(hasattr(os, "preadv"), "os.readv is not available")
1962
1963 else:
1964 self.assertFalse(hasattr(os, "pwritev"), "os.pwritev is available")
1965 self.assertFalse(hasattr(os, "preadv"), "os.readv is available")
1966
1967 def test_stat(self):
1968 self._verify_available("HAVE_FSTATAT")
1969 if self.mac_ver >= (10, 10):
1970 self.assertIn("HAVE_FSTATAT", posix._have_functions)
1971
1972 else:
1973 self.assertNotIn("HAVE_FSTATAT", posix._have_functions)
1974
1975 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1976 os.stat("file", dir_fd=0)
1977
1978 def test_access(self):
1979 self._verify_available("HAVE_FACCESSAT")
1980 if self.mac_ver >= (10, 10):
1981 self.assertIn("HAVE_FACCESSAT", posix._have_functions)
1982
1983 else:
1984 self.assertNotIn("HAVE_FACCESSAT", posix._have_functions)
1985
1986 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1987 os.access("file", os.R_OK, dir_fd=0)
1988
1989 with self.assertRaisesRegex(NotImplementedError, "follow_symlinks unavailable"):
1990 os.access("file", os.R_OK, follow_symlinks=False)
1991
1992 with self.assertRaisesRegex(NotImplementedError, "effective_ids unavailable"):
1993 os.access("file", os.R_OK, effective_ids=True)
1994
1995 def test_chmod(self):
1996 self._verify_available("HAVE_FCHMODAT")
1997 if self.mac_ver >= (10, 10):
1998 self.assertIn("HAVE_FCHMODAT", posix._have_functions)
1999
2000 else:
2001 self.assertNotIn("HAVE_FCHMODAT", posix._have_functions)
2002 self.assertIn("HAVE_LCHMOD", posix._have_functions)
2003
2004 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2005 os.chmod("file", 0o644, dir_fd=0)
2006
2007 def test_chown(self):
2008 self._verify_available("HAVE_FCHOWNAT")
2009 if self.mac_ver >= (10, 10):
2010 self.assertIn("HAVE_FCHOWNAT", posix._have_functions)
2011
2012 else:
2013 self.assertNotIn("HAVE_FCHOWNAT", posix._have_functions)
2014 self.assertIn("HAVE_LCHOWN", posix._have_functions)
2015
2016 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2017 os.chown("file", 0, 0, dir_fd=0)
2018
2019 def test_link(self):
2020 self._verify_available("HAVE_LINKAT")
2021 if self.mac_ver >= (10, 10):
2022 self.assertIn("HAVE_LINKAT", posix._have_functions)
2023
2024 else:
2025 self.assertNotIn("HAVE_LINKAT", posix._have_functions)
2026
2027 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2028 os.link("source", "target", src_dir_fd=0)
2029
2030 with self.assertRaisesRegex(NotImplementedError, "dst_dir_fd unavailable"):
2031 os.link("source", "target", dst_dir_fd=0)
2032
2033 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2034 os.link("source", "target", src_dir_fd=0, dst_dir_fd=0)
2035
2036 # issue 41355: !HAVE_LINKAT code path ignores the follow_symlinks flag
2037 with os_helper.temp_dir() as base_path:
2038 link_path = os.path.join(base_path, "link")
2039 target_path = os.path.join(base_path, "target")
2040 source_path = os.path.join(base_path, "source")
2041
2042 with open(source_path, "w") as fp:
2043 fp.write("data")
2044
2045 os.symlink("target", link_path)
2046
2047 # Calling os.link should fail in the link(2) call, and
2048 # should not reject *follow_symlinks* (to match the
2049 # behaviour you'd get when building on a platform without
2050 # linkat)
2051 with self.assertRaises(FileExistsError):
2052 os.link(source_path, link_path, follow_symlinks=True)
2053
2054 with self.assertRaises(FileExistsError):
2055 os.link(source_path, link_path, follow_symlinks=False)
2056
2057
2058 def test_listdir_scandir(self):
2059 self._verify_available("HAVE_FDOPENDIR")
2060 if self.mac_ver >= (10, 10):
2061 self.assertIn("HAVE_FDOPENDIR", posix._have_functions)
2062
2063 else:
2064 self.assertNotIn("HAVE_FDOPENDIR", posix._have_functions)
2065
2066 with self.assertRaisesRegex(TypeError, "listdir: path should be string, bytes, os.PathLike or None, not int"):
2067 os.listdir(0)
2068
2069 with self.assertRaisesRegex(TypeError, "scandir: path should be string, bytes, os.PathLike or None, not int"):
2070 os.scandir(0)
2071
2072 def test_mkdir(self):
2073 self._verify_available("HAVE_MKDIRAT")
2074 if self.mac_ver >= (10, 10):
2075 self.assertIn("HAVE_MKDIRAT", posix._have_functions)
2076
2077 else:
2078 self.assertNotIn("HAVE_MKDIRAT", posix._have_functions)
2079
2080 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2081 os.mkdir("dir", dir_fd=0)
2082
2083 def test_rename_replace(self):
2084 self._verify_available("HAVE_RENAMEAT")
2085 if self.mac_ver >= (10, 10):
2086 self.assertIn("HAVE_RENAMEAT", posix._have_functions)
2087
2088 else:
2089 self.assertNotIn("HAVE_RENAMEAT", posix._have_functions)
2090
2091 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2092 os.rename("a", "b", src_dir_fd=0)
2093
2094 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2095 os.rename("a", "b", dst_dir_fd=0)
2096
2097 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2098 os.replace("a", "b", src_dir_fd=0)
2099
2100 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2101 os.replace("a", "b", dst_dir_fd=0)
2102
2103 def test_unlink_rmdir(self):
2104 self._verify_available("HAVE_UNLINKAT")
2105 if self.mac_ver >= (10, 10):
2106 self.assertIn("HAVE_UNLINKAT", posix._have_functions)
2107
2108 else:
2109 self.assertNotIn("HAVE_UNLINKAT", posix._have_functions)
2110
2111 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2112 os.unlink("path", dir_fd=0)
2113
2114 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2115 os.rmdir("path", dir_fd=0)
2116
2117 def test_open(self):
2118 self._verify_available("HAVE_OPENAT")
2119 if self.mac_ver >= (10, 10):
2120 self.assertIn("HAVE_OPENAT", posix._have_functions)
2121
2122 else:
2123 self.assertNotIn("HAVE_OPENAT", posix._have_functions)
2124
2125 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2126 os.open("path", os.O_RDONLY, dir_fd=0)
2127
2128 def test_readlink(self):
2129 self._verify_available("HAVE_READLINKAT")
2130 if self.mac_ver >= (10, 10):
2131 self.assertIn("HAVE_READLINKAT", posix._have_functions)
2132
2133 else:
2134 self.assertNotIn("HAVE_READLINKAT", posix._have_functions)
2135
2136 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2137 os.readlink("path", dir_fd=0)
2138
2139 def test_symlink(self):
2140 self._verify_available("HAVE_SYMLINKAT")
2141 if self.mac_ver >= (10, 10):
2142 self.assertIn("HAVE_SYMLINKAT", posix._have_functions)
2143
2144 else:
2145 self.assertNotIn("HAVE_SYMLINKAT", posix._have_functions)
2146
2147 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2148 os.symlink("a", "b", dir_fd=0)
2149
2150 def test_utime(self):
2151 self._verify_available("HAVE_FUTIMENS")
2152 self._verify_available("HAVE_UTIMENSAT")
2153 if self.mac_ver >= (10, 13):
2154 self.assertIn("HAVE_FUTIMENS", posix._have_functions)
2155 self.assertIn("HAVE_UTIMENSAT", posix._have_functions)
2156
2157 else:
2158 self.assertNotIn("HAVE_FUTIMENS", posix._have_functions)
2159 self.assertNotIn("HAVE_UTIMENSAT", posix._have_functions)
2160
2161 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2162 os.utime("path", dir_fd=0)
2163
2164
Neal Norwitze241ce82003-02-17 18:17:05 +00002165def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01002166 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002167 support.run_unittest(
2168 PosixTester,
2169 PosixGroupsTester,
2170 TestPosixSpawn,
2171 TestPosixSpawnP,
Ronald Oussoren41761932020-11-08 10:05:27 +01002172 TestPosixWeaklinking
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002173 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01002174 finally:
2175 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00002176
2177if __name__ == '__main__':
2178 test_main()