blob: a522717751ac17a72e5b6df5e3113c34f1e7e48a [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):
Hai Shibb0424b2020-08-04 00:47:42 +0800645 os_helper.unlink(os_helper.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100646 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800647 posix.mkfifo(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
xdegaye92c2ca72017-11-12 17:31:07 +0100648 except PermissionError as e:
649 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +0800650 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000651
652 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
653 "don't have mknod()/S_IFIFO")
654 def test_mknod(self):
655 # Test using mknod() to create a FIFO (the only use specified
656 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +0800657 os_helper.unlink(os_helper.TESTFN)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000658 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
659 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800660 posix.mknod(os_helper.TESTFN, mode, 0)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000661 except OSError as e:
662 # Some old systems don't allow unprivileged users to use
663 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100664 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000665 else:
Hai Shibb0424b2020-08-04 00:47:42 +0800666 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000667
Martin Panterbf19d162015-09-09 01:01:13 +0000668 # Keyword arguments are also supported
Hai Shibb0424b2020-08-04 00:47:42 +0800669 os_helper.unlink(os_helper.TESTFN)
Martin Panterbf19d162015-09-09 01:01:13 +0000670 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800671 posix.mknod(path=os_helper.TESTFN, mode=mode, device=0,
Martin Panterbf19d162015-09-09 01:01:13 +0000672 dir_fd=None)
673 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100674 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000675
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300676 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
677 def test_makedev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800678 st = posix.stat(os_helper.TESTFN)
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300679 dev = st.st_dev
680 self.assertIsInstance(dev, int)
681 self.assertGreaterEqual(dev, 0)
682
683 major = posix.major(dev)
684 self.assertIsInstance(major, int)
685 self.assertGreaterEqual(major, 0)
686 self.assertEqual(posix.major(dev), major)
687 self.assertRaises(TypeError, posix.major, float(dev))
688 self.assertRaises(TypeError, posix.major)
689 self.assertRaises((ValueError, OverflowError), posix.major, -1)
690
691 minor = posix.minor(dev)
692 self.assertIsInstance(minor, int)
693 self.assertGreaterEqual(minor, 0)
694 self.assertEqual(posix.minor(dev), minor)
695 self.assertRaises(TypeError, posix.minor, float(dev))
696 self.assertRaises(TypeError, posix.minor)
697 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
698
699 self.assertEqual(posix.makedev(major, minor), dev)
700 self.assertRaises(TypeError, posix.makedev, float(major), minor)
701 self.assertRaises(TypeError, posix.makedev, major, float(minor))
702 self.assertRaises(TypeError, posix.makedev, major)
703 self.assertRaises(TypeError, posix.makedev)
704
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200705 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000706 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200707 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200708 if stat_func is not None:
709 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200710 self.assertEqual(stat.st_uid, uid)
711 self.assertEqual(stat.st_gid, gid)
712 uid = os.getuid()
713 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200714 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200715 chown_func(first_param, uid, gid)
716 check_stat(uid, gid)
717 chown_func(first_param, -1, gid)
718 check_stat(uid, gid)
719 chown_func(first_param, uid, -1)
720 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200721
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200722 if uid == 0:
723 # Try an amusingly large uid/gid to make sure we handle
724 # large unsigned values. (chown lets you use any
725 # uid/gid you like, even if they aren't defined.)
726 #
727 # This problem keeps coming up:
728 # http://bugs.python.org/issue1747858
729 # http://bugs.python.org/issue4591
730 # http://bugs.python.org/issue15301
731 # Hopefully the fix in 4591 fixes it for good!
732 #
733 # This part of the test only runs when run as root.
734 # Only scary people run their tests as root.
735
736 big_value = 2**31
737 chown_func(first_param, big_value, big_value)
738 check_stat(big_value, big_value)
739 chown_func(first_param, -1, -1)
740 check_stat(big_value, big_value)
741 chown_func(first_param, uid, gid)
742 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200743 elif platform.system() in ('HP-UX', 'SunOS'):
744 # HP-UX and Solaris can allow a non-root user to chown() to root
745 # (issue #5113)
746 raise unittest.SkipTest("Skipping because of non-standard chown() "
747 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000748 else:
749 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200750 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200751 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200752 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200753 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200754 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200755 self.assertRaises(OSError, chown_func, first_param, -1, 0)
756 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200757 # test illegal types
758 for t in str, float:
759 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
760 check_stat(uid, gid)
761 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
762 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000763
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000764 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
765 def test_chown(self):
766 # raise an OSError if the file does not exist
Hai Shibb0424b2020-08-04 00:47:42 +0800767 os.unlink(os_helper.TESTFN)
768 self.assertRaises(OSError, posix.chown, os_helper.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000769
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000770 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800771 os_helper.create_empty_file(os_helper.TESTFN)
772 self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000773
774 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
775 def test_fchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800776 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000777
778 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800779 test_file = open(os_helper.TESTFN, 'w')
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000780 try:
781 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200782 self._test_all_chown_common(posix.fchown, fd,
783 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000784 finally:
785 test_file.close()
786
787 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
788 def test_lchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800789 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000790 # create a symlink
Hai Shibb0424b2020-08-04 00:47:42 +0800791 os.symlink(_DUMMY_SYMLINK, os_helper.TESTFN)
792 self._test_all_chown_common(posix.lchown, os_helper.TESTFN,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200793 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000794
Serhiy Storchaka43767632013-11-03 21:31:38 +0200795 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000796 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200797 posix.chdir(os.curdir)
Hai Shibb0424b2020-08-04 00:47:42 +0800798 self.assertRaises(OSError, posix.chdir, os_helper.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000799
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000800 def test_listdir(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800801 self.assertIn(os_helper.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000802
803 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700804 # When listdir is called without argument,
805 # it's the same as listdir(os.curdir).
Hai Shibb0424b2020-08-04 00:47:42 +0800806 self.assertIn(os_helper.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000807
Larry Hastingsfdaea062012-06-25 04:42:23 -0700808 def test_listdir_bytes(self):
809 # When listdir is called with a bytes object,
810 # the returned strings are of type bytes.
Hai Shibb0424b2020-08-04 00:47:42 +0800811 self.assertIn(os.fsencode(os_helper.TESTFN), posix.listdir(b'.'))
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300812
813 def test_listdir_bytes_like(self):
814 for cls in bytearray, memoryview:
815 with self.assertWarns(DeprecationWarning):
816 names = posix.listdir(cls(b'.'))
Hai Shibb0424b2020-08-04 00:47:42 +0800817 self.assertIn(os.fsencode(os_helper.TESTFN), names)
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300818 for name in names:
819 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700820
821 @unittest.skipUnless(posix.listdir in os.supports_fd,
822 "test needs fd support for posix.listdir()")
823 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000824 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100825 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000826 self.assertEqual(
827 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700828 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000829 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100830 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100831 self.assertEqual(
832 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700833 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100834 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000835
Serhiy Storchaka43767632013-11-03 21:31:38 +0200836 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000837 def test_access(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800838 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000839
Serhiy Storchaka43767632013-11-03 21:31:38 +0200840 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000841 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200842 old_mask = posix.umask(0)
843 self.assertIsInstance(old_mask, int)
844 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000845
Serhiy Storchaka43767632013-11-03 21:31:38 +0200846 @unittest.skipUnless(hasattr(posix, 'strerror'),
847 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000848 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200849 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000850
Serhiy Storchaka43767632013-11-03 21:31:38 +0200851 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000852 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200853 reader, writer = posix.pipe()
854 os.close(reader)
855 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000856
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200857 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200858 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200859 def test_pipe2(self):
860 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
861 self.assertRaises(TypeError, os.pipe2, 0, 0)
862
Charles-François Natali368f34b2011-06-06 19:49:47 +0200863 # try calling with flags = 0, like os.pipe()
864 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200865 os.close(r)
866 os.close(w)
867
868 # test flags
869 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
870 self.addCleanup(os.close, r)
871 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200872 self.assertFalse(os.get_inheritable(r))
873 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200874 self.assertFalse(os.get_blocking(r))
875 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200876 # try reading from an empty pipe: this should fail, not block
877 self.assertRaises(OSError, os.read, r, 1)
878 # try a write big enough to fill-up the pipe: this should either
879 # fail or perform a partial write, not block
880 try:
881 os.write(w, b'x' * support.PIPE_MAX_SIZE)
882 except OSError:
883 pass
884
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200885 @support.cpython_only
886 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
887 @support.requires_linux_version(2, 6, 27)
888 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200889 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200890 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200891 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
892 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
893
Serhiy Storchaka43767632013-11-03 21:31:38 +0200894 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000895 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200896 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800897 posix.utime(os_helper.TESTFN, None)
898 self.assertRaises(TypeError, posix.utime,
899 os_helper.TESTFN, (None, None))
900 self.assertRaises(TypeError, posix.utime,
901 os_helper.TESTFN, (now, None))
902 self.assertRaises(TypeError, posix.utime,
903 os_helper.TESTFN, (None, now))
904 posix.utime(os_helper.TESTFN, (int(now), int(now)))
905 posix.utime(os_helper.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000906
Larry Hastings9cf065c2012-06-22 16:30:09 -0700907 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700908 st = os.stat(target_file)
909 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000910
911 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
912 flags = st.st_flags | stat.UF_IMMUTABLE
913 try:
914 chflags_func(target_file, flags, **kwargs)
915 except OSError as err:
916 if err.errno != errno.EOPNOTSUPP:
917 raise
918 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
919 self.skipTest(msg)
920
Ned Deily3eb67d52011-06-28 00:00:28 -0700921 try:
922 new_st = os.stat(target_file)
923 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
924 try:
925 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200926 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700927 self.assertEqual(e.errno, errno.EPERM)
928 finally:
929 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000930
Ned Deily3eb67d52011-06-28 00:00:28 -0700931 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
932 def test_chflags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800933 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700934
935 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
936 def test_lchflags_regular_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800937 self._test_chflags_regular_file(posix.lchflags, os_helper.TESTFN)
938 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN,
939 follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700940
941 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
942 def test_lchflags_symlink(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800943 testfn_st = os.stat(os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700944
945 self.assertTrue(hasattr(testfn_st, 'st_flags'))
946
Hai Shibb0424b2020-08-04 00:47:42 +0800947 os.symlink(os_helper.TESTFN, _DUMMY_SYMLINK)
Ned Deily3eb67d52011-06-28 00:00:28 -0700948 self.teardown_files.append(_DUMMY_SYMLINK)
949 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
950
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 def chflags_nofollow(path, flags):
952 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700953
Larry Hastings9cf065c2012-06-22 16:30:09 -0700954 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000955 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
956 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
957 try:
958 fn(_DUMMY_SYMLINK, flags)
959 except OSError as err:
960 if err.errno != errno.EOPNOTSUPP:
961 raise
962 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
963 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700964 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800965 new_testfn_st = os.stat(os_helper.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
967
968 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
969 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
970 new_dummy_symlink_st.st_flags)
971 finally:
972 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000973
Guido van Rossum98297ee2007-11-06 21:34:58 +0000974 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000975 if os.name == "nt":
976 item_type = str
977 else:
978 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000979 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000980 self.assertEqual(type(k), item_type)
981 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000982
Serhiy Storchaka77703942017-06-25 07:33:01 +0300983 def test_putenv(self):
984 with self.assertRaises(ValueError):
985 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
986 with self.assertRaises(ValueError):
987 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
988 with self.assertRaises(ValueError):
989 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
990 with self.assertRaises(ValueError):
991 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
992 with self.assertRaises(ValueError):
993 os.putenv('FRUIT=ORANGE', 'lemon')
994 with self.assertRaises(ValueError):
995 os.putenv(b'FRUIT=ORANGE', b'lemon')
996
Serhiy Storchaka43767632013-11-03 21:31:38 +0200997 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000998 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500999 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
1000 curdir = os.getcwd()
Hai Shibb0424b2020-08-04 00:47:42 +08001001 base_path = os.path.abspath(os_helper.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001002
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001003 try:
1004 os.mkdir(base_path)
1005 os.chdir(base_path)
1006 except:
1007 # Just returning nothing instead of the SkipTest exception, because
1008 # the test results in Error in that case. Is that ok?
1009 # raise unittest.SkipTest("cannot create directory for testing")
1010 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001011
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001012 def _create_and_do_getcwd(dirname, current_path_length = 0):
1013 try:
1014 os.mkdir(dirname)
1015 except:
1016 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001017
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001018 os.chdir(dirname)
1019 try:
1020 os.getcwd()
1021 if current_path_length < 1027:
1022 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1023 finally:
1024 os.chdir('..')
1025 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001026
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001027 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001028
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001029 finally:
1030 os.chdir(curdir)
Hai Shibb0424b2020-08-04 00:47:42 +08001031 os_helper.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001032
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001033 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1034 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1035 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1036 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001037 user = pwd.getpwuid(os.getuid())[0]
1038 group = pwd.getpwuid(os.getuid())[3]
1039 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001040
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001041
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001042 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001043 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001044 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001045 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001046 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001047
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001048 try:
1049 idg_groups = set(int(g) for g in groups.split())
1050 except ValueError:
1051 idg_groups = set()
1052 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001053 raise unittest.SkipTest("need working 'id -G'")
1054
Ned Deily028915e2013-02-02 15:08:52 -08001055 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1056 if sys.platform == 'darwin':
1057 import sysconfig
1058 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001059 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001060 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1061
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001062 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001063 # groups, ignoring order, duplicates, and the effective gid.
1064 # #10822/#26944 - It is implementation defined whether
1065 # posix.getgroups() includes the effective gid.
1066 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1067 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001068
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001069 # tests for the posix *at functions follow
1070
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1072 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001073 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1074 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001075 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001076 finally:
1077 posix.close(f)
1078
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1080 def test_chmod_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001081 os.chmod(os_helper.TESTFN, stat.S_IRUSR)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001082
1083 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1084 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001085 posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001086
Hai Shibb0424b2020-08-04 00:47:42 +08001087 s = posix.stat(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001088 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1089 finally:
1090 posix.close(f)
1091
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1093 def test_chown_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001094 os_helper.unlink(os_helper.TESTFN)
1095 os_helper.create_empty_file(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001096
1097 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1098 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001099 posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001100 finally:
1101 posix.close(f)
1102
Larry Hastings9cf065c2012-06-22 16:30:09 -07001103 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1104 def test_stat_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001105 os_helper.unlink(os_helper.TESTFN)
1106 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001107 outfile.write("testline\n")
1108
1109 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1110 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001111 s1 = posix.stat(os_helper.TESTFN)
1112 s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001113 self.assertEqual(s1, s2)
Hai Shibb0424b2020-08-04 00:47:42 +08001114 s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001115 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001116 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001117 posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001118 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001119 posix.stat, os_helper.TESTFN, dir_fd=float(f))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001120 self.assertRaises(OverflowError,
Hai Shibb0424b2020-08-04 00:47:42 +08001121 posix.stat, os_helper.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001122 finally:
1123 posix.close(f)
1124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1126 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001127 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1128 try:
1129 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +08001130 posix.utime(os_helper.TESTFN, None, dir_fd=f)
1131 posix.utime(os_helper.TESTFN, dir_fd=f)
1132 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1133 now, dir_fd=f)
1134 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1135 (None, None), dir_fd=f)
1136 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1137 (now, None), dir_fd=f)
1138 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1139 (None, now), dir_fd=f)
1140 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1141 (now, "x"), dir_fd=f)
1142 posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
1143 posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
1144 posix.utime(os_helper.TESTFN,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001145 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
Hai Shibb0424b2020-08-04 00:47:42 +08001146 posix.utime(os_helper.TESTFN, dir_fd=f,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147 times=(int(now), int((now - int(now)) * 1e9)))
1148
Larry Hastings90867a52012-06-22 17:01:41 -07001149 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001151 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001152 posix.utime(os_helper.TESTFN, follow_symlinks=False,
1153 dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001154 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001155 # whoops! using both together not supported on this platform.
1156 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001157
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001158 finally:
1159 posix.close(f)
1160
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1162 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001163 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1164 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001165 posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link',
1166 src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001167 except PermissionError as e:
1168 self.skipTest('posix.link(): %s' % e)
1169 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001170 # should have same inodes
Hai Shibb0424b2020-08-04 00:47:42 +08001171 self.assertEqual(posix.stat(os_helper.TESTFN)[1],
1172 posix.stat(os_helper.TESTFN + 'link')[1])
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001173 finally:
1174 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001175 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001176
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1178 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001179 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1180 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001181 posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
1182 posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001183 finally:
1184 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001185 os_helper.rmtree(os_helper.TESTFN + 'dir')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001186
Larry Hastings9cf065c2012-06-22 16:30:09 -07001187 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1188 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1189 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001190 # Test using mknodat() to create a FIFO (the only use specified
1191 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +08001192 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001193 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1194 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1195 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001196 posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001197 except OSError as e:
1198 # Some old systems don't allow unprivileged users to use
1199 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001200 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001201 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001202 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001203 finally:
1204 posix.close(f)
1205
Larry Hastings9cf065c2012-06-22 16:30:09 -07001206 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1207 def test_open_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001208 os_helper.unlink(os_helper.TESTFN)
1209 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001210 outfile.write("testline\n")
1211 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001212 b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001213 try:
1214 res = posix.read(b, 9).decode(encoding="utf-8")
1215 self.assertEqual("testline\n", res)
1216 finally:
1217 posix.close(a)
1218 posix.close(b)
1219
Larry Hastings9cf065c2012-06-22 16:30:09 -07001220 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1221 def test_readlink_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001222 os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001223 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1224 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001225 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1226 posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001227 finally:
Hai Shibb0424b2020-08-04 00:47:42 +08001228 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001229 posix.close(f)
1230
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1232 def test_rename_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001233 os_helper.unlink(os_helper.TESTFN)
1234 os_helper.create_empty_file(os_helper.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001235 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1236 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001237 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001238 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001239 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001240 raise
1241 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001242 posix.stat(os_helper.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001243 finally:
1244 posix.close(f)
1245
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001246 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1247 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1248 def test_cld_xxxx_constants(self):
1249 os.CLD_EXITED
1250 os.CLD_KILLED
1251 os.CLD_DUMPED
1252 os.CLD_TRAPPED
1253 os.CLD_STOPPED
1254 os.CLD_CONTINUED
1255
Larry Hastings9cf065c2012-06-22 16:30:09 -07001256 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1257 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001258 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1259 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001260 posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link',
1261 dir_fd=f)
1262 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1263 os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001264 finally:
1265 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001266 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001267
Larry Hastings9cf065c2012-06-22 16:30:09 -07001268 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1269 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001270 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001271 os_helper.create_empty_file(os_helper.TESTFN + 'del')
1272 posix.stat(os_helper.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001273 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001274 posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001275 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001276 os_helper.unlink(os_helper.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001277 raise
1278 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001279 self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001280 finally:
1281 posix.close(f)
1282
Larry Hastings9cf065c2012-06-22 16:30:09 -07001283 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1284 def test_mkfifo_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001285 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001286 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1287 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001288 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001289 posix.mkfifo(os_helper.TESTFN,
xdegaye92c2ca72017-11-12 17:31:07 +01001290 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1291 except PermissionError as e:
1292 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +08001293 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001294 finally:
1295 posix.close(f)
1296
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001297 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1298 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001299 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001300 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001301
1302 @requires_sched_h
1303 def test_sched_yield(self):
1304 # This has no error conditions (at least on Linux).
1305 posix.sched_yield()
1306
1307 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001308 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1309 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001310 def test_sched_priority(self):
1311 # Round-robin usually has interesting priorities.
1312 pol = posix.SCHED_RR
1313 lo = posix.sched_get_priority_min(pol)
1314 hi = posix.sched_get_priority_max(pol)
1315 self.assertIsInstance(lo, int)
1316 self.assertIsInstance(hi, int)
1317 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001318 # OSX evidently just returns 15 without checking the argument.
1319 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001320 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1321 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001322
Benjamin Petersonc7042222018-09-12 15:12:24 -07001323 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001324 def test_get_and_set_scheduler_and_param(self):
1325 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1326 if name.startswith("SCHED_")]
1327 mine = posix.sched_getscheduler(0)
1328 self.assertIn(mine, possible_schedulers)
1329 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001330 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001331 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001332 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001333 raise
1334 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001335 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001336 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1337 self.assertRaises(OSError, posix.sched_getparam, -1)
1338 param = posix.sched_getparam(0)
1339 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001340
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001341 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1342 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1343 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1344 if not sys.platform.startswith(('freebsd', 'netbsd')):
1345 try:
1346 posix.sched_setscheduler(0, mine, param)
1347 posix.sched_setparam(0, param)
1348 except OSError as e:
1349 if e.errno != errno.EPERM:
1350 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001351 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1352
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001353 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1354 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1355 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1356 param = posix.sched_param(None)
1357 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1358 large = 214748364700
1359 param = posix.sched_param(large)
1360 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1361 param = posix.sched_param(sched_priority=-large)
1362 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1363
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001364 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001365 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001366 try:
1367 interval = posix.sched_rr_get_interval(0)
1368 except OSError as e:
1369 # This likely means that sched_rr_get_interval is only valid for
1370 # processes with the SCHED_RR scheduler in effect.
1371 if e.errno != errno.EINVAL:
1372 raise
1373 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001374 self.assertIsInstance(interval, float)
1375 # Reasonable constraints, I think.
1376 self.assertGreaterEqual(interval, 0.)
1377 self.assertLess(interval, 1.)
1378
Benjamin Peterson2740af82011-08-02 17:41:34 -05001379 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001380 def test_sched_getaffinity(self):
1381 mask = posix.sched_getaffinity(0)
1382 self.assertIsInstance(mask, set)
1383 self.assertGreaterEqual(len(mask), 1)
1384 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1385 for cpu in mask:
1386 self.assertIsInstance(cpu, int)
1387 self.assertGreaterEqual(cpu, 0)
1388 self.assertLess(cpu, 1 << 32)
1389
1390 @requires_sched_affinity
1391 def test_sched_setaffinity(self):
1392 mask = posix.sched_getaffinity(0)
1393 if len(mask) > 1:
1394 # Empty masks are forbidden
1395 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001396 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001397 self.assertEqual(posix.sched_getaffinity(0), mask)
1398 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1399 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001400 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001401 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001402 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1403
Victor Stinner8b905bd2011-10-25 13:34:04 +02001404 def test_rtld_constants(self):
1405 # check presence of major RTLD_* constants
1406 posix.RTLD_LAZY
1407 posix.RTLD_NOW
1408 posix.RTLD_GLOBAL
1409 posix.RTLD_LOCAL
1410
Jesus Cea60c13dd2012-06-23 02:58:14 +02001411 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1412 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001413 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001414 # Even if the filesystem doesn't report holes,
1415 # if the OS supports it the SEEK_* constants
1416 # will be defined and will have a consistent
1417 # behaviour:
1418 # os.SEEK_DATA = current position
1419 # os.SEEK_HOLE = end of file position
Hai Shibb0424b2020-08-04 00:47:42 +08001420 with open(os_helper.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001421 fp.write(b"hello")
1422 fp.flush()
1423 size = fp.tell()
1424 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001425 try :
1426 for i in range(size):
1427 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1428 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1429 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1430 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1431 except OSError :
1432 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1433 # but it is not true.
1434 # For instance:
1435 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1436 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001437
Larry Hastingsb0827312014-02-09 22:05:19 -08001438 def test_path_error2(self):
1439 """
1440 Test functions that call path_error2(), providing two filenames in their exceptions.
1441 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001442 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001443 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001444 if function is None:
1445 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001446
Hai Shibb0424b2020-08-04 00:47:42 +08001447 for dst in ("noodly2", os_helper.TESTFN):
Victor Stinnerbed04a72014-10-05 17:37:59 +02001448 try:
1449 function('doesnotexistfilename', dst)
1450 except OSError as e:
1451 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1452 break
1453 else:
1454 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001455
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001456 def test_path_with_null_character(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001457 fn = os_helper.TESTFN
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001458 fn_with_NUL = fn + '\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001459 self.addCleanup(os_helper.unlink, fn)
1460 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001461 fd = None
1462 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001463 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001464 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1465 finally:
1466 if fd is not None:
1467 os.close(fd)
1468 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001469 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001470 self.assertFalse(os.path.exists(fn))
1471 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001472 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001473
1474 def test_path_with_null_byte(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001475 fn = os.fsencode(os_helper.TESTFN)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001476 fn_with_NUL = fn + b'\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001477 self.addCleanup(os_helper.unlink, fn)
1478 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001479 fd = None
1480 try:
1481 with self.assertRaises(ValueError):
1482 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1483 finally:
1484 if fd is not None:
1485 os.close(fd)
1486 self.assertFalse(os.path.exists(fn))
1487 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1488 self.assertFalse(os.path.exists(fn))
1489 open(fn, 'wb').close()
1490 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1491
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001492 @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1493 def test_pidfd_open(self):
1494 with self.assertRaises(OSError) as cm:
1495 os.pidfd_open(-1)
1496 if cm.exception.errno == errno.ENOSYS:
1497 self.skipTest("system does not support pidfd_open")
Victor Stinner3ab479a2019-11-21 12:54:54 +01001498 if isinstance(cm.exception, PermissionError):
1499 self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}")
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001500 self.assertEqual(cm.exception.errno, errno.EINVAL)
1501 os.close(os.pidfd_open(os.getpid(), 0))
1502
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001503class PosixGroupsTester(unittest.TestCase):
1504
1505 def setUp(self):
1506 if posix.getuid() != 0:
1507 raise unittest.SkipTest("not enough privileges")
1508 if not hasattr(posix, 'getgroups'):
1509 raise unittest.SkipTest("need posix.getgroups")
1510 if sys.platform == 'darwin':
1511 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1512 self.saved_groups = posix.getgroups()
1513
1514 def tearDown(self):
1515 if hasattr(posix, 'setgroups'):
1516 posix.setgroups(self.saved_groups)
1517 elif hasattr(posix, 'initgroups'):
1518 name = pwd.getpwuid(posix.getuid()).pw_name
1519 posix.initgroups(name, self.saved_groups[0])
1520
1521 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1522 "test needs posix.initgroups()")
1523 def test_initgroups(self):
1524 # find missing group
1525
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001526 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001527 name = pwd.getpwuid(posix.getuid()).pw_name
1528 posix.initgroups(name, g)
1529 self.assertIn(g, posix.getgroups())
1530
1531 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1532 "test needs posix.setgroups()")
1533 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001534 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001535 posix.setgroups(groups)
1536 self.assertListEqual(groups, posix.getgroups())
1537
Serhiy Storchakaef347532018-05-01 16:45:04 +03001538
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001539class _PosixSpawnMixin:
1540 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001541 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001542 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001543
1544 def python_args(self, *args):
1545 # Disable site module to avoid side effects. For example,
1546 # on Fedora 28, if the HOME environment variable is not set,
1547 # site._getuserbase() calls pwd.getpwuid() which opens
1548 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1549 # test_close_file() to fail.
1550 return (sys.executable, '-I', '-S', *args)
1551
Serhiy Storchakaef347532018-05-01 16:45:04 +03001552 def test_returns_pid(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001553 pidfile = os_helper.TESTFN
1554 self.addCleanup(os_helper.unlink, pidfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001555 script = f"""if 1:
1556 import os
1557 with open({pidfile!r}, "w") as pidfile:
1558 pidfile.write(str(os.getpid()))
1559 """
Victor Stinner03824062018-08-30 01:21:11 +02001560 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001561 pid = self.spawn_func(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001562 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001563 with open(pidfile) as f:
1564 self.assertEqual(f.read(), str(pid))
1565
1566 def test_no_such_executable(self):
1567 no_such_executable = 'no_such_executable'
1568 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001569 pid = self.spawn_func(no_such_executable,
1570 [no_such_executable],
1571 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001572 # bpo-35794: PermissionError can be raised if there are
1573 # directories in the $PATH that are not accessible.
1574 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001575 self.assertEqual(exc.filename, no_such_executable)
1576 else:
1577 pid2, status = os.waitpid(pid, 0)
1578 self.assertEqual(pid2, pid)
1579 self.assertNotEqual(status, 0)
1580
1581 def test_specify_environment(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001582 envfile = os_helper.TESTFN
1583 self.addCleanup(os_helper.unlink, envfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001584 script = f"""if 1:
1585 import os
1586 with open({envfile!r}, "w") as envfile:
1587 envfile.write(os.environ['foo'])
1588 """
Victor Stinner03824062018-08-30 01:21:11 +02001589 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001590 pid = self.spawn_func(args[0], args,
1591 {**os.environ, 'foo': 'bar'})
Victor Stinner278c1e12020-03-31 20:08:12 +02001592 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001593 with open(envfile) as f:
1594 self.assertEqual(f.read(), 'bar')
1595
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001596 def test_none_file_actions(self):
1597 pid = self.spawn_func(
1598 self.NOOP_PROGRAM[0],
1599 self.NOOP_PROGRAM,
1600 os.environ,
1601 file_actions=None
1602 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001603 support.wait_process(pid, exitcode=0)
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001604
Serhiy Storchakaef347532018-05-01 16:45:04 +03001605 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001606 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001607 self.NOOP_PROGRAM[0],
1608 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001609 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001610 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001611 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001612 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001613
Pablo Galindo254a4662018-09-07 16:44:24 +01001614 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001615 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001616 sys.executable,
1617 [sys.executable, '-c', 'pass'],
1618 os.environ,
1619 resetids=False
1620 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001621 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001622
1623 def test_resetids(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=True
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_wrong_type(self):
1633 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001634 self.spawn_func(sys.executable,
1635 [sys.executable, "-c", "pass"],
1636 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001637
1638 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001639 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001640 sys.executable,
1641 [sys.executable, '-c', 'pass'],
1642 os.environ,
1643 setpgroup=os.getpgrp()
1644 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001645 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001646
1647 def test_setpgroup_wrong_type(self):
1648 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001649 self.spawn_func(sys.executable,
1650 [sys.executable, "-c", "pass"],
1651 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001652
1653 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1654 'need signal.pthread_sigmask()')
1655 def test_setsigmask(self):
1656 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001657 import signal
1658 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001659
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001660 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001661 sys.executable,
1662 [sys.executable, '-c', code],
1663 os.environ,
1664 setsigmask=[signal.SIGUSR1]
1665 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001666 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001667
1668 def test_setsigmask_wrong_type(self):
1669 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001670 self.spawn_func(sys.executable,
1671 [sys.executable, "-c", "pass"],
1672 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001673 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001674 self.spawn_func(sys.executable,
1675 [sys.executable, "-c", "pass"],
1676 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001677 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001678 self.spawn_func(sys.executable,
1679 [sys.executable, "-c", "pass"],
1680 os.environ, setsigmask=[signal.NSIG,
1681 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001682
Victor Stinner58840432019-06-14 19:31:43 +02001683 def test_setsid(self):
1684 rfd, wfd = os.pipe()
1685 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001686 try:
Victor Stinner58840432019-06-14 19:31:43 +02001687 os.set_inheritable(wfd, True)
1688
1689 code = textwrap.dedent(f"""
1690 import os
1691 fd = {wfd}
1692 sid = os.getsid(0)
1693 os.write(fd, str(sid).encode())
1694 """)
1695
1696 try:
1697 pid = self.spawn_func(sys.executable,
1698 [sys.executable, "-c", code],
1699 os.environ, setsid=True)
1700 except NotImplementedError as exc:
1701 self.skipTest(f"setsid is not supported: {exc!r}")
1702 except PermissionError as exc:
1703 self.skipTest(f"setsid failed with: {exc!r}")
1704 finally:
1705 os.close(wfd)
1706
Victor Stinner278c1e12020-03-31 20:08:12 +02001707 support.wait_process(pid, exitcode=0)
1708
Victor Stinner58840432019-06-14 19:31:43 +02001709 output = os.read(rfd, 100)
1710 child_sid = int(output)
1711 parent_sid = os.getsid(os.getpid())
1712 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001713
Pablo Galindo254a4662018-09-07 16:44:24 +01001714 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1715 'need signal.pthread_sigmask()')
1716 def test_setsigdef(self):
1717 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1718 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001719 import signal
1720 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001721 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001722 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001723 sys.executable,
1724 [sys.executable, '-c', code],
1725 os.environ,
1726 setsigdef=[signal.SIGUSR1]
1727 )
1728 finally:
1729 signal.signal(signal.SIGUSR1, original_handler)
1730
Victor Stinner278c1e12020-03-31 20:08:12 +02001731 support.wait_process(pid, exitcode=-signal.SIGUSR1)
Pablo Galindo254a4662018-09-07 16:44:24 +01001732
1733 def test_setsigdef_wrong_type(self):
1734 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001735 self.spawn_func(sys.executable,
1736 [sys.executable, "-c", "pass"],
1737 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001738 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001739 self.spawn_func(sys.executable,
1740 [sys.executable, "-c", "pass"],
1741 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001742 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001743 self.spawn_func(sys.executable,
1744 [sys.executable, "-c", "pass"],
1745 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001746
Benjamin Petersonc7042222018-09-12 15:12:24 -07001747 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001748 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1749 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001750 def test_setscheduler_only_param(self):
1751 policy = os.sched_getscheduler(0)
1752 priority = os.sched_get_priority_min(policy)
1753 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001754 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001755 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001756 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001757 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001758 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001759 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001760 sys.executable,
1761 [sys.executable, '-c', code],
1762 os.environ,
1763 scheduler=(None, os.sched_param(priority))
1764 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001765 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001766
Benjamin Petersonc7042222018-09-12 15:12:24 -07001767 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001768 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1769 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001770 def test_setscheduler_with_policy(self):
1771 policy = os.sched_getscheduler(0)
1772 priority = os.sched_get_priority_min(policy)
1773 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001774 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001775 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001776 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001777 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001778 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001779 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001780 sys.executable,
1781 [sys.executable, '-c', code],
1782 os.environ,
1783 scheduler=(policy, os.sched_param(priority))
1784 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001785 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001786
Serhiy Storchakaef347532018-05-01 16:45:04 +03001787 def test_multiple_file_actions(self):
1788 file_actions = [
1789 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1790 (os.POSIX_SPAWN_CLOSE, 0),
1791 (os.POSIX_SPAWN_DUP2, 1, 4),
1792 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001793 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1794 self.NOOP_PROGRAM,
1795 os.environ,
1796 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001797 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001798
1799 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001800 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001801 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001802 self.spawn_func(args[0], args, os.environ,
1803 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001804 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001805 self.spawn_func(args[0], args, os.environ,
1806 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001807 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001808 self.spawn_func(args[0], args, os.environ,
1809 file_actions=[(None,)])
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=[(12345,)])
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=[(os.POSIX_SPAWN_CLOSE,)])
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=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
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=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001822 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001823 self.spawn_func(args[0], args, os.environ,
1824 file_actions=[(os.POSIX_SPAWN_OPEN,
1825 3, __file__ + '\0',
1826 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001827
1828 def test_open_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001829 outfile = os_helper.TESTFN
1830 self.addCleanup(os_helper.unlink, outfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001831 script = """if 1:
1832 import sys
1833 sys.stdout.write("hello")
1834 """
1835 file_actions = [
1836 (os.POSIX_SPAWN_OPEN, 1, outfile,
1837 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1838 stat.S_IRUSR | stat.S_IWUSR),
1839 ]
Victor Stinner03824062018-08-30 01:21:11 +02001840 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001841 pid = self.spawn_func(args[0], args, os.environ,
1842 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001843
1844 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001845 with open(outfile) as f:
1846 self.assertEqual(f.read(), 'hello')
1847
1848 def test_close_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001849 closefile = os_helper.TESTFN
1850 self.addCleanup(os_helper.unlink, closefile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001851 script = f"""if 1:
1852 import os
1853 try:
1854 os.fstat(0)
1855 except OSError as e:
1856 with open({closefile!r}, 'w') as closefile:
1857 closefile.write('is closed %d' % e.errno)
1858 """
Victor Stinner03824062018-08-30 01:21:11 +02001859 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001860 pid = self.spawn_func(args[0], args, os.environ,
1861 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Victor Stinner278c1e12020-03-31 20:08:12 +02001862
1863 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001864 with open(closefile) as f:
1865 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1866
1867 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001868 dupfile = os_helper.TESTFN
1869 self.addCleanup(os_helper.unlink, dupfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001870 script = """if 1:
1871 import sys
1872 sys.stdout.write("hello")
1873 """
1874 with open(dupfile, "wb") as childfile:
1875 file_actions = [
1876 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1877 ]
Victor Stinner03824062018-08-30 01:21:11 +02001878 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001879 pid = self.spawn_func(args[0], args, os.environ,
1880 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001881 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001882 with open(dupfile) as f:
1883 self.assertEqual(f.read(), 'hello')
1884
1885
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001886@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1887class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1888 spawn_func = getattr(posix, 'posix_spawn', None)
1889
1890
1891@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1892class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1893 spawn_func = getattr(posix, 'posix_spawnp', None)
1894
Hai Shibb0424b2020-08-04 00:47:42 +08001895 @os_helper.skip_unless_symlink
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001896 def test_posix_spawnp(self):
1897 # Use a symlink to create a program in its own temporary directory
1898 temp_dir = tempfile.mkdtemp()
Hai Shibb0424b2020-08-04 00:47:42 +08001899 self.addCleanup(os_helper.rmtree, temp_dir)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001900
1901 program = 'posix_spawnp_test_program.exe'
1902 program_fullpath = os.path.join(temp_dir, program)
1903 os.symlink(sys.executable, program_fullpath)
1904
1905 try:
1906 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1907 except KeyError:
1908 path = temp_dir # PATH is not set
1909
1910 spawn_args = (program, '-I', '-S', '-c', 'pass')
1911 code = textwrap.dedent("""
1912 import os
Victor Stinner278c1e12020-03-31 20:08:12 +02001913 from test import support
1914
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001915 args = %a
1916 pid = os.posix_spawnp(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001917
1918 support.wait_process(pid, exitcode=0)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001919 """ % (spawn_args,))
1920
1921 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1922 # environment variable: posix_spawnp() uses the current environment
1923 # to locate the program, not its environment argument.
1924 args = ('-c', code)
1925 assert_python_ok(*args, PATH=path)
1926
1927
Ronald Oussoren41761932020-11-08 10:05:27 +01001928@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
1929class TestPosixWeaklinking(unittest.TestCase):
1930 # These test cases verify that weak linking support on macOS works
1931 # as expected. These cases only test new behaviour introduced by weak linking,
1932 # regular behaviour is tested by the normal test cases.
1933 #
1934 # See the section on Weak Linking in Mac/README.txt for more information.
1935 def setUp(self):
1936 import sysconfig
1937 import platform
1938
1939 config_vars = sysconfig.get_config_vars()
1940 self.available = { nm for nm in config_vars if nm.startswith("HAVE_") and config_vars[nm] }
1941 self.mac_ver = tuple(int(part) for part in platform.mac_ver()[0].split("."))
1942
1943 def _verify_available(self, name):
1944 if name not in self.available:
1945 raise unittest.SkipTest(f"{name} not weak-linked")
1946
1947 def test_pwritev(self):
1948 self._verify_available("HAVE_PWRITEV")
1949 if self.mac_ver >= (10, 16):
1950 self.assertTrue(hasattr(os, "pwritev"), "os.pwritev is not available")
1951 self.assertTrue(hasattr(os, "preadv"), "os.readv is not available")
1952
1953 else:
1954 self.assertFalse(hasattr(os, "pwritev"), "os.pwritev is available")
1955 self.assertFalse(hasattr(os, "preadv"), "os.readv is available")
1956
1957 def test_stat(self):
1958 self._verify_available("HAVE_FSTATAT")
1959 if self.mac_ver >= (10, 10):
1960 self.assertIn("HAVE_FSTATAT", posix._have_functions)
1961
1962 else:
1963 self.assertNotIn("HAVE_FSTATAT", posix._have_functions)
1964
1965 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1966 os.stat("file", dir_fd=0)
1967
1968 def test_access(self):
1969 self._verify_available("HAVE_FACCESSAT")
1970 if self.mac_ver >= (10, 10):
1971 self.assertIn("HAVE_FACCESSAT", posix._have_functions)
1972
1973 else:
1974 self.assertNotIn("HAVE_FACCESSAT", posix._have_functions)
1975
1976 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1977 os.access("file", os.R_OK, dir_fd=0)
1978
1979 with self.assertRaisesRegex(NotImplementedError, "follow_symlinks unavailable"):
1980 os.access("file", os.R_OK, follow_symlinks=False)
1981
1982 with self.assertRaisesRegex(NotImplementedError, "effective_ids unavailable"):
1983 os.access("file", os.R_OK, effective_ids=True)
1984
1985 def test_chmod(self):
1986 self._verify_available("HAVE_FCHMODAT")
1987 if self.mac_ver >= (10, 10):
1988 self.assertIn("HAVE_FCHMODAT", posix._have_functions)
1989
1990 else:
1991 self.assertNotIn("HAVE_FCHMODAT", posix._have_functions)
1992 self.assertIn("HAVE_LCHMOD", posix._have_functions)
1993
1994 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1995 os.chmod("file", 0o644, dir_fd=0)
1996
1997 def test_chown(self):
1998 self._verify_available("HAVE_FCHOWNAT")
1999 if self.mac_ver >= (10, 10):
2000 self.assertIn("HAVE_FCHOWNAT", posix._have_functions)
2001
2002 else:
2003 self.assertNotIn("HAVE_FCHOWNAT", posix._have_functions)
2004 self.assertIn("HAVE_LCHOWN", posix._have_functions)
2005
2006 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2007 os.chown("file", 0, 0, dir_fd=0)
2008
2009 def test_link(self):
2010 self._verify_available("HAVE_LINKAT")
2011 if self.mac_ver >= (10, 10):
2012 self.assertIn("HAVE_LINKAT", posix._have_functions)
2013
2014 else:
2015 self.assertNotIn("HAVE_LINKAT", posix._have_functions)
2016
2017 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2018 os.link("source", "target", src_dir_fd=0)
2019
2020 with self.assertRaisesRegex(NotImplementedError, "dst_dir_fd unavailable"):
2021 os.link("source", "target", dst_dir_fd=0)
2022
2023 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2024 os.link("source", "target", src_dir_fd=0, dst_dir_fd=0)
2025
2026 # issue 41355: !HAVE_LINKAT code path ignores the follow_symlinks flag
2027 with os_helper.temp_dir() as base_path:
2028 link_path = os.path.join(base_path, "link")
2029 target_path = os.path.join(base_path, "target")
2030 source_path = os.path.join(base_path, "source")
2031
2032 with open(source_path, "w") as fp:
2033 fp.write("data")
2034
2035 os.symlink("target", link_path)
2036
2037 # Calling os.link should fail in the link(2) call, and
2038 # should not reject *follow_symlinks* (to match the
2039 # behaviour you'd get when building on a platform without
2040 # linkat)
2041 with self.assertRaises(FileExistsError):
2042 os.link(source_path, link_path, follow_symlinks=True)
2043
2044 with self.assertRaises(FileExistsError):
2045 os.link(source_path, link_path, follow_symlinks=False)
2046
2047
2048 def test_listdir_scandir(self):
2049 self._verify_available("HAVE_FDOPENDIR")
2050 if self.mac_ver >= (10, 10):
2051 self.assertIn("HAVE_FDOPENDIR", posix._have_functions)
2052
2053 else:
2054 self.assertNotIn("HAVE_FDOPENDIR", posix._have_functions)
2055
2056 with self.assertRaisesRegex(TypeError, "listdir: path should be string, bytes, os.PathLike or None, not int"):
2057 os.listdir(0)
2058
2059 with self.assertRaisesRegex(TypeError, "scandir: path should be string, bytes, os.PathLike or None, not int"):
2060 os.scandir(0)
2061
2062 def test_mkdir(self):
2063 self._verify_available("HAVE_MKDIRAT")
2064 if self.mac_ver >= (10, 10):
2065 self.assertIn("HAVE_MKDIRAT", posix._have_functions)
2066
2067 else:
2068 self.assertNotIn("HAVE_MKDIRAT", posix._have_functions)
2069
2070 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2071 os.mkdir("dir", dir_fd=0)
2072
2073 def test_rename_replace(self):
2074 self._verify_available("HAVE_RENAMEAT")
2075 if self.mac_ver >= (10, 10):
2076 self.assertIn("HAVE_RENAMEAT", posix._have_functions)
2077
2078 else:
2079 self.assertNotIn("HAVE_RENAMEAT", posix._have_functions)
2080
2081 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2082 os.rename("a", "b", src_dir_fd=0)
2083
2084 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2085 os.rename("a", "b", dst_dir_fd=0)
2086
2087 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2088 os.replace("a", "b", src_dir_fd=0)
2089
2090 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2091 os.replace("a", "b", dst_dir_fd=0)
2092
2093 def test_unlink_rmdir(self):
2094 self._verify_available("HAVE_UNLINKAT")
2095 if self.mac_ver >= (10, 10):
2096 self.assertIn("HAVE_UNLINKAT", posix._have_functions)
2097
2098 else:
2099 self.assertNotIn("HAVE_UNLINKAT", posix._have_functions)
2100
2101 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2102 os.unlink("path", dir_fd=0)
2103
2104 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2105 os.rmdir("path", dir_fd=0)
2106
2107 def test_open(self):
2108 self._verify_available("HAVE_OPENAT")
2109 if self.mac_ver >= (10, 10):
2110 self.assertIn("HAVE_OPENAT", posix._have_functions)
2111
2112 else:
2113 self.assertNotIn("HAVE_OPENAT", posix._have_functions)
2114
2115 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2116 os.open("path", os.O_RDONLY, dir_fd=0)
2117
2118 def test_readlink(self):
2119 self._verify_available("HAVE_READLINKAT")
2120 if self.mac_ver >= (10, 10):
2121 self.assertIn("HAVE_READLINKAT", posix._have_functions)
2122
2123 else:
2124 self.assertNotIn("HAVE_READLINKAT", posix._have_functions)
2125
2126 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2127 os.readlink("path", dir_fd=0)
2128
2129 def test_symlink(self):
2130 self._verify_available("HAVE_SYMLINKAT")
2131 if self.mac_ver >= (10, 10):
2132 self.assertIn("HAVE_SYMLINKAT", posix._have_functions)
2133
2134 else:
2135 self.assertNotIn("HAVE_SYMLINKAT", posix._have_functions)
2136
2137 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2138 os.symlink("a", "b", dir_fd=0)
2139
2140 def test_utime(self):
2141 self._verify_available("HAVE_FUTIMENS")
2142 self._verify_available("HAVE_UTIMENSAT")
2143 if self.mac_ver >= (10, 13):
2144 self.assertIn("HAVE_FUTIMENS", posix._have_functions)
2145 self.assertIn("HAVE_UTIMENSAT", posix._have_functions)
2146
2147 else:
2148 self.assertNotIn("HAVE_FUTIMENS", posix._have_functions)
2149 self.assertNotIn("HAVE_UTIMENSAT", posix._have_functions)
2150
2151 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2152 os.utime("path", dir_fd=0)
2153
2154
Neal Norwitze241ce82003-02-17 18:17:05 +00002155def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01002156 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002157 support.run_unittest(
2158 PosixTester,
2159 PosixGroupsTester,
2160 TestPosixSpawn,
2161 TestPosixSpawnP,
Ronald Oussoren41761932020-11-08 10:05:27 +01002162 TestPosixWeaklinking
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002163 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01002164 finally:
2165 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00002166
2167if __name__ == '__main__':
2168 test_main()