blob: 185b293b0704690018dc391390a3e0bb0c540dbf [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()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001048 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001049 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001050 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001051 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001052
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001053 try:
1054 idg_groups = set(int(g) for g in groups.split())
1055 except ValueError:
1056 idg_groups = set()
1057 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001058 raise unittest.SkipTest("need working 'id -G'")
1059
Ned Deily028915e2013-02-02 15:08:52 -08001060 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1061 if sys.platform == 'darwin':
1062 import sysconfig
1063 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
FX Coudert52916392020-12-03 04:20:18 +01001064 if tuple(int(n) for n in str(dt).split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001065 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1066
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001067 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001068 # groups, ignoring order, duplicates, and the effective gid.
1069 # #10822/#26944 - It is implementation defined whether
1070 # posix.getgroups() includes the effective gid.
1071 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1072 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001073
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001074 # tests for the posix *at functions follow
1075
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1077 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001078 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1079 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001080 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001081 finally:
1082 posix.close(f)
1083
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1085 def test_chmod_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001086 os.chmod(os_helper.TESTFN, stat.S_IRUSR)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001087
1088 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1089 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001090 posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001091
Hai Shibb0424b2020-08-04 00:47:42 +08001092 s = posix.stat(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001093 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1094 finally:
1095 posix.close(f)
1096
pxinwreb7594f2020-12-09 07:18:37 +08001097 @unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd),
1098 "test needs dir_fd support in os.chown()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001099 def test_chown_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001100 os_helper.unlink(os_helper.TESTFN)
1101 os_helper.create_empty_file(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001102
1103 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1104 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001105 posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001106 finally:
1107 posix.close(f)
1108
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1110 def test_stat_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001111 os_helper.unlink(os_helper.TESTFN)
1112 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001113 outfile.write("testline\n")
1114
1115 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1116 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001117 s1 = posix.stat(os_helper.TESTFN)
1118 s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001119 self.assertEqual(s1, s2)
Hai Shibb0424b2020-08-04 00:47:42 +08001120 s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001121 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001122 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001123 posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001124 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001125 posix.stat, os_helper.TESTFN, dir_fd=float(f))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001126 self.assertRaises(OverflowError,
Hai Shibb0424b2020-08-04 00:47:42 +08001127 posix.stat, os_helper.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001128 finally:
1129 posix.close(f)
1130
Larry Hastings9cf065c2012-06-22 16:30:09 -07001131 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1132 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001133 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1134 try:
1135 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +08001136 posix.utime(os_helper.TESTFN, None, dir_fd=f)
1137 posix.utime(os_helper.TESTFN, dir_fd=f)
1138 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1139 now, dir_fd=f)
1140 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1141 (None, None), dir_fd=f)
1142 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1143 (now, None), dir_fd=f)
1144 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1145 (None, now), dir_fd=f)
1146 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1147 (now, "x"), dir_fd=f)
1148 posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
1149 posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
1150 posix.utime(os_helper.TESTFN,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001151 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
Hai Shibb0424b2020-08-04 00:47:42 +08001152 posix.utime(os_helper.TESTFN, dir_fd=f,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001153 times=(int(now), int((now - int(now)) * 1e9)))
1154
Larry Hastings90867a52012-06-22 17:01:41 -07001155 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001156 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001157 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001158 posix.utime(os_helper.TESTFN, follow_symlinks=False,
1159 dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001160 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001161 # whoops! using both together not supported on this platform.
1162 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001163
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001164 finally:
1165 posix.close(f)
1166
Larry Hastings9cf065c2012-06-22 16:30:09 -07001167 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1168 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001169 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1170 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001171 posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link',
1172 src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001173 except PermissionError as e:
1174 self.skipTest('posix.link(): %s' % e)
1175 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001176 # should have same inodes
Hai Shibb0424b2020-08-04 00:47:42 +08001177 self.assertEqual(posix.stat(os_helper.TESTFN)[1],
1178 posix.stat(os_helper.TESTFN + 'link')[1])
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001179 finally:
1180 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001181 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001182
Larry Hastings9cf065c2012-06-22 16:30:09 -07001183 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1184 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001185 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1186 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001187 posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
1188 posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001189 finally:
1190 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001191 os_helper.rmtree(os_helper.TESTFN + 'dir')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001192
pxinwreb7594f2020-12-09 07:18:37 +08001193 @unittest.skipUnless(hasattr(os, 'mknod')
1194 and (os.mknod in os.supports_dir_fd)
1195 and hasattr(stat, 'S_IFIFO'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001196 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1197 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001198 # Test using mknodat() to create a FIFO (the only use specified
1199 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +08001200 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001201 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1202 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1203 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001204 posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001205 except OSError as e:
1206 # Some old systems don't allow unprivileged users to use
1207 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001208 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001209 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001210 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001211 finally:
1212 posix.close(f)
1213
Larry Hastings9cf065c2012-06-22 16:30:09 -07001214 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1215 def test_open_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001216 os_helper.unlink(os_helper.TESTFN)
1217 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001218 outfile.write("testline\n")
1219 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001220 b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001221 try:
1222 res = posix.read(b, 9).decode(encoding="utf-8")
1223 self.assertEqual("testline\n", res)
1224 finally:
1225 posix.close(a)
1226 posix.close(b)
1227
pxinwreb7594f2020-12-09 07:18:37 +08001228 @unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd),
1229 "test needs dir_fd support in os.readlink()")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001230 def test_readlink_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001231 os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001232 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1233 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001234 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1235 posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001236 finally:
Hai Shibb0424b2020-08-04 00:47:42 +08001237 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001238 posix.close(f)
1239
Larry Hastings9cf065c2012-06-22 16:30:09 -07001240 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1241 def test_rename_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001242 os_helper.unlink(os_helper.TESTFN)
1243 os_helper.create_empty_file(os_helper.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001244 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1245 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001246 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001247 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001248 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001249 raise
1250 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001251 posix.stat(os_helper.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001252 finally:
1253 posix.close(f)
1254
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001255 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1256 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1257 def test_cld_xxxx_constants(self):
1258 os.CLD_EXITED
1259 os.CLD_KILLED
1260 os.CLD_DUMPED
1261 os.CLD_TRAPPED
1262 os.CLD_STOPPED
1263 os.CLD_CONTINUED
1264
Larry Hastings9cf065c2012-06-22 16:30:09 -07001265 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1266 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001267 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1268 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001269 posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link',
1270 dir_fd=f)
1271 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1272 os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001273 finally:
1274 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001275 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001276
Larry Hastings9cf065c2012-06-22 16:30:09 -07001277 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1278 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001279 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001280 os_helper.create_empty_file(os_helper.TESTFN + 'del')
1281 posix.stat(os_helper.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001282 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001283 posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001284 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001285 os_helper.unlink(os_helper.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001286 raise
1287 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001288 self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001289 finally:
1290 posix.close(f)
1291
Larry Hastings9cf065c2012-06-22 16:30:09 -07001292 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1293 def test_mkfifo_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001294 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001295 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1296 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001297 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001298 posix.mkfifo(os_helper.TESTFN,
xdegaye92c2ca72017-11-12 17:31:07 +01001299 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1300 except PermissionError as e:
1301 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +08001302 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001303 finally:
1304 posix.close(f)
1305
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001306 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1307 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001308 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001309 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001310
1311 @requires_sched_h
1312 def test_sched_yield(self):
1313 # This has no error conditions (at least on Linux).
1314 posix.sched_yield()
1315
1316 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001317 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1318 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001319 def test_sched_priority(self):
1320 # Round-robin usually has interesting priorities.
1321 pol = posix.SCHED_RR
1322 lo = posix.sched_get_priority_min(pol)
1323 hi = posix.sched_get_priority_max(pol)
1324 self.assertIsInstance(lo, int)
1325 self.assertIsInstance(hi, int)
1326 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001327 # OSX evidently just returns 15 without checking the argument.
1328 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001329 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1330 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001331
Benjamin Petersonc7042222018-09-12 15:12:24 -07001332 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001333 def test_get_and_set_scheduler_and_param(self):
1334 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1335 if name.startswith("SCHED_")]
1336 mine = posix.sched_getscheduler(0)
1337 self.assertIn(mine, possible_schedulers)
1338 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001339 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001340 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001341 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001342 raise
1343 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001344 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001345 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1346 self.assertRaises(OSError, posix.sched_getparam, -1)
1347 param = posix.sched_getparam(0)
1348 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001349
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001350 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1351 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1352 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1353 if not sys.platform.startswith(('freebsd', 'netbsd')):
1354 try:
1355 posix.sched_setscheduler(0, mine, param)
1356 posix.sched_setparam(0, param)
1357 except OSError as e:
1358 if e.errno != errno.EPERM:
1359 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001360 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1361
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001362 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1363 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1364 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1365 param = posix.sched_param(None)
1366 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1367 large = 214748364700
1368 param = posix.sched_param(large)
1369 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1370 param = posix.sched_param(sched_priority=-large)
1371 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1372
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001373 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001374 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001375 try:
1376 interval = posix.sched_rr_get_interval(0)
1377 except OSError as e:
1378 # This likely means that sched_rr_get_interval is only valid for
1379 # processes with the SCHED_RR scheduler in effect.
1380 if e.errno != errno.EINVAL:
1381 raise
1382 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001383 self.assertIsInstance(interval, float)
1384 # Reasonable constraints, I think.
1385 self.assertGreaterEqual(interval, 0.)
1386 self.assertLess(interval, 1.)
1387
Benjamin Peterson2740af82011-08-02 17:41:34 -05001388 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001389 def test_sched_getaffinity(self):
1390 mask = posix.sched_getaffinity(0)
1391 self.assertIsInstance(mask, set)
1392 self.assertGreaterEqual(len(mask), 1)
1393 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1394 for cpu in mask:
1395 self.assertIsInstance(cpu, int)
1396 self.assertGreaterEqual(cpu, 0)
1397 self.assertLess(cpu, 1 << 32)
1398
1399 @requires_sched_affinity
1400 def test_sched_setaffinity(self):
1401 mask = posix.sched_getaffinity(0)
1402 if len(mask) > 1:
1403 # Empty masks are forbidden
1404 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001405 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001406 self.assertEqual(posix.sched_getaffinity(0), mask)
1407 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1408 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001409 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001410 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001411 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1412
Victor Stinner8b905bd2011-10-25 13:34:04 +02001413 def test_rtld_constants(self):
1414 # check presence of major RTLD_* constants
1415 posix.RTLD_LAZY
1416 posix.RTLD_NOW
1417 posix.RTLD_GLOBAL
1418 posix.RTLD_LOCAL
1419
Jesus Cea60c13dd2012-06-23 02:58:14 +02001420 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1421 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001422 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001423 # Even if the filesystem doesn't report holes,
1424 # if the OS supports it the SEEK_* constants
1425 # will be defined and will have a consistent
1426 # behaviour:
1427 # os.SEEK_DATA = current position
1428 # os.SEEK_HOLE = end of file position
Hai Shibb0424b2020-08-04 00:47:42 +08001429 with open(os_helper.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001430 fp.write(b"hello")
1431 fp.flush()
1432 size = fp.tell()
1433 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001434 try :
1435 for i in range(size):
1436 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1437 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1438 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1439 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1440 except OSError :
1441 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1442 # but it is not true.
1443 # For instance:
1444 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1445 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001446
Larry Hastingsb0827312014-02-09 22:05:19 -08001447 def test_path_error2(self):
1448 """
1449 Test functions that call path_error2(), providing two filenames in their exceptions.
1450 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001451 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001452 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001453 if function is None:
1454 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001455
Hai Shibb0424b2020-08-04 00:47:42 +08001456 for dst in ("noodly2", os_helper.TESTFN):
Victor Stinnerbed04a72014-10-05 17:37:59 +02001457 try:
1458 function('doesnotexistfilename', dst)
1459 except OSError as e:
1460 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1461 break
1462 else:
1463 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001464
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001465 def test_path_with_null_character(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001466 fn = os_helper.TESTFN
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001467 fn_with_NUL = fn + '\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001468 self.addCleanup(os_helper.unlink, fn)
1469 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001470 fd = None
1471 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001472 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001473 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1474 finally:
1475 if fd is not None:
1476 os.close(fd)
1477 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001478 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001479 self.assertFalse(os.path.exists(fn))
1480 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001481 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001482
1483 def test_path_with_null_byte(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001484 fn = os.fsencode(os_helper.TESTFN)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001485 fn_with_NUL = fn + b'\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001486 self.addCleanup(os_helper.unlink, fn)
1487 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001488 fd = None
1489 try:
1490 with self.assertRaises(ValueError):
1491 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1492 finally:
1493 if fd is not None:
1494 os.close(fd)
1495 self.assertFalse(os.path.exists(fn))
1496 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1497 self.assertFalse(os.path.exists(fn))
1498 open(fn, 'wb').close()
1499 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1500
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001501 @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1502 def test_pidfd_open(self):
1503 with self.assertRaises(OSError) as cm:
1504 os.pidfd_open(-1)
1505 if cm.exception.errno == errno.ENOSYS:
1506 self.skipTest("system does not support pidfd_open")
Victor Stinner3ab479a2019-11-21 12:54:54 +01001507 if isinstance(cm.exception, PermissionError):
1508 self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}")
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001509 self.assertEqual(cm.exception.errno, errno.EINVAL)
1510 os.close(os.pidfd_open(os.getpid(), 0))
1511
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001512class PosixGroupsTester(unittest.TestCase):
1513
1514 def setUp(self):
1515 if posix.getuid() != 0:
1516 raise unittest.SkipTest("not enough privileges")
1517 if not hasattr(posix, 'getgroups'):
1518 raise unittest.SkipTest("need posix.getgroups")
1519 if sys.platform == 'darwin':
1520 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1521 self.saved_groups = posix.getgroups()
1522
1523 def tearDown(self):
1524 if hasattr(posix, 'setgroups'):
1525 posix.setgroups(self.saved_groups)
1526 elif hasattr(posix, 'initgroups'):
1527 name = pwd.getpwuid(posix.getuid()).pw_name
1528 posix.initgroups(name, self.saved_groups[0])
1529
1530 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1531 "test needs posix.initgroups()")
1532 def test_initgroups(self):
1533 # find missing group
1534
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001535 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001536 name = pwd.getpwuid(posix.getuid()).pw_name
1537 posix.initgroups(name, g)
1538 self.assertIn(g, posix.getgroups())
1539
1540 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1541 "test needs posix.setgroups()")
1542 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001543 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001544 posix.setgroups(groups)
1545 self.assertListEqual(groups, posix.getgroups())
1546
Serhiy Storchakaef347532018-05-01 16:45:04 +03001547
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001548class _PosixSpawnMixin:
1549 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001550 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001551 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001552
1553 def python_args(self, *args):
1554 # Disable site module to avoid side effects. For example,
1555 # on Fedora 28, if the HOME environment variable is not set,
1556 # site._getuserbase() calls pwd.getpwuid() which opens
1557 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1558 # test_close_file() to fail.
1559 return (sys.executable, '-I', '-S', *args)
1560
Serhiy Storchakaef347532018-05-01 16:45:04 +03001561 def test_returns_pid(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001562 pidfile = os_helper.TESTFN
1563 self.addCleanup(os_helper.unlink, pidfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001564 script = f"""if 1:
1565 import os
1566 with open({pidfile!r}, "w") as pidfile:
1567 pidfile.write(str(os.getpid()))
1568 """
Victor Stinner03824062018-08-30 01:21:11 +02001569 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001570 pid = self.spawn_func(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001571 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001572 with open(pidfile) as f:
1573 self.assertEqual(f.read(), str(pid))
1574
1575 def test_no_such_executable(self):
1576 no_such_executable = 'no_such_executable'
1577 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001578 pid = self.spawn_func(no_such_executable,
1579 [no_such_executable],
1580 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001581 # bpo-35794: PermissionError can be raised if there are
1582 # directories in the $PATH that are not accessible.
1583 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001584 self.assertEqual(exc.filename, no_such_executable)
1585 else:
1586 pid2, status = os.waitpid(pid, 0)
1587 self.assertEqual(pid2, pid)
1588 self.assertNotEqual(status, 0)
1589
1590 def test_specify_environment(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001591 envfile = os_helper.TESTFN
1592 self.addCleanup(os_helper.unlink, envfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001593 script = f"""if 1:
1594 import os
1595 with open({envfile!r}, "w") as envfile:
1596 envfile.write(os.environ['foo'])
1597 """
Victor Stinner03824062018-08-30 01:21:11 +02001598 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001599 pid = self.spawn_func(args[0], args,
1600 {**os.environ, 'foo': 'bar'})
Victor Stinner278c1e12020-03-31 20:08:12 +02001601 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001602 with open(envfile) as f:
1603 self.assertEqual(f.read(), 'bar')
1604
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001605 def test_none_file_actions(self):
1606 pid = self.spawn_func(
1607 self.NOOP_PROGRAM[0],
1608 self.NOOP_PROGRAM,
1609 os.environ,
1610 file_actions=None
1611 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001612 support.wait_process(pid, exitcode=0)
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001613
Serhiy Storchakaef347532018-05-01 16:45:04 +03001614 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001615 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001616 self.NOOP_PROGRAM[0],
1617 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001618 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001619 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001620 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001621 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001622
Pablo Galindo254a4662018-09-07 16:44:24 +01001623 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001624 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001625 sys.executable,
1626 [sys.executable, '-c', 'pass'],
1627 os.environ,
1628 resetids=False
1629 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001630 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001631
1632 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001633 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001634 sys.executable,
1635 [sys.executable, '-c', 'pass'],
1636 os.environ,
1637 resetids=True
1638 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001639 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001640
1641 def test_resetids_wrong_type(self):
1642 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001643 self.spawn_func(sys.executable,
1644 [sys.executable, "-c", "pass"],
1645 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001646
1647 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001648 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001649 sys.executable,
1650 [sys.executable, '-c', 'pass'],
1651 os.environ,
1652 setpgroup=os.getpgrp()
1653 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001654 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001655
1656 def test_setpgroup_wrong_type(self):
1657 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001658 self.spawn_func(sys.executable,
1659 [sys.executable, "-c", "pass"],
1660 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001661
1662 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1663 'need signal.pthread_sigmask()')
1664 def test_setsigmask(self):
1665 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001666 import signal
1667 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001668
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001669 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001670 sys.executable,
1671 [sys.executable, '-c', code],
1672 os.environ,
1673 setsigmask=[signal.SIGUSR1]
1674 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001675 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001676
1677 def test_setsigmask_wrong_type(self):
1678 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001679 self.spawn_func(sys.executable,
1680 [sys.executable, "-c", "pass"],
1681 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001682 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001683 self.spawn_func(sys.executable,
1684 [sys.executable, "-c", "pass"],
1685 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001686 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001687 self.spawn_func(sys.executable,
1688 [sys.executable, "-c", "pass"],
1689 os.environ, setsigmask=[signal.NSIG,
1690 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001691
Victor Stinner58840432019-06-14 19:31:43 +02001692 def test_setsid(self):
1693 rfd, wfd = os.pipe()
1694 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001695 try:
Victor Stinner58840432019-06-14 19:31:43 +02001696 os.set_inheritable(wfd, True)
1697
1698 code = textwrap.dedent(f"""
1699 import os
1700 fd = {wfd}
1701 sid = os.getsid(0)
1702 os.write(fd, str(sid).encode())
1703 """)
1704
1705 try:
1706 pid = self.spawn_func(sys.executable,
1707 [sys.executable, "-c", code],
1708 os.environ, setsid=True)
1709 except NotImplementedError as exc:
1710 self.skipTest(f"setsid is not supported: {exc!r}")
1711 except PermissionError as exc:
1712 self.skipTest(f"setsid failed with: {exc!r}")
1713 finally:
1714 os.close(wfd)
1715
Victor Stinner278c1e12020-03-31 20:08:12 +02001716 support.wait_process(pid, exitcode=0)
1717
Victor Stinner58840432019-06-14 19:31:43 +02001718 output = os.read(rfd, 100)
1719 child_sid = int(output)
1720 parent_sid = os.getsid(os.getpid())
1721 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001722
Pablo Galindo254a4662018-09-07 16:44:24 +01001723 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1724 'need signal.pthread_sigmask()')
1725 def test_setsigdef(self):
1726 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1727 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001728 import signal
1729 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001730 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001731 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001732 sys.executable,
1733 [sys.executable, '-c', code],
1734 os.environ,
1735 setsigdef=[signal.SIGUSR1]
1736 )
1737 finally:
1738 signal.signal(signal.SIGUSR1, original_handler)
1739
Victor Stinner278c1e12020-03-31 20:08:12 +02001740 support.wait_process(pid, exitcode=-signal.SIGUSR1)
Pablo Galindo254a4662018-09-07 16:44:24 +01001741
1742 def test_setsigdef_wrong_type(self):
1743 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001744 self.spawn_func(sys.executable,
1745 [sys.executable, "-c", "pass"],
1746 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001747 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001748 self.spawn_func(sys.executable,
1749 [sys.executable, "-c", "pass"],
1750 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001751 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001752 self.spawn_func(sys.executable,
1753 [sys.executable, "-c", "pass"],
1754 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001755
Benjamin Petersonc7042222018-09-12 15:12:24 -07001756 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001757 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1758 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001759 def test_setscheduler_only_param(self):
1760 policy = os.sched_getscheduler(0)
1761 priority = os.sched_get_priority_min(policy)
1762 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001763 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001764 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001765 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001766 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001767 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001768 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001769 sys.executable,
1770 [sys.executable, '-c', code],
1771 os.environ,
1772 scheduler=(None, os.sched_param(priority))
1773 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001774 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001775
Benjamin Petersonc7042222018-09-12 15:12:24 -07001776 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001777 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1778 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001779 def test_setscheduler_with_policy(self):
1780 policy = os.sched_getscheduler(0)
1781 priority = os.sched_get_priority_min(policy)
1782 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001783 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001784 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001785 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001786 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001787 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001788 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001789 sys.executable,
1790 [sys.executable, '-c', code],
1791 os.environ,
1792 scheduler=(policy, os.sched_param(priority))
1793 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001794 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001795
Serhiy Storchakaef347532018-05-01 16:45:04 +03001796 def test_multiple_file_actions(self):
1797 file_actions = [
1798 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1799 (os.POSIX_SPAWN_CLOSE, 0),
1800 (os.POSIX_SPAWN_DUP2, 1, 4),
1801 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001802 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1803 self.NOOP_PROGRAM,
1804 os.environ,
1805 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001806 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001807
1808 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001809 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001810 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001811 self.spawn_func(args[0], args, os.environ,
1812 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001813 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001814 self.spawn_func(args[0], args, os.environ,
1815 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001816 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001817 self.spawn_func(args[0], args, os.environ,
1818 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001819 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001820 self.spawn_func(args[0], args, os.environ,
1821 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001822 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001823 self.spawn_func(args[0], args, os.environ,
1824 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001825 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001826 self.spawn_func(args[0], args, os.environ,
1827 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001828 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001829 self.spawn_func(args[0], args, os.environ,
1830 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001831 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001832 self.spawn_func(args[0], args, os.environ,
1833 file_actions=[(os.POSIX_SPAWN_OPEN,
1834 3, __file__ + '\0',
1835 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001836
1837 def test_open_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001838 outfile = os_helper.TESTFN
1839 self.addCleanup(os_helper.unlink, outfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001840 script = """if 1:
1841 import sys
1842 sys.stdout.write("hello")
1843 """
1844 file_actions = [
1845 (os.POSIX_SPAWN_OPEN, 1, outfile,
1846 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1847 stat.S_IRUSR | stat.S_IWUSR),
1848 ]
Victor Stinner03824062018-08-30 01:21:11 +02001849 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001850 pid = self.spawn_func(args[0], args, os.environ,
1851 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001852
1853 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001854 with open(outfile) as f:
1855 self.assertEqual(f.read(), 'hello')
1856
1857 def test_close_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001858 closefile = os_helper.TESTFN
1859 self.addCleanup(os_helper.unlink, closefile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001860 script = f"""if 1:
1861 import os
1862 try:
1863 os.fstat(0)
1864 except OSError as e:
1865 with open({closefile!r}, 'w') as closefile:
1866 closefile.write('is closed %d' % e.errno)
1867 """
Victor Stinner03824062018-08-30 01:21:11 +02001868 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001869 pid = self.spawn_func(args[0], args, os.environ,
1870 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Victor Stinner278c1e12020-03-31 20:08:12 +02001871
1872 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001873 with open(closefile) as f:
1874 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1875
1876 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001877 dupfile = os_helper.TESTFN
1878 self.addCleanup(os_helper.unlink, dupfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001879 script = """if 1:
1880 import sys
1881 sys.stdout.write("hello")
1882 """
1883 with open(dupfile, "wb") as childfile:
1884 file_actions = [
1885 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1886 ]
Victor Stinner03824062018-08-30 01:21:11 +02001887 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001888 pid = self.spawn_func(args[0], args, os.environ,
1889 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001890 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001891 with open(dupfile) as f:
1892 self.assertEqual(f.read(), 'hello')
1893
1894
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001895@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1896class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1897 spawn_func = getattr(posix, 'posix_spawn', None)
1898
1899
1900@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1901class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1902 spawn_func = getattr(posix, 'posix_spawnp', None)
1903
Hai Shibb0424b2020-08-04 00:47:42 +08001904 @os_helper.skip_unless_symlink
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001905 def test_posix_spawnp(self):
1906 # Use a symlink to create a program in its own temporary directory
1907 temp_dir = tempfile.mkdtemp()
Hai Shibb0424b2020-08-04 00:47:42 +08001908 self.addCleanup(os_helper.rmtree, temp_dir)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001909
1910 program = 'posix_spawnp_test_program.exe'
1911 program_fullpath = os.path.join(temp_dir, program)
1912 os.symlink(sys.executable, program_fullpath)
1913
1914 try:
1915 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1916 except KeyError:
1917 path = temp_dir # PATH is not set
1918
1919 spawn_args = (program, '-I', '-S', '-c', 'pass')
1920 code = textwrap.dedent("""
1921 import os
Victor Stinner278c1e12020-03-31 20:08:12 +02001922 from test import support
1923
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001924 args = %a
1925 pid = os.posix_spawnp(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001926
1927 support.wait_process(pid, exitcode=0)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001928 """ % (spawn_args,))
1929
1930 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1931 # environment variable: posix_spawnp() uses the current environment
1932 # to locate the program, not its environment argument.
1933 args = ('-c', code)
1934 assert_python_ok(*args, PATH=path)
1935
1936
Ronald Oussoren41761932020-11-08 10:05:27 +01001937@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
1938class TestPosixWeaklinking(unittest.TestCase):
1939 # These test cases verify that weak linking support on macOS works
1940 # as expected. These cases only test new behaviour introduced by weak linking,
pxinwrb2d0c662020-12-01 16:20:50 +08001941 # regular behaviour is tested by the normal test cases.
Ronald Oussoren41761932020-11-08 10:05:27 +01001942 #
1943 # See the section on Weak Linking in Mac/README.txt for more information.
1944 def setUp(self):
1945 import sysconfig
1946 import platform
1947
1948 config_vars = sysconfig.get_config_vars()
1949 self.available = { nm for nm in config_vars if nm.startswith("HAVE_") and config_vars[nm] }
1950 self.mac_ver = tuple(int(part) for part in platform.mac_ver()[0].split("."))
1951
1952 def _verify_available(self, name):
1953 if name not in self.available:
1954 raise unittest.SkipTest(f"{name} not weak-linked")
1955
1956 def test_pwritev(self):
1957 self._verify_available("HAVE_PWRITEV")
1958 if self.mac_ver >= (10, 16):
1959 self.assertTrue(hasattr(os, "pwritev"), "os.pwritev is not available")
1960 self.assertTrue(hasattr(os, "preadv"), "os.readv is not available")
1961
1962 else:
1963 self.assertFalse(hasattr(os, "pwritev"), "os.pwritev is available")
1964 self.assertFalse(hasattr(os, "preadv"), "os.readv is available")
1965
1966 def test_stat(self):
1967 self._verify_available("HAVE_FSTATAT")
1968 if self.mac_ver >= (10, 10):
1969 self.assertIn("HAVE_FSTATAT", posix._have_functions)
1970
1971 else:
1972 self.assertNotIn("HAVE_FSTATAT", posix._have_functions)
1973
1974 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1975 os.stat("file", dir_fd=0)
1976
1977 def test_access(self):
1978 self._verify_available("HAVE_FACCESSAT")
1979 if self.mac_ver >= (10, 10):
1980 self.assertIn("HAVE_FACCESSAT", posix._have_functions)
1981
1982 else:
1983 self.assertNotIn("HAVE_FACCESSAT", posix._have_functions)
1984
1985 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1986 os.access("file", os.R_OK, dir_fd=0)
1987
1988 with self.assertRaisesRegex(NotImplementedError, "follow_symlinks unavailable"):
1989 os.access("file", os.R_OK, follow_symlinks=False)
1990
1991 with self.assertRaisesRegex(NotImplementedError, "effective_ids unavailable"):
1992 os.access("file", os.R_OK, effective_ids=True)
1993
1994 def test_chmod(self):
1995 self._verify_available("HAVE_FCHMODAT")
1996 if self.mac_ver >= (10, 10):
1997 self.assertIn("HAVE_FCHMODAT", posix._have_functions)
1998
1999 else:
2000 self.assertNotIn("HAVE_FCHMODAT", posix._have_functions)
2001 self.assertIn("HAVE_LCHMOD", posix._have_functions)
2002
2003 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2004 os.chmod("file", 0o644, dir_fd=0)
2005
2006 def test_chown(self):
2007 self._verify_available("HAVE_FCHOWNAT")
2008 if self.mac_ver >= (10, 10):
2009 self.assertIn("HAVE_FCHOWNAT", posix._have_functions)
2010
2011 else:
2012 self.assertNotIn("HAVE_FCHOWNAT", posix._have_functions)
2013 self.assertIn("HAVE_LCHOWN", posix._have_functions)
2014
2015 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2016 os.chown("file", 0, 0, dir_fd=0)
2017
2018 def test_link(self):
2019 self._verify_available("HAVE_LINKAT")
2020 if self.mac_ver >= (10, 10):
2021 self.assertIn("HAVE_LINKAT", posix._have_functions)
2022
2023 else:
2024 self.assertNotIn("HAVE_LINKAT", posix._have_functions)
2025
2026 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2027 os.link("source", "target", src_dir_fd=0)
2028
2029 with self.assertRaisesRegex(NotImplementedError, "dst_dir_fd unavailable"):
2030 os.link("source", "target", dst_dir_fd=0)
2031
2032 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2033 os.link("source", "target", src_dir_fd=0, dst_dir_fd=0)
2034
2035 # issue 41355: !HAVE_LINKAT code path ignores the follow_symlinks flag
2036 with os_helper.temp_dir() as base_path:
2037 link_path = os.path.join(base_path, "link")
2038 target_path = os.path.join(base_path, "target")
2039 source_path = os.path.join(base_path, "source")
2040
2041 with open(source_path, "w") as fp:
2042 fp.write("data")
2043
2044 os.symlink("target", link_path)
2045
2046 # Calling os.link should fail in the link(2) call, and
2047 # should not reject *follow_symlinks* (to match the
2048 # behaviour you'd get when building on a platform without
2049 # linkat)
2050 with self.assertRaises(FileExistsError):
2051 os.link(source_path, link_path, follow_symlinks=True)
2052
2053 with self.assertRaises(FileExistsError):
2054 os.link(source_path, link_path, follow_symlinks=False)
2055
2056
2057 def test_listdir_scandir(self):
2058 self._verify_available("HAVE_FDOPENDIR")
2059 if self.mac_ver >= (10, 10):
2060 self.assertIn("HAVE_FDOPENDIR", posix._have_functions)
2061
2062 else:
2063 self.assertNotIn("HAVE_FDOPENDIR", posix._have_functions)
2064
2065 with self.assertRaisesRegex(TypeError, "listdir: path should be string, bytes, os.PathLike or None, not int"):
2066 os.listdir(0)
2067
2068 with self.assertRaisesRegex(TypeError, "scandir: path should be string, bytes, os.PathLike or None, not int"):
2069 os.scandir(0)
2070
2071 def test_mkdir(self):
2072 self._verify_available("HAVE_MKDIRAT")
2073 if self.mac_ver >= (10, 10):
2074 self.assertIn("HAVE_MKDIRAT", posix._have_functions)
2075
2076 else:
2077 self.assertNotIn("HAVE_MKDIRAT", posix._have_functions)
2078
2079 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2080 os.mkdir("dir", dir_fd=0)
2081
2082 def test_rename_replace(self):
2083 self._verify_available("HAVE_RENAMEAT")
2084 if self.mac_ver >= (10, 10):
2085 self.assertIn("HAVE_RENAMEAT", posix._have_functions)
2086
2087 else:
2088 self.assertNotIn("HAVE_RENAMEAT", posix._have_functions)
2089
2090 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2091 os.rename("a", "b", src_dir_fd=0)
2092
2093 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2094 os.rename("a", "b", dst_dir_fd=0)
2095
2096 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2097 os.replace("a", "b", src_dir_fd=0)
2098
2099 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2100 os.replace("a", "b", dst_dir_fd=0)
2101
2102 def test_unlink_rmdir(self):
2103 self._verify_available("HAVE_UNLINKAT")
2104 if self.mac_ver >= (10, 10):
2105 self.assertIn("HAVE_UNLINKAT", posix._have_functions)
2106
2107 else:
2108 self.assertNotIn("HAVE_UNLINKAT", posix._have_functions)
2109
2110 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2111 os.unlink("path", dir_fd=0)
2112
2113 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2114 os.rmdir("path", dir_fd=0)
2115
2116 def test_open(self):
2117 self._verify_available("HAVE_OPENAT")
2118 if self.mac_ver >= (10, 10):
2119 self.assertIn("HAVE_OPENAT", posix._have_functions)
2120
2121 else:
2122 self.assertNotIn("HAVE_OPENAT", posix._have_functions)
2123
2124 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2125 os.open("path", os.O_RDONLY, dir_fd=0)
2126
2127 def test_readlink(self):
2128 self._verify_available("HAVE_READLINKAT")
2129 if self.mac_ver >= (10, 10):
2130 self.assertIn("HAVE_READLINKAT", posix._have_functions)
2131
2132 else:
2133 self.assertNotIn("HAVE_READLINKAT", posix._have_functions)
2134
2135 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2136 os.readlink("path", dir_fd=0)
2137
2138 def test_symlink(self):
2139 self._verify_available("HAVE_SYMLINKAT")
2140 if self.mac_ver >= (10, 10):
2141 self.assertIn("HAVE_SYMLINKAT", posix._have_functions)
2142
2143 else:
2144 self.assertNotIn("HAVE_SYMLINKAT", posix._have_functions)
2145
2146 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2147 os.symlink("a", "b", dir_fd=0)
2148
2149 def test_utime(self):
2150 self._verify_available("HAVE_FUTIMENS")
2151 self._verify_available("HAVE_UTIMENSAT")
2152 if self.mac_ver >= (10, 13):
2153 self.assertIn("HAVE_FUTIMENS", posix._have_functions)
2154 self.assertIn("HAVE_UTIMENSAT", posix._have_functions)
2155
2156 else:
2157 self.assertNotIn("HAVE_FUTIMENS", posix._have_functions)
2158 self.assertNotIn("HAVE_UTIMENSAT", posix._have_functions)
2159
2160 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2161 os.utime("path", dir_fd=0)
2162
2163
Neal Norwitze241ce82003-02-17 18:17:05 +00002164def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01002165 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002166 support.run_unittest(
2167 PosixTester,
2168 PosixGroupsTester,
2169 TestPosixSpawn,
2170 TestPosixSpawnP,
Ronald Oussoren41761932020-11-08 10:05:27 +01002171 TestPosixWeaklinking
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002172 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01002173 finally:
2174 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00002175
2176if __name__ == '__main__':
2177 test_main()