blob: 18afbef082bffc3c3e4055d8ea4c8f778ffeae55 [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Hai Shibb0424b2020-08-04 00:47:42 +08004from test.support import import_helper
5from test.support import os_helper
6from test.support import warnings_helper
Antoine Pitrou346cbd32017-05-27 17:50:54 +02007from test.support.script_helper import assert_python_ok
R. David Murrayeb3615d2009-04-22 02:24:39 +00008
9# Skip these tests if there is no posix module.
Hai Shibb0424b2020-08-04 00:47:42 +080010posix = import_helper.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +000011
Antoine Pitroub7572f02009-12-02 20:46:48 +000012import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +000013import sys
Pablo Galindo254a4662018-09-07 16:44:24 +010014import signal
Neal Norwitze241ce82003-02-17 18:17:05 +000015import time
16import os
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020017import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000018import pwd
Benjamin Peterson052a02b2010-08-17 01:27:09 +000019import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070020import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000021import unittest
22import warnings
Pablo Galindo254a4662018-09-07 16:44:24 +010023import textwrap
R. David Murraya21e4ca2009-03-31 23:16:50 +000024
Ned Deilyba2eab22011-07-26 13:53:55 -070025_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
Hai Shibb0424b2020-08-04 00:47:42 +080026 os_helper.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000027
Serhiy Storchaka9d572732018-07-31 10:24:54 +030028requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
29 'test is only meaningful on 32-bit builds')
30
Benjamin Petersonc7042222018-09-12 15:12:24 -070031def _supports_sched():
32 if not hasattr(posix, 'sched_getscheduler'):
33 return False
34 try:
35 posix.sched_getscheduler(0)
36 except OSError as e:
37 if e.errno == errno.ENOSYS:
38 return False
39 return True
40
41requires_sched = unittest.skipUnless(_supports_sched(), 'requires POSIX scheduler API')
42
Victor Stinner278c1e12020-03-31 20:08:12 +020043
Neal Norwitze241ce82003-02-17 18:17:05 +000044class PosixTester(unittest.TestCase):
45
46 def setUp(self):
47 # create empty file
Hai Shibb0424b2020-08-04 00:47:42 +080048 fp = open(os_helper.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000049 fp.close()
Hai Shibb0424b2020-08-04 00:47:42 +080050 self.teardown_files = [ os_helper.TESTFN ]
51 self._warnings_manager = warnings_helper.check_warnings()
Brett Cannonc8d502e2010-03-20 21:53:28 +000052 self._warnings_manager.__enter__()
53 warnings.filterwarnings('ignore', '.* potential security risk .*',
54 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
56 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070057 for teardown_file in self.teardown_files:
Hai Shibb0424b2020-08-04 00:47:42 +080058 os_helper.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000059 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000060
61 def testNoArgFunctions(self):
62 # test posix functions which take no arguments and have
63 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000064 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000065 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000066 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020067 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000068 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000069
Neal Norwitze241ce82003-02-17 18:17:05 +000070 for name in NO_ARG_FUNCTIONS:
71 posix_func = getattr(posix, name, None)
72 if posix_func is not None:
73 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000074 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000075
Serhiy Storchaka43767632013-11-03 21:31:38 +020076 @unittest.skipUnless(hasattr(posix, 'getresuid'),
77 'test needs posix.getresuid()')
78 def test_getresuid(self):
79 user_ids = posix.getresuid()
80 self.assertEqual(len(user_ids), 3)
81 for val in user_ids:
82 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000083
Serhiy Storchaka43767632013-11-03 21:31:38 +020084 @unittest.skipUnless(hasattr(posix, 'getresgid'),
85 'test needs posix.getresgid()')
86 def test_getresgid(self):
87 group_ids = posix.getresgid()
88 self.assertEqual(len(group_ids), 3)
89 for val in group_ids:
90 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000091
Serhiy Storchaka43767632013-11-03 21:31:38 +020092 @unittest.skipUnless(hasattr(posix, 'setresuid'),
93 'test needs posix.setresuid()')
94 def test_setresuid(self):
95 current_user_ids = posix.getresuid()
96 self.assertIsNone(posix.setresuid(*current_user_ids))
97 # -1 means don't change that value.
98 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000099
Serhiy Storchaka43767632013-11-03 21:31:38 +0200100 @unittest.skipUnless(hasattr(posix, 'setresuid'),
101 'test needs posix.setresuid()')
102 def test_setresuid_exception(self):
103 # Don't do this test if someone is silly enough to run us as root.
104 current_user_ids = posix.getresuid()
105 if 0 not in current_user_ids:
106 new_user_ids = (current_user_ids[0]+1, -1, -1)
107 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000108
Serhiy Storchaka43767632013-11-03 21:31:38 +0200109 @unittest.skipUnless(hasattr(posix, 'setresgid'),
110 'test needs posix.setresgid()')
111 def test_setresgid(self):
112 current_group_ids = posix.getresgid()
113 self.assertIsNone(posix.setresgid(*current_group_ids))
114 # -1 means don't change that value.
115 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000116
Serhiy Storchaka43767632013-11-03 21:31:38 +0200117 @unittest.skipUnless(hasattr(posix, 'setresgid'),
118 'test needs posix.setresgid()')
119 def test_setresgid_exception(self):
120 # Don't do this test if someone is silly enough to run us as root.
121 current_group_ids = posix.getresgid()
122 if 0 not in current_group_ids:
123 new_group_ids = (current_group_ids[0]+1, -1, -1)
124 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000125
Antoine Pitroub7572f02009-12-02 20:46:48 +0000126 @unittest.skipUnless(hasattr(posix, 'initgroups'),
127 "test needs os.initgroups()")
128 def test_initgroups(self):
129 # It takes a string and an integer; check that it raises a TypeError
130 # for other argument lists.
131 self.assertRaises(TypeError, posix.initgroups)
132 self.assertRaises(TypeError, posix.initgroups, None)
133 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
134 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
135
136 # If a non-privileged user invokes it, it should fail with OSError
137 # EPERM.
138 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200139 try:
140 name = pwd.getpwuid(posix.getuid()).pw_name
141 except KeyError:
142 # the current UID may not have a pwd entry
143 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000144 try:
145 posix.initgroups(name, 13)
146 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000147 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000148 else:
149 self.fail("Expected OSError to be raised by initgroups")
150
Serhiy Storchaka43767632013-11-03 21:31:38 +0200151 @unittest.skipUnless(hasattr(posix, 'statvfs'),
152 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000153 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200154 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000155
Serhiy Storchaka43767632013-11-03 21:31:38 +0200156 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
157 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000158 def test_fstatvfs(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800159 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200160 try:
161 self.assertTrue(posix.fstatvfs(fp.fileno()))
162 self.assertTrue(posix.statvfs(fp.fileno()))
163 finally:
164 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000165
Serhiy Storchaka43767632013-11-03 21:31:38 +0200166 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
167 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000168 def test_ftruncate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800169 fp = open(os_helper.TESTFN, 'w+')
Serhiy Storchaka43767632013-11-03 21:31:38 +0200170 try:
171 # we need to have some data to truncate
172 fp.write('test')
173 fp.flush()
174 posix.ftruncate(fp.fileno(), 0)
175 finally:
176 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000177
Ross Lagerwall7807c352011-03-17 20:20:30 +0200178 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
179 def test_truncate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800180 with open(os_helper.TESTFN, 'w') as fp:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200181 fp.write('test')
182 fp.flush()
Hai Shibb0424b2020-08-04 00:47:42 +0800183 posix.truncate(os_helper.TESTFN, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200184
Larry Hastings9cf065c2012-06-22 16:30:09 -0700185 @unittest.skipUnless(getattr(os, 'execve', None) in os.supports_fd, "test needs execve() to support the fd parameter")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200186 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200187 def test_fexecve(self):
188 fp = os.open(sys.executable, os.O_RDONLY)
189 try:
190 pid = os.fork()
191 if pid == 0:
192 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700193 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200194 else:
Victor Stinner278c1e12020-03-31 20:08:12 +0200195 support.wait_process(pid, exitcode=0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200196 finally:
197 os.close(fp)
198
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000199
Ross Lagerwall7807c352011-03-17 20:20:30 +0200200 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
201 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
202 def test_waitid(self):
203 pid = os.fork()
204 if pid == 0:
205 os.chdir(os.path.split(sys.executable)[0])
206 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
207 else:
208 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
209 self.assertEqual(pid, res.si_pid)
210
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200211 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700212 def test_register_at_fork(self):
213 with self.assertRaises(TypeError, msg="Positional args not allowed"):
214 os.register_at_fork(lambda: None)
215 with self.assertRaises(TypeError, msg="Args must be callable"):
216 os.register_at_fork(before=2)
217 with self.assertRaises(TypeError, msg="Args must be callable"):
218 os.register_at_fork(after_in_child="three")
219 with self.assertRaises(TypeError, msg="Args must be callable"):
220 os.register_at_fork(after_in_parent=b"Five")
221 with self.assertRaises(TypeError, msg="Args must not be None"):
222 os.register_at_fork(before=None)
223 with self.assertRaises(TypeError, msg="Args must not be None"):
224 os.register_at_fork(after_in_child=None)
225 with self.assertRaises(TypeError, msg="Args must not be None"):
226 os.register_at_fork(after_in_parent=None)
227 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
228 # Ensure a combination of valid and invalid is an error.
229 os.register_at_fork(before=None, after_in_parent=lambda: 3)
230 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
231 # Ensure a combination of valid and invalid is an error.
232 os.register_at_fork(before=lambda: None, after_in_child='')
233 # We test actual registrations in their own process so as not to
234 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200235 code = """if 1:
236 import os
237
238 r, w = os.pipe()
239 fin_r, fin_w = os.pipe()
240
Gregory P. Smith163468a2017-05-29 10:03:41 -0700241 os.register_at_fork(before=lambda: os.write(w, b'A'))
242 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
243 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
244 os.register_at_fork(before=lambda: os.write(w, b'B'),
245 after_in_parent=lambda: os.write(w, b'D'),
246 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200247
248 pid = os.fork()
249 if pid == 0:
250 # At this point, after-forkers have already been executed
251 os.close(w)
252 # Wait for parent to tell us to exit
253 os.read(fin_r, 1)
254 os._exit(0)
255 else:
256 try:
257 os.close(w)
258 with open(r, "rb") as f:
259 data = f.read()
260 assert len(data) == 6, data
261 # Check before-fork callbacks
262 assert data[:2] == b'BA', data
263 # Check after-fork callbacks
264 assert sorted(data[2:]) == list(b'CDEF'), data
265 assert data.index(b'C') < data.index(b'D'), data
266 assert data.index(b'E') < data.index(b'F'), data
267 finally:
268 os.write(fin_w, b'!')
269 """
270 assert_python_ok('-c', code)
271
Ross Lagerwall7807c352011-03-17 20:20:30 +0200272 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
273 def test_lockf(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800274 fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200275 try:
276 os.write(fd, b'test')
277 os.lseek(fd, 0, os.SEEK_SET)
278 posix.lockf(fd, posix.F_LOCK, 4)
279 # section is locked
280 posix.lockf(fd, posix.F_ULOCK, 4)
281 finally:
282 os.close(fd)
283
284 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
285 def test_pread(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800286 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200287 try:
288 os.write(fd, b'test')
289 os.lseek(fd, 0, os.SEEK_SET)
290 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100291 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200292 self.assertEqual(b'te', posix.read(fd, 2))
293 finally:
294 os.close(fd)
295
Pablo Galindo4defba32018-01-27 16:16:37 +0000296 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
297 def test_preadv(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800298 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000299 try:
300 os.write(fd, b'test1tt2t3t5t6t6t8')
301 buf = [bytearray(i) for i in [5, 3, 2]]
302 self.assertEqual(posix.preadv(fd, buf, 3), 10)
303 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
304 finally:
305 os.close(fd)
306
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300307 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000308 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
309 def test_preadv_flags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800310 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000311 try:
312 os.write(fd, b'test1tt2t3t5t6t6t8')
313 buf = [bytearray(i) for i in [5, 3, 2]]
314 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
315 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
Benjamin Peterson44867bb2019-06-11 10:15:31 -0700316 except NotImplementedError:
317 self.skipTest("preadv2 not available")
Pablo Galindo46544f62019-04-13 17:06:03 +0100318 except OSError as inst:
319 # Is possible that the macro RWF_HIPRI was defined at compilation time
320 # but the option is not supported by the kernel or the runtime libc shared
321 # library.
322 if inst.errno in {errno.EINVAL, errno.ENOTSUP}:
323 raise unittest.SkipTest("RWF_HIPRI is not supported by the current system")
324 else:
325 raise
Pablo Galindo4defba32018-01-27 16:16:37 +0000326 finally:
327 os.close(fd)
328
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300329 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
330 @requires_32b
331 def test_preadv_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800332 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300333 try:
334 buf = [bytearray(2**16)] * 2**15
335 with self.assertRaises(OSError) as cm:
336 os.preadv(fd, buf, 0)
337 self.assertEqual(cm.exception.errno, errno.EINVAL)
338 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
339 finally:
340 os.close(fd)
341
Ross Lagerwall7807c352011-03-17 20:20:30 +0200342 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
343 def test_pwrite(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800344 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200345 try:
346 os.write(fd, b'test')
347 os.lseek(fd, 0, os.SEEK_SET)
348 posix.pwrite(fd, b'xx', 1)
349 self.assertEqual(b'txxt', posix.read(fd, 4))
350 finally:
351 os.close(fd)
352
Pablo Galindo4defba32018-01-27 16:16:37 +0000353 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
354 def test_pwritev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800355 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000356 try:
357 os.write(fd, b"xx")
358 os.lseek(fd, 0, os.SEEK_SET)
359 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
360 self.assertEqual(n, 10)
361
362 os.lseek(fd, 0, os.SEEK_SET)
363 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
364 finally:
365 os.close(fd)
366
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300367 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000368 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
369 def test_pwritev_flags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800370 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Pablo Galindo4defba32018-01-27 16:16:37 +0000371 try:
372 os.write(fd,b"xx")
373 os.lseek(fd, 0, os.SEEK_SET)
374 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
375 self.assertEqual(n, 10)
376
377 os.lseek(fd, 0, os.SEEK_SET)
378 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
379 finally:
380 os.close(fd)
381
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300382 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
383 @requires_32b
384 def test_pwritev_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800385 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300386 try:
387 with self.assertRaises(OSError) as cm:
388 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
389 self.assertEqual(cm.exception.errno, errno.EINVAL)
390 finally:
391 os.close(fd)
392
Ross Lagerwall7807c352011-03-17 20:20:30 +0200393 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
394 "test needs posix.posix_fallocate()")
395 def test_posix_fallocate(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800396 fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200397 try:
398 posix.posix_fallocate(fd, 0, 10)
399 except OSError as inst:
400 # issue10812, ZFS doesn't appear to support posix_fallocate,
401 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400402 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
403 # often used there.
404 if inst.errno == errno.EINVAL and sys.platform.startswith(
405 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
406 raise unittest.SkipTest("test may fail on ZFS filesystems")
407 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200408 raise
409 finally:
410 os.close(fd)
411
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500412 # issue31106 - posix_fallocate() does not set error in errno.
413 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
414 "test needs posix.posix_fallocate()")
415 def test_posix_fallocate_errno(self):
416 try:
417 posix.posix_fallocate(-42, 0, 10)
418 except OSError as inst:
419 if inst.errno != errno.EBADF:
420 raise
421
Ross Lagerwall7807c352011-03-17 20:20:30 +0200422 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
423 "test needs posix.posix_fadvise()")
424 def test_posix_fadvise(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800425 fd = os.open(os_helper.TESTFN, os.O_RDONLY)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200426 try:
427 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
428 finally:
429 os.close(fd)
430
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500431 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
432 "test needs posix.posix_fadvise()")
433 def test_posix_fadvise_errno(self):
434 try:
435 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
436 except OSError as inst:
437 if inst.errno != errno.EBADF:
438 raise
439
Larry Hastings9cf065c2012-06-22 16:30:09 -0700440 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
441 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200442 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800443 fd = os.open(os_helper.TESTFN, os.O_RDONLY)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200444 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700445 posix.utime(fd)
446 posix.utime(fd, None)
447 self.assertRaises(TypeError, posix.utime, fd, (None, None))
448 self.assertRaises(TypeError, posix.utime, fd, (now, None))
449 self.assertRaises(TypeError, posix.utime, fd, (None, now))
450 posix.utime(fd, (int(now), int(now)))
451 posix.utime(fd, (now, now))
452 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
453 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
454 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
455 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
456 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
457
Ross Lagerwall7807c352011-03-17 20:20:30 +0200458 finally:
459 os.close(fd)
460
Larry Hastings9cf065c2012-06-22 16:30:09 -0700461 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
462 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200463 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800464 posix.utime(os_helper.TESTFN, None, follow_symlinks=False)
465 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
466 (None, None), follow_symlinks=False)
467 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
468 (now, None), follow_symlinks=False)
469 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
470 (None, now), follow_symlinks=False)
471 posix.utime(os_helper.TESTFN, (int(now), int(now)),
472 follow_symlinks=False)
473 posix.utime(os_helper.TESTFN, (now, now), follow_symlinks=False)
474 posix.utime(os_helper.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200475
476 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
477 def test_writev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800478 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200479 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100480 n = os.writev(fd, (b'test1', b'tt2', b't3'))
481 self.assertEqual(n, 10)
482
Ross Lagerwall7807c352011-03-17 20:20:30 +0200483 os.lseek(fd, 0, os.SEEK_SET)
484 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100485
486 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100487 try:
488 size = posix.writev(fd, [])
489 except OSError:
490 # writev(fd, []) raises OSError(22, "Invalid argument")
491 # on OpenIndiana
492 pass
493 else:
494 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200495 finally:
496 os.close(fd)
497
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300498 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
499 @requires_32b
500 def test_writev_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800501 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300502 try:
503 with self.assertRaises(OSError) as cm:
504 os.writev(fd, [b"x" * 2**16] * 2**15)
505 self.assertEqual(cm.exception.errno, errno.EINVAL)
506 finally:
507 os.close(fd)
508
Ross Lagerwall7807c352011-03-17 20:20:30 +0200509 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
510 def test_readv(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800511 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200512 try:
513 os.write(fd, b'test1tt2t3')
514 os.lseek(fd, 0, os.SEEK_SET)
515 buf = [bytearray(i) for i in [5, 3, 2]]
516 self.assertEqual(posix.readv(fd, buf), 10)
517 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100518
519 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100520 try:
521 size = posix.readv(fd, [])
522 except OSError:
523 # readv(fd, []) raises OSError(22, "Invalid argument")
524 # on OpenIndiana
525 pass
526 else:
527 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200528 finally:
529 os.close(fd)
530
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300531 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
532 @requires_32b
533 def test_readv_overflow_32bits(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800534 fd = os.open(os_helper.TESTFN, os.O_RDWR | os.O_CREAT)
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300535 try:
536 buf = [bytearray(2**16)] * 2**15
537 with self.assertRaises(OSError) as cm:
538 os.readv(fd, buf)
539 self.assertEqual(cm.exception.errno, errno.EINVAL)
540 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
541 finally:
542 os.close(fd)
543
Serhiy Storchaka43767632013-11-03 21:31:38 +0200544 @unittest.skipUnless(hasattr(posix, 'dup'),
545 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000546 def test_dup(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800547 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200548 try:
549 fd = posix.dup(fp.fileno())
550 self.assertIsInstance(fd, int)
551 os.close(fd)
552 finally:
553 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000554
Serhiy Storchaka43767632013-11-03 21:31:38 +0200555 @unittest.skipUnless(hasattr(posix, 'confstr'),
556 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000557 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200558 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
559 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000560
Serhiy Storchaka43767632013-11-03 21:31:38 +0200561 @unittest.skipUnless(hasattr(posix, 'dup2'),
562 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000563 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800564 fp1 = open(os_helper.TESTFN)
565 fp2 = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200566 try:
567 posix.dup2(fp1.fileno(), fp2.fileno())
568 finally:
569 fp1.close()
570 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000571
Charles-François Natali1e045b12011-05-22 20:42:32 +0200572 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200573 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200574 def test_oscloexec(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800575 fd = os.open(os_helper.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200576 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200577 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200578
Serhiy Storchaka43767632013-11-03 21:31:38 +0200579 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
580 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000581 def test_osexlock(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800582 fd = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200583 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800584 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200585 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
586 os.close(fd)
587
588 if hasattr(posix, "O_SHLOCK"):
Hai Shibb0424b2020-08-04 00:47:42 +0800589 fd = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200590 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800591 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000592 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
593 os.close(fd)
594
Serhiy Storchaka43767632013-11-03 21:31:38 +0200595 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
596 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000597 def test_osshlock(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800598 fd1 = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200599 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800600 fd2 = os.open(os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200601 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
602 os.close(fd2)
603 os.close(fd1)
604
605 if hasattr(posix, "O_EXLOCK"):
Hai Shibb0424b2020-08-04 00:47:42 +0800606 fd = os.open(os_helper.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000607 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Hai Shibb0424b2020-08-04 00:47:42 +0800608 self.assertRaises(OSError, os.open, os_helper.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200609 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
610 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000611
Serhiy Storchaka43767632013-11-03 21:31:38 +0200612 @unittest.skipUnless(hasattr(posix, 'fstat'),
613 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000614 def test_fstat(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800615 fp = open(os_helper.TESTFN)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200616 try:
617 self.assertTrue(posix.fstat(fp.fileno()))
618 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200619
Serhiy Storchaka43767632013-11-03 21:31:38 +0200620 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700621 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200622 posix.stat, float(fp.fileno()))
623 finally:
624 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000625
626 def test_stat(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800627 self.assertTrue(posix.stat(os_helper.TESTFN))
628 self.assertTrue(posix.stat(os.fsencode(os_helper.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200629
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300630 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700631 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800632 posix.stat, bytearray(os.fsencode(os_helper.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200633 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700634 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200635 posix.stat, None)
636 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700637 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800638 posix.stat, list(os_helper.TESTFN))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200639 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700640 'should be string, bytes, os.PathLike or integer, not',
Hai Shibb0424b2020-08-04 00:47:42 +0800641 posix.stat, list(os.fsencode(os_helper.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000642
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000643 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
644 def test_mkfifo(self):
pxinwrb2d0c662020-12-01 16:20:50 +0800645 if sys.platform == "vxworks":
646 fifo_path = os.path.join("/fifos/", os_helper.TESTFN)
647 else:
648 fifo_path = os_helper.TESTFN
649 os_helper.unlink(fifo_path)
650 self.addCleanup(os_helper.unlink, fifo_path)
xdegaye92c2ca72017-11-12 17:31:07 +0100651 try:
pxinwrb2d0c662020-12-01 16:20:50 +0800652 posix.mkfifo(fifo_path, stat.S_IRUSR | stat.S_IWUSR)
xdegaye92c2ca72017-11-12 17:31:07 +0100653 except PermissionError as e:
654 self.skipTest('posix.mkfifo(): %s' % e)
pxinwrb2d0c662020-12-01 16:20:50 +0800655 self.assertTrue(stat.S_ISFIFO(posix.stat(fifo_path).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000656
657 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
658 "don't have mknod()/S_IFIFO")
659 def test_mknod(self):
660 # Test using mknod() to create a FIFO (the only use specified
661 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +0800662 os_helper.unlink(os_helper.TESTFN)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000663 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
664 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800665 posix.mknod(os_helper.TESTFN, mode, 0)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000666 except OSError as e:
667 # Some old systems don't allow unprivileged users to use
668 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100669 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000670 else:
Hai Shibb0424b2020-08-04 00:47:42 +0800671 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000672
Martin Panterbf19d162015-09-09 01:01:13 +0000673 # Keyword arguments are also supported
Hai Shibb0424b2020-08-04 00:47:42 +0800674 os_helper.unlink(os_helper.TESTFN)
Martin Panterbf19d162015-09-09 01:01:13 +0000675 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800676 posix.mknod(path=os_helper.TESTFN, mode=mode, device=0,
Martin Panterbf19d162015-09-09 01:01:13 +0000677 dir_fd=None)
678 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100679 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000680
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300681 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
682 def test_makedev(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800683 st = posix.stat(os_helper.TESTFN)
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300684 dev = st.st_dev
685 self.assertIsInstance(dev, int)
686 self.assertGreaterEqual(dev, 0)
687
688 major = posix.major(dev)
689 self.assertIsInstance(major, int)
690 self.assertGreaterEqual(major, 0)
691 self.assertEqual(posix.major(dev), major)
692 self.assertRaises(TypeError, posix.major, float(dev))
693 self.assertRaises(TypeError, posix.major)
694 self.assertRaises((ValueError, OverflowError), posix.major, -1)
695
696 minor = posix.minor(dev)
697 self.assertIsInstance(minor, int)
698 self.assertGreaterEqual(minor, 0)
699 self.assertEqual(posix.minor(dev), minor)
700 self.assertRaises(TypeError, posix.minor, float(dev))
701 self.assertRaises(TypeError, posix.minor)
702 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
703
704 self.assertEqual(posix.makedev(major, minor), dev)
705 self.assertRaises(TypeError, posix.makedev, float(major), minor)
706 self.assertRaises(TypeError, posix.makedev, major, float(minor))
707 self.assertRaises(TypeError, posix.makedev, major)
708 self.assertRaises(TypeError, posix.makedev)
709
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200710 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000711 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200712 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200713 if stat_func is not None:
714 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200715 self.assertEqual(stat.st_uid, uid)
716 self.assertEqual(stat.st_gid, gid)
717 uid = os.getuid()
718 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200719 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200720 chown_func(first_param, uid, gid)
721 check_stat(uid, gid)
722 chown_func(first_param, -1, gid)
723 check_stat(uid, gid)
724 chown_func(first_param, uid, -1)
725 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200726
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200727 if uid == 0:
728 # Try an amusingly large uid/gid to make sure we handle
729 # large unsigned values. (chown lets you use any
730 # uid/gid you like, even if they aren't defined.)
731 #
732 # This problem keeps coming up:
733 # http://bugs.python.org/issue1747858
734 # http://bugs.python.org/issue4591
735 # http://bugs.python.org/issue15301
736 # Hopefully the fix in 4591 fixes it for good!
737 #
738 # This part of the test only runs when run as root.
739 # Only scary people run their tests as root.
740
741 big_value = 2**31
742 chown_func(first_param, big_value, big_value)
743 check_stat(big_value, big_value)
744 chown_func(first_param, -1, -1)
745 check_stat(big_value, big_value)
746 chown_func(first_param, uid, gid)
747 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200748 elif platform.system() in ('HP-UX', 'SunOS'):
749 # HP-UX and Solaris can allow a non-root user to chown() to root
750 # (issue #5113)
751 raise unittest.SkipTest("Skipping because of non-standard chown() "
752 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000753 else:
754 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200755 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200756 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200757 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200758 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200759 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200760 self.assertRaises(OSError, chown_func, first_param, -1, 0)
761 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200762 # test illegal types
763 for t in str, float:
764 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
765 check_stat(uid, gid)
766 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
767 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000768
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000769 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
770 def test_chown(self):
771 # raise an OSError if the file does not exist
Hai Shibb0424b2020-08-04 00:47:42 +0800772 os.unlink(os_helper.TESTFN)
773 self.assertRaises(OSError, posix.chown, os_helper.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000774
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000775 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800776 os_helper.create_empty_file(os_helper.TESTFN)
777 self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000778
779 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
780 def test_fchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800781 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000782
783 # re-create the file
Hai Shibb0424b2020-08-04 00:47:42 +0800784 test_file = open(os_helper.TESTFN, 'w')
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000785 try:
786 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200787 self._test_all_chown_common(posix.fchown, fd,
788 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000789 finally:
790 test_file.close()
791
792 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
793 def test_lchown(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800794 os.unlink(os_helper.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000795 # create a symlink
Hai Shibb0424b2020-08-04 00:47:42 +0800796 os.symlink(_DUMMY_SYMLINK, os_helper.TESTFN)
797 self._test_all_chown_common(posix.lchown, os_helper.TESTFN,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200798 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000799
Serhiy Storchaka43767632013-11-03 21:31:38 +0200800 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000801 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200802 posix.chdir(os.curdir)
Hai Shibb0424b2020-08-04 00:47:42 +0800803 self.assertRaises(OSError, posix.chdir, os_helper.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000804
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000805 def test_listdir(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800806 self.assertIn(os_helper.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000807
808 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700809 # When listdir is called without argument,
810 # it's the same as listdir(os.curdir).
Hai Shibb0424b2020-08-04 00:47:42 +0800811 self.assertIn(os_helper.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000812
Larry Hastingsfdaea062012-06-25 04:42:23 -0700813 def test_listdir_bytes(self):
814 # When listdir is called with a bytes object,
815 # the returned strings are of type bytes.
Hai Shibb0424b2020-08-04 00:47:42 +0800816 self.assertIn(os.fsencode(os_helper.TESTFN), posix.listdir(b'.'))
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300817
818 def test_listdir_bytes_like(self):
819 for cls in bytearray, memoryview:
820 with self.assertWarns(DeprecationWarning):
821 names = posix.listdir(cls(b'.'))
Hai Shibb0424b2020-08-04 00:47:42 +0800822 self.assertIn(os.fsencode(os_helper.TESTFN), names)
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300823 for name in names:
824 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700825
826 @unittest.skipUnless(posix.listdir in os.supports_fd,
827 "test needs fd support for posix.listdir()")
828 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000829 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100830 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000831 self.assertEqual(
832 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700833 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000834 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100835 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100836 self.assertEqual(
837 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100839 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000840
Serhiy Storchaka43767632013-11-03 21:31:38 +0200841 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000842 def test_access(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800843 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000844
Serhiy Storchaka43767632013-11-03 21:31:38 +0200845 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000846 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200847 old_mask = posix.umask(0)
848 self.assertIsInstance(old_mask, int)
849 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000850
Serhiy Storchaka43767632013-11-03 21:31:38 +0200851 @unittest.skipUnless(hasattr(posix, 'strerror'),
852 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000853 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200854 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000855
Serhiy Storchaka43767632013-11-03 21:31:38 +0200856 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000857 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200858 reader, writer = posix.pipe()
859 os.close(reader)
860 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000861
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200862 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200863 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200864 def test_pipe2(self):
865 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
866 self.assertRaises(TypeError, os.pipe2, 0, 0)
867
Charles-François Natali368f34b2011-06-06 19:49:47 +0200868 # try calling with flags = 0, like os.pipe()
869 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200870 os.close(r)
871 os.close(w)
872
873 # test flags
874 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
875 self.addCleanup(os.close, r)
876 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200877 self.assertFalse(os.get_inheritable(r))
878 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200879 self.assertFalse(os.get_blocking(r))
880 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200881 # try reading from an empty pipe: this should fail, not block
882 self.assertRaises(OSError, os.read, r, 1)
883 # try a write big enough to fill-up the pipe: this should either
884 # fail or perform a partial write, not block
885 try:
886 os.write(w, b'x' * support.PIPE_MAX_SIZE)
887 except OSError:
888 pass
889
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200890 @support.cpython_only
891 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
892 @support.requires_linux_version(2, 6, 27)
893 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200894 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200895 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200896 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
897 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
898
Serhiy Storchaka43767632013-11-03 21:31:38 +0200899 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000900 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200901 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +0800902 posix.utime(os_helper.TESTFN, None)
903 self.assertRaises(TypeError, posix.utime,
904 os_helper.TESTFN, (None, None))
905 self.assertRaises(TypeError, posix.utime,
906 os_helper.TESTFN, (now, None))
907 self.assertRaises(TypeError, posix.utime,
908 os_helper.TESTFN, (None, now))
909 posix.utime(os_helper.TESTFN, (int(now), int(now)))
910 posix.utime(os_helper.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000911
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700913 st = os.stat(target_file)
914 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000915
916 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
917 flags = st.st_flags | stat.UF_IMMUTABLE
918 try:
919 chflags_func(target_file, flags, **kwargs)
920 except OSError as err:
921 if err.errno != errno.EOPNOTSUPP:
922 raise
923 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
924 self.skipTest(msg)
925
Ned Deily3eb67d52011-06-28 00:00:28 -0700926 try:
927 new_st = os.stat(target_file)
928 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
929 try:
930 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200931 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700932 self.assertEqual(e.errno, errno.EPERM)
933 finally:
934 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000935
Ned Deily3eb67d52011-06-28 00:00:28 -0700936 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
937 def test_chflags(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800938 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700939
940 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
941 def test_lchflags_regular_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800942 self._test_chflags_regular_file(posix.lchflags, os_helper.TESTFN)
943 self._test_chflags_regular_file(posix.chflags, os_helper.TESTFN,
944 follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700945
946 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
947 def test_lchflags_symlink(self):
Hai Shibb0424b2020-08-04 00:47:42 +0800948 testfn_st = os.stat(os_helper.TESTFN)
Ned Deily3eb67d52011-06-28 00:00:28 -0700949
950 self.assertTrue(hasattr(testfn_st, 'st_flags'))
951
Hai Shibb0424b2020-08-04 00:47:42 +0800952 os.symlink(os_helper.TESTFN, _DUMMY_SYMLINK)
Ned Deily3eb67d52011-06-28 00:00:28 -0700953 self.teardown_files.append(_DUMMY_SYMLINK)
954 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
955
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956 def chflags_nofollow(path, flags):
957 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700958
Larry Hastings9cf065c2012-06-22 16:30:09 -0700959 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000960 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
961 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
962 try:
963 fn(_DUMMY_SYMLINK, flags)
964 except OSError as err:
965 if err.errno != errno.EOPNOTSUPP:
966 raise
967 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
968 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 try:
Hai Shibb0424b2020-08-04 00:47:42 +0800970 new_testfn_st = os.stat(os_helper.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700971 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
972
973 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
974 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
975 new_dummy_symlink_st.st_flags)
976 finally:
977 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000978
Guido van Rossum98297ee2007-11-06 21:34:58 +0000979 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000980 if os.name == "nt":
981 item_type = str
982 else:
983 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000984 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000985 self.assertEqual(type(k), item_type)
986 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000987
Serhiy Storchaka77703942017-06-25 07:33:01 +0300988 def test_putenv(self):
989 with self.assertRaises(ValueError):
990 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
991 with self.assertRaises(ValueError):
992 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
993 with self.assertRaises(ValueError):
994 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
995 with self.assertRaises(ValueError):
996 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
997 with self.assertRaises(ValueError):
998 os.putenv('FRUIT=ORANGE', 'lemon')
999 with self.assertRaises(ValueError):
1000 os.putenv(b'FRUIT=ORANGE', b'lemon')
1001
Serhiy Storchaka43767632013-11-03 21:31:38 +02001002 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001003 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001004 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
1005 curdir = os.getcwd()
Hai Shibb0424b2020-08-04 00:47:42 +08001006 base_path = os.path.abspath(os_helper.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001007
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001008 try:
1009 os.mkdir(base_path)
1010 os.chdir(base_path)
1011 except:
1012 # Just returning nothing instead of the SkipTest exception, because
1013 # the test results in Error in that case. Is that ok?
1014 # raise unittest.SkipTest("cannot create directory for testing")
1015 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001017 def _create_and_do_getcwd(dirname, current_path_length = 0):
1018 try:
1019 os.mkdir(dirname)
1020 except:
1021 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001022
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001023 os.chdir(dirname)
1024 try:
1025 os.getcwd()
1026 if current_path_length < 1027:
1027 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1028 finally:
1029 os.chdir('..')
1030 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001031
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001032 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001033
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001034 finally:
1035 os.chdir(curdir)
Hai Shibb0424b2020-08-04 00:47:42 +08001036 os_helper.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001037
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001038 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1039 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1040 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1041 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001042 user = pwd.getpwuid(os.getuid())[0]
1043 group = pwd.getpwuid(os.getuid())[3]
1044 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001045
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001046
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001047 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001048 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001049 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001050 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001051 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001052
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001053 try:
1054 idg_groups = set(int(g) for g in groups.split())
1055 except ValueError:
1056 idg_groups = set()
1057 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001058 raise unittest.SkipTest("need working 'id -G'")
1059
Ned Deily028915e2013-02-02 15:08:52 -08001060 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1061 if sys.platform == 'darwin':
1062 import sysconfig
1063 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001064 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001065 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1066
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001067 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001068 # groups, ignoring order, duplicates, and the effective gid.
1069 # #10822/#26944 - It is implementation defined whether
1070 # posix.getgroups() includes the effective gid.
1071 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1072 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001073
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001074 # tests for the posix *at functions follow
1075
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1077 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001078 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1079 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001080 self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001081 finally:
1082 posix.close(f)
1083
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1085 def test_chmod_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001086 os.chmod(os_helper.TESTFN, stat.S_IRUSR)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001087
1088 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1089 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001090 posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001091
Hai Shibb0424b2020-08-04 00:47:42 +08001092 s = posix.stat(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001093 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1094 finally:
1095 posix.close(f)
1096
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1098 def test_chown_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001099 os_helper.unlink(os_helper.TESTFN)
1100 os_helper.create_empty_file(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001101
1102 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1103 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001104 posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001105 finally:
1106 posix.close(f)
1107
Larry Hastings9cf065c2012-06-22 16:30:09 -07001108 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1109 def test_stat_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001110 os_helper.unlink(os_helper.TESTFN)
1111 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001112 outfile.write("testline\n")
1113
1114 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1115 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001116 s1 = posix.stat(os_helper.TESTFN)
1117 s2 = posix.stat(os_helper.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001118 self.assertEqual(s1, s2)
Hai Shibb0424b2020-08-04 00:47:42 +08001119 s2 = posix.stat(os_helper.TESTFN, dir_fd=None)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001120 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001121 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001122 posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001123 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Hai Shibb0424b2020-08-04 00:47:42 +08001124 posix.stat, os_helper.TESTFN, dir_fd=float(f))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001125 self.assertRaises(OverflowError,
Hai Shibb0424b2020-08-04 00:47:42 +08001126 posix.stat, os_helper.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001127 finally:
1128 posix.close(f)
1129
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1131 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001132 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1133 try:
1134 now = time.time()
Hai Shibb0424b2020-08-04 00:47:42 +08001135 posix.utime(os_helper.TESTFN, None, dir_fd=f)
1136 posix.utime(os_helper.TESTFN, dir_fd=f)
1137 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1138 now, dir_fd=f)
1139 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1140 (None, None), dir_fd=f)
1141 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1142 (now, None), dir_fd=f)
1143 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1144 (None, now), dir_fd=f)
1145 self.assertRaises(TypeError, posix.utime, os_helper.TESTFN,
1146 (now, "x"), dir_fd=f)
1147 posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f)
1148 posix.utime(os_helper.TESTFN, (now, now), dir_fd=f)
1149 posix.utime(os_helper.TESTFN,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
Hai Shibb0424b2020-08-04 00:47:42 +08001151 posix.utime(os_helper.TESTFN, dir_fd=f,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001152 times=(int(now), int((now - int(now)) * 1e9)))
1153
Larry Hastings90867a52012-06-22 17:01:41 -07001154 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001156 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001157 posix.utime(os_helper.TESTFN, follow_symlinks=False,
1158 dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001159 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001160 # whoops! using both together not supported on this platform.
1161 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001162
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001163 finally:
1164 posix.close(f)
1165
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1167 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001168 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1169 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001170 posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link',
1171 src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001172 except PermissionError as e:
1173 self.skipTest('posix.link(): %s' % e)
1174 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001175 # should have same inodes
Hai Shibb0424b2020-08-04 00:47:42 +08001176 self.assertEqual(posix.stat(os_helper.TESTFN)[1],
1177 posix.stat(os_helper.TESTFN + 'link')[1])
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001178 finally:
1179 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001180 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001181
Larry Hastings9cf065c2012-06-22 16:30:09 -07001182 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1183 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001184 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1185 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001186 posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f)
1187 posix.stat(os_helper.TESTFN + 'dir') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001188 finally:
1189 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001190 os_helper.rmtree(os_helper.TESTFN + 'dir')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001191
Larry Hastings9cf065c2012-06-22 16:30:09 -07001192 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1193 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1194 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001195 # Test using mknodat() to create a FIFO (the only use specified
1196 # by POSIX).
Hai Shibb0424b2020-08-04 00:47:42 +08001197 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001198 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1199 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1200 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001201 posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001202 except OSError as e:
1203 # Some old systems don't allow unprivileged users to use
1204 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001205 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001206 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001207 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001208 finally:
1209 posix.close(f)
1210
Larry Hastings9cf065c2012-06-22 16:30:09 -07001211 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1212 def test_open_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001213 os_helper.unlink(os_helper.TESTFN)
1214 with open(os_helper.TESTFN, 'w') as outfile:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001215 outfile.write("testline\n")
1216 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001217 b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001218 try:
1219 res = posix.read(b, 9).decode(encoding="utf-8")
1220 self.assertEqual("testline\n", res)
1221 finally:
1222 posix.close(a)
1223 posix.close(b)
1224
Larry Hastings9cf065c2012-06-22 16:30:09 -07001225 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1226 def test_readlink_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001227 os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001228 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1229 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001230 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1231 posix.readlink(os_helper.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001232 finally:
Hai Shibb0424b2020-08-04 00:47:42 +08001233 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001234 posix.close(f)
1235
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1237 def test_rename_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001238 os_helper.unlink(os_helper.TESTFN)
1239 os_helper.create_empty_file(os_helper.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001240 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1241 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001242 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001243 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001244 posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001245 raise
1246 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001247 posix.stat(os_helper.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001248 finally:
1249 posix.close(f)
1250
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001251 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1252 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1253 def test_cld_xxxx_constants(self):
1254 os.CLD_EXITED
1255 os.CLD_KILLED
1256 os.CLD_DUMPED
1257 os.CLD_TRAPPED
1258 os.CLD_STOPPED
1259 os.CLD_CONTINUED
1260
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1262 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001263 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1264 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001265 posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link',
1266 dir_fd=f)
1267 self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'),
1268 os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001269 finally:
1270 posix.close(f)
Hai Shibb0424b2020-08-04 00:47:42 +08001271 os_helper.unlink(os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001272
Larry Hastings9cf065c2012-06-22 16:30:09 -07001273 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1274 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001275 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Hai Shibb0424b2020-08-04 00:47:42 +08001276 os_helper.create_empty_file(os_helper.TESTFN + 'del')
1277 posix.stat(os_helper.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001278 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001279 posix.unlink(os_helper.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001280 except:
Hai Shibb0424b2020-08-04 00:47:42 +08001281 os_helper.unlink(os_helper.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001282 raise
1283 else:
Hai Shibb0424b2020-08-04 00:47:42 +08001284 self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001285 finally:
1286 posix.close(f)
1287
Larry Hastings9cf065c2012-06-22 16:30:09 -07001288 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1289 def test_mkfifo_dir_fd(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001290 os_helper.unlink(os_helper.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001291 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1292 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001293 try:
Hai Shibb0424b2020-08-04 00:47:42 +08001294 posix.mkfifo(os_helper.TESTFN,
xdegaye92c2ca72017-11-12 17:31:07 +01001295 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1296 except PermissionError as e:
1297 self.skipTest('posix.mkfifo(): %s' % e)
Hai Shibb0424b2020-08-04 00:47:42 +08001298 self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001299 finally:
1300 posix.close(f)
1301
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001302 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1303 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001304 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001305 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001306
1307 @requires_sched_h
1308 def test_sched_yield(self):
1309 # This has no error conditions (at least on Linux).
1310 posix.sched_yield()
1311
1312 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001313 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1314 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001315 def test_sched_priority(self):
1316 # Round-robin usually has interesting priorities.
1317 pol = posix.SCHED_RR
1318 lo = posix.sched_get_priority_min(pol)
1319 hi = posix.sched_get_priority_max(pol)
1320 self.assertIsInstance(lo, int)
1321 self.assertIsInstance(hi, int)
1322 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001323 # OSX evidently just returns 15 without checking the argument.
1324 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001325 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1326 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001327
Benjamin Petersonc7042222018-09-12 15:12:24 -07001328 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001329 def test_get_and_set_scheduler_and_param(self):
1330 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1331 if name.startswith("SCHED_")]
1332 mine = posix.sched_getscheduler(0)
1333 self.assertIn(mine, possible_schedulers)
1334 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001335 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001336 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001337 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001338 raise
1339 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001340 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001341 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1342 self.assertRaises(OSError, posix.sched_getparam, -1)
1343 param = posix.sched_getparam(0)
1344 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001345
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001346 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1347 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1348 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1349 if not sys.platform.startswith(('freebsd', 'netbsd')):
1350 try:
1351 posix.sched_setscheduler(0, mine, param)
1352 posix.sched_setparam(0, param)
1353 except OSError as e:
1354 if e.errno != errno.EPERM:
1355 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001356 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1357
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001358 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1359 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1360 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1361 param = posix.sched_param(None)
1362 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1363 large = 214748364700
1364 param = posix.sched_param(large)
1365 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1366 param = posix.sched_param(sched_priority=-large)
1367 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1368
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001369 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001370 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001371 try:
1372 interval = posix.sched_rr_get_interval(0)
1373 except OSError as e:
1374 # This likely means that sched_rr_get_interval is only valid for
1375 # processes with the SCHED_RR scheduler in effect.
1376 if e.errno != errno.EINVAL:
1377 raise
1378 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001379 self.assertIsInstance(interval, float)
1380 # Reasonable constraints, I think.
1381 self.assertGreaterEqual(interval, 0.)
1382 self.assertLess(interval, 1.)
1383
Benjamin Peterson2740af82011-08-02 17:41:34 -05001384 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001385 def test_sched_getaffinity(self):
1386 mask = posix.sched_getaffinity(0)
1387 self.assertIsInstance(mask, set)
1388 self.assertGreaterEqual(len(mask), 1)
1389 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1390 for cpu in mask:
1391 self.assertIsInstance(cpu, int)
1392 self.assertGreaterEqual(cpu, 0)
1393 self.assertLess(cpu, 1 << 32)
1394
1395 @requires_sched_affinity
1396 def test_sched_setaffinity(self):
1397 mask = posix.sched_getaffinity(0)
1398 if len(mask) > 1:
1399 # Empty masks are forbidden
1400 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001401 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001402 self.assertEqual(posix.sched_getaffinity(0), mask)
1403 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1404 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001405 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001406 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001407 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1408
Victor Stinner8b905bd2011-10-25 13:34:04 +02001409 def test_rtld_constants(self):
1410 # check presence of major RTLD_* constants
1411 posix.RTLD_LAZY
1412 posix.RTLD_NOW
1413 posix.RTLD_GLOBAL
1414 posix.RTLD_LOCAL
1415
Jesus Cea60c13dd2012-06-23 02:58:14 +02001416 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1417 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001418 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001419 # Even if the filesystem doesn't report holes,
1420 # if the OS supports it the SEEK_* constants
1421 # will be defined and will have a consistent
1422 # behaviour:
1423 # os.SEEK_DATA = current position
1424 # os.SEEK_HOLE = end of file position
Hai Shibb0424b2020-08-04 00:47:42 +08001425 with open(os_helper.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001426 fp.write(b"hello")
1427 fp.flush()
1428 size = fp.tell()
1429 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001430 try :
1431 for i in range(size):
1432 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1433 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1434 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1435 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1436 except OSError :
1437 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1438 # but it is not true.
1439 # For instance:
1440 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1441 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001442
Larry Hastingsb0827312014-02-09 22:05:19 -08001443 def test_path_error2(self):
1444 """
1445 Test functions that call path_error2(), providing two filenames in their exceptions.
1446 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001447 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001448 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001449 if function is None:
1450 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001451
Hai Shibb0424b2020-08-04 00:47:42 +08001452 for dst in ("noodly2", os_helper.TESTFN):
Victor Stinnerbed04a72014-10-05 17:37:59 +02001453 try:
1454 function('doesnotexistfilename', dst)
1455 except OSError as e:
1456 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1457 break
1458 else:
1459 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001460
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001461 def test_path_with_null_character(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001462 fn = os_helper.TESTFN
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001463 fn_with_NUL = fn + '\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001464 self.addCleanup(os_helper.unlink, fn)
1465 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001466 fd = None
1467 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001468 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001469 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1470 finally:
1471 if fd is not None:
1472 os.close(fd)
1473 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001474 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001475 self.assertFalse(os.path.exists(fn))
1476 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001477 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001478
1479 def test_path_with_null_byte(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001480 fn = os.fsencode(os_helper.TESTFN)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001481 fn_with_NUL = fn + b'\0'
Hai Shibb0424b2020-08-04 00:47:42 +08001482 self.addCleanup(os_helper.unlink, fn)
1483 os_helper.unlink(fn)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001484 fd = None
1485 try:
1486 with self.assertRaises(ValueError):
1487 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1488 finally:
1489 if fd is not None:
1490 os.close(fd)
1491 self.assertFalse(os.path.exists(fn))
1492 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1493 self.assertFalse(os.path.exists(fn))
1494 open(fn, 'wb').close()
1495 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1496
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001497 @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable")
1498 def test_pidfd_open(self):
1499 with self.assertRaises(OSError) as cm:
1500 os.pidfd_open(-1)
1501 if cm.exception.errno == errno.ENOSYS:
1502 self.skipTest("system does not support pidfd_open")
Victor Stinner3ab479a2019-11-21 12:54:54 +01001503 if isinstance(cm.exception, PermissionError):
1504 self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}")
Benjamin Peterson6c4c45e2019-11-05 19:21:29 -08001505 self.assertEqual(cm.exception.errno, errno.EINVAL)
1506 os.close(os.pidfd_open(os.getpid(), 0))
1507
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001508class PosixGroupsTester(unittest.TestCase):
1509
1510 def setUp(self):
1511 if posix.getuid() != 0:
1512 raise unittest.SkipTest("not enough privileges")
1513 if not hasattr(posix, 'getgroups'):
1514 raise unittest.SkipTest("need posix.getgroups")
1515 if sys.platform == 'darwin':
1516 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1517 self.saved_groups = posix.getgroups()
1518
1519 def tearDown(self):
1520 if hasattr(posix, 'setgroups'):
1521 posix.setgroups(self.saved_groups)
1522 elif hasattr(posix, 'initgroups'):
1523 name = pwd.getpwuid(posix.getuid()).pw_name
1524 posix.initgroups(name, self.saved_groups[0])
1525
1526 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1527 "test needs posix.initgroups()")
1528 def test_initgroups(self):
1529 # find missing group
1530
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001531 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001532 name = pwd.getpwuid(posix.getuid()).pw_name
1533 posix.initgroups(name, g)
1534 self.assertIn(g, posix.getgroups())
1535
1536 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1537 "test needs posix.setgroups()")
1538 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001539 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001540 posix.setgroups(groups)
1541 self.assertListEqual(groups, posix.getgroups())
1542
Serhiy Storchakaef347532018-05-01 16:45:04 +03001543
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001544class _PosixSpawnMixin:
1545 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001546 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001547 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001548
1549 def python_args(self, *args):
1550 # Disable site module to avoid side effects. For example,
1551 # on Fedora 28, if the HOME environment variable is not set,
1552 # site._getuserbase() calls pwd.getpwuid() which opens
1553 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1554 # test_close_file() to fail.
1555 return (sys.executable, '-I', '-S', *args)
1556
Serhiy Storchakaef347532018-05-01 16:45:04 +03001557 def test_returns_pid(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001558 pidfile = os_helper.TESTFN
1559 self.addCleanup(os_helper.unlink, pidfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001560 script = f"""if 1:
1561 import os
1562 with open({pidfile!r}, "w") as pidfile:
1563 pidfile.write(str(os.getpid()))
1564 """
Victor Stinner03824062018-08-30 01:21:11 +02001565 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001566 pid = self.spawn_func(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001567 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001568 with open(pidfile) as f:
1569 self.assertEqual(f.read(), str(pid))
1570
1571 def test_no_such_executable(self):
1572 no_such_executable = 'no_such_executable'
1573 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001574 pid = self.spawn_func(no_such_executable,
1575 [no_such_executable],
1576 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001577 # bpo-35794: PermissionError can be raised if there are
1578 # directories in the $PATH that are not accessible.
1579 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001580 self.assertEqual(exc.filename, no_such_executable)
1581 else:
1582 pid2, status = os.waitpid(pid, 0)
1583 self.assertEqual(pid2, pid)
1584 self.assertNotEqual(status, 0)
1585
1586 def test_specify_environment(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001587 envfile = os_helper.TESTFN
1588 self.addCleanup(os_helper.unlink, envfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001589 script = f"""if 1:
1590 import os
1591 with open({envfile!r}, "w") as envfile:
1592 envfile.write(os.environ['foo'])
1593 """
Victor Stinner03824062018-08-30 01:21:11 +02001594 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001595 pid = self.spawn_func(args[0], args,
1596 {**os.environ, 'foo': 'bar'})
Victor Stinner278c1e12020-03-31 20:08:12 +02001597 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001598 with open(envfile) as f:
1599 self.assertEqual(f.read(), 'bar')
1600
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001601 def test_none_file_actions(self):
1602 pid = self.spawn_func(
1603 self.NOOP_PROGRAM[0],
1604 self.NOOP_PROGRAM,
1605 os.environ,
1606 file_actions=None
1607 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001608 support.wait_process(pid, exitcode=0)
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001609
Serhiy Storchakaef347532018-05-01 16:45:04 +03001610 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001611 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001612 self.NOOP_PROGRAM[0],
1613 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001614 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001615 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001616 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001617 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001618
Pablo Galindo254a4662018-09-07 16:44:24 +01001619 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001620 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001621 sys.executable,
1622 [sys.executable, '-c', 'pass'],
1623 os.environ,
1624 resetids=False
1625 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001626 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001627
1628 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001629 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001630 sys.executable,
1631 [sys.executable, '-c', 'pass'],
1632 os.environ,
1633 resetids=True
1634 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001635 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001636
1637 def test_resetids_wrong_type(self):
1638 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001639 self.spawn_func(sys.executable,
1640 [sys.executable, "-c", "pass"],
1641 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001642
1643 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001644 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001645 sys.executable,
1646 [sys.executable, '-c', 'pass'],
1647 os.environ,
1648 setpgroup=os.getpgrp()
1649 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001650 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001651
1652 def test_setpgroup_wrong_type(self):
1653 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001654 self.spawn_func(sys.executable,
1655 [sys.executable, "-c", "pass"],
1656 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001657
1658 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1659 'need signal.pthread_sigmask()')
1660 def test_setsigmask(self):
1661 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001662 import signal
1663 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001664
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001665 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001666 sys.executable,
1667 [sys.executable, '-c', code],
1668 os.environ,
1669 setsigmask=[signal.SIGUSR1]
1670 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001671 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001672
1673 def test_setsigmask_wrong_type(self):
1674 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001675 self.spawn_func(sys.executable,
1676 [sys.executable, "-c", "pass"],
1677 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001678 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001679 self.spawn_func(sys.executable,
1680 [sys.executable, "-c", "pass"],
1681 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001682 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001683 self.spawn_func(sys.executable,
1684 [sys.executable, "-c", "pass"],
1685 os.environ, setsigmask=[signal.NSIG,
1686 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001687
Victor Stinner58840432019-06-14 19:31:43 +02001688 def test_setsid(self):
1689 rfd, wfd = os.pipe()
1690 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001691 try:
Victor Stinner58840432019-06-14 19:31:43 +02001692 os.set_inheritable(wfd, True)
1693
1694 code = textwrap.dedent(f"""
1695 import os
1696 fd = {wfd}
1697 sid = os.getsid(0)
1698 os.write(fd, str(sid).encode())
1699 """)
1700
1701 try:
1702 pid = self.spawn_func(sys.executable,
1703 [sys.executable, "-c", code],
1704 os.environ, setsid=True)
1705 except NotImplementedError as exc:
1706 self.skipTest(f"setsid is not supported: {exc!r}")
1707 except PermissionError as exc:
1708 self.skipTest(f"setsid failed with: {exc!r}")
1709 finally:
1710 os.close(wfd)
1711
Victor Stinner278c1e12020-03-31 20:08:12 +02001712 support.wait_process(pid, exitcode=0)
1713
Victor Stinner58840432019-06-14 19:31:43 +02001714 output = os.read(rfd, 100)
1715 child_sid = int(output)
1716 parent_sid = os.getsid(os.getpid())
1717 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001718
Pablo Galindo254a4662018-09-07 16:44:24 +01001719 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1720 'need signal.pthread_sigmask()')
1721 def test_setsigdef(self):
1722 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1723 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001724 import signal
1725 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001726 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001727 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001728 sys.executable,
1729 [sys.executable, '-c', code],
1730 os.environ,
1731 setsigdef=[signal.SIGUSR1]
1732 )
1733 finally:
1734 signal.signal(signal.SIGUSR1, original_handler)
1735
Victor Stinner278c1e12020-03-31 20:08:12 +02001736 support.wait_process(pid, exitcode=-signal.SIGUSR1)
Pablo Galindo254a4662018-09-07 16:44:24 +01001737
1738 def test_setsigdef_wrong_type(self):
1739 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001740 self.spawn_func(sys.executable,
1741 [sys.executable, "-c", "pass"],
1742 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001743 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001744 self.spawn_func(sys.executable,
1745 [sys.executable, "-c", "pass"],
1746 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001747 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001748 self.spawn_func(sys.executable,
1749 [sys.executable, "-c", "pass"],
1750 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001751
Benjamin Petersonc7042222018-09-12 15:12:24 -07001752 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001753 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1754 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001755 def test_setscheduler_only_param(self):
1756 policy = os.sched_getscheduler(0)
1757 priority = os.sched_get_priority_min(policy)
1758 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001759 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001760 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001761 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001762 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001763 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001764 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001765 sys.executable,
1766 [sys.executable, '-c', code],
1767 os.environ,
1768 scheduler=(None, os.sched_param(priority))
1769 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001770 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001771
Benjamin Petersonc7042222018-09-12 15:12:24 -07001772 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001773 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1774 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001775 def test_setscheduler_with_policy(self):
1776 policy = os.sched_getscheduler(0)
1777 priority = os.sched_get_priority_min(policy)
1778 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001779 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001780 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001781 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001782 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001783 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001784 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001785 sys.executable,
1786 [sys.executable, '-c', code],
1787 os.environ,
1788 scheduler=(policy, os.sched_param(priority))
1789 )
Victor Stinner278c1e12020-03-31 20:08:12 +02001790 support.wait_process(pid, exitcode=0)
Pablo Galindo254a4662018-09-07 16:44:24 +01001791
Serhiy Storchakaef347532018-05-01 16:45:04 +03001792 def test_multiple_file_actions(self):
1793 file_actions = [
1794 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1795 (os.POSIX_SPAWN_CLOSE, 0),
1796 (os.POSIX_SPAWN_DUP2, 1, 4),
1797 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001798 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1799 self.NOOP_PROGRAM,
1800 os.environ,
1801 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001802 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001803
1804 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001805 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001806 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001807 self.spawn_func(args[0], args, os.environ,
1808 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001809 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001810 self.spawn_func(args[0], args, os.environ,
1811 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001812 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001813 self.spawn_func(args[0], args, os.environ,
1814 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001815 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001816 self.spawn_func(args[0], args, os.environ,
1817 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001818 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001819 self.spawn_func(args[0], args, os.environ,
1820 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001821 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001822 self.spawn_func(args[0], args, os.environ,
1823 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001824 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001825 self.spawn_func(args[0], args, os.environ,
1826 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001827 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001828 self.spawn_func(args[0], args, os.environ,
1829 file_actions=[(os.POSIX_SPAWN_OPEN,
1830 3, __file__ + '\0',
1831 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001832
1833 def test_open_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001834 outfile = os_helper.TESTFN
1835 self.addCleanup(os_helper.unlink, outfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001836 script = """if 1:
1837 import sys
1838 sys.stdout.write("hello")
1839 """
1840 file_actions = [
1841 (os.POSIX_SPAWN_OPEN, 1, outfile,
1842 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1843 stat.S_IRUSR | stat.S_IWUSR),
1844 ]
Victor Stinner03824062018-08-30 01:21:11 +02001845 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001846 pid = self.spawn_func(args[0], args, os.environ,
1847 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001848
1849 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001850 with open(outfile) as f:
1851 self.assertEqual(f.read(), 'hello')
1852
1853 def test_close_file(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001854 closefile = os_helper.TESTFN
1855 self.addCleanup(os_helper.unlink, closefile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001856 script = f"""if 1:
1857 import os
1858 try:
1859 os.fstat(0)
1860 except OSError as e:
1861 with open({closefile!r}, 'w') as closefile:
1862 closefile.write('is closed %d' % e.errno)
1863 """
Victor Stinner03824062018-08-30 01:21:11 +02001864 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001865 pid = self.spawn_func(args[0], args, os.environ,
1866 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Victor Stinner278c1e12020-03-31 20:08:12 +02001867
1868 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001869 with open(closefile) as f:
1870 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1871
1872 def test_dup2(self):
Hai Shibb0424b2020-08-04 00:47:42 +08001873 dupfile = os_helper.TESTFN
1874 self.addCleanup(os_helper.unlink, dupfile)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001875 script = """if 1:
1876 import sys
1877 sys.stdout.write("hello")
1878 """
1879 with open(dupfile, "wb") as childfile:
1880 file_actions = [
1881 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1882 ]
Victor Stinner03824062018-08-30 01:21:11 +02001883 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001884 pid = self.spawn_func(args[0], args, os.environ,
1885 file_actions=file_actions)
Victor Stinner278c1e12020-03-31 20:08:12 +02001886 support.wait_process(pid, exitcode=0)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001887 with open(dupfile) as f:
1888 self.assertEqual(f.read(), 'hello')
1889
1890
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001891@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1892class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1893 spawn_func = getattr(posix, 'posix_spawn', None)
1894
1895
1896@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1897class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1898 spawn_func = getattr(posix, 'posix_spawnp', None)
1899
Hai Shibb0424b2020-08-04 00:47:42 +08001900 @os_helper.skip_unless_symlink
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001901 def test_posix_spawnp(self):
1902 # Use a symlink to create a program in its own temporary directory
1903 temp_dir = tempfile.mkdtemp()
Hai Shibb0424b2020-08-04 00:47:42 +08001904 self.addCleanup(os_helper.rmtree, temp_dir)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001905
1906 program = 'posix_spawnp_test_program.exe'
1907 program_fullpath = os.path.join(temp_dir, program)
1908 os.symlink(sys.executable, program_fullpath)
1909
1910 try:
1911 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1912 except KeyError:
1913 path = temp_dir # PATH is not set
1914
1915 spawn_args = (program, '-I', '-S', '-c', 'pass')
1916 code = textwrap.dedent("""
1917 import os
Victor Stinner278c1e12020-03-31 20:08:12 +02001918 from test import support
1919
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001920 args = %a
1921 pid = os.posix_spawnp(args[0], args, os.environ)
Victor Stinner278c1e12020-03-31 20:08:12 +02001922
1923 support.wait_process(pid, exitcode=0)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001924 """ % (spawn_args,))
1925
1926 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1927 # environment variable: posix_spawnp() uses the current environment
1928 # to locate the program, not its environment argument.
1929 args = ('-c', code)
1930 assert_python_ok(*args, PATH=path)
1931
1932
Ronald Oussoren41761932020-11-08 10:05:27 +01001933@unittest.skipUnless(sys.platform == "darwin", "test weak linking on macOS")
1934class TestPosixWeaklinking(unittest.TestCase):
1935 # These test cases verify that weak linking support on macOS works
1936 # as expected. These cases only test new behaviour introduced by weak linking,
pxinwrb2d0c662020-12-01 16:20:50 +08001937 # regular behaviour is tested by the normal test cases.
Ronald Oussoren41761932020-11-08 10:05:27 +01001938 #
1939 # See the section on Weak Linking in Mac/README.txt for more information.
1940 def setUp(self):
1941 import sysconfig
1942 import platform
1943
1944 config_vars = sysconfig.get_config_vars()
1945 self.available = { nm for nm in config_vars if nm.startswith("HAVE_") and config_vars[nm] }
1946 self.mac_ver = tuple(int(part) for part in platform.mac_ver()[0].split("."))
1947
1948 def _verify_available(self, name):
1949 if name not in self.available:
1950 raise unittest.SkipTest(f"{name} not weak-linked")
1951
1952 def test_pwritev(self):
1953 self._verify_available("HAVE_PWRITEV")
1954 if self.mac_ver >= (10, 16):
1955 self.assertTrue(hasattr(os, "pwritev"), "os.pwritev is not available")
1956 self.assertTrue(hasattr(os, "preadv"), "os.readv is not available")
1957
1958 else:
1959 self.assertFalse(hasattr(os, "pwritev"), "os.pwritev is available")
1960 self.assertFalse(hasattr(os, "preadv"), "os.readv is available")
1961
1962 def test_stat(self):
1963 self._verify_available("HAVE_FSTATAT")
1964 if self.mac_ver >= (10, 10):
1965 self.assertIn("HAVE_FSTATAT", posix._have_functions)
1966
1967 else:
1968 self.assertNotIn("HAVE_FSTATAT", posix._have_functions)
1969
1970 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1971 os.stat("file", dir_fd=0)
1972
1973 def test_access(self):
1974 self._verify_available("HAVE_FACCESSAT")
1975 if self.mac_ver >= (10, 10):
1976 self.assertIn("HAVE_FACCESSAT", posix._have_functions)
1977
1978 else:
1979 self.assertNotIn("HAVE_FACCESSAT", posix._have_functions)
1980
1981 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
1982 os.access("file", os.R_OK, dir_fd=0)
1983
1984 with self.assertRaisesRegex(NotImplementedError, "follow_symlinks unavailable"):
1985 os.access("file", os.R_OK, follow_symlinks=False)
1986
1987 with self.assertRaisesRegex(NotImplementedError, "effective_ids unavailable"):
1988 os.access("file", os.R_OK, effective_ids=True)
1989
1990 def test_chmod(self):
1991 self._verify_available("HAVE_FCHMODAT")
1992 if self.mac_ver >= (10, 10):
1993 self.assertIn("HAVE_FCHMODAT", posix._have_functions)
1994
1995 else:
1996 self.assertNotIn("HAVE_FCHMODAT", posix._have_functions)
1997 self.assertIn("HAVE_LCHMOD", posix._have_functions)
1998
1999 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2000 os.chmod("file", 0o644, dir_fd=0)
2001
2002 def test_chown(self):
2003 self._verify_available("HAVE_FCHOWNAT")
2004 if self.mac_ver >= (10, 10):
2005 self.assertIn("HAVE_FCHOWNAT", posix._have_functions)
2006
2007 else:
2008 self.assertNotIn("HAVE_FCHOWNAT", posix._have_functions)
2009 self.assertIn("HAVE_LCHOWN", posix._have_functions)
2010
2011 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2012 os.chown("file", 0, 0, dir_fd=0)
2013
2014 def test_link(self):
2015 self._verify_available("HAVE_LINKAT")
2016 if self.mac_ver >= (10, 10):
2017 self.assertIn("HAVE_LINKAT", posix._have_functions)
2018
2019 else:
2020 self.assertNotIn("HAVE_LINKAT", posix._have_functions)
2021
2022 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2023 os.link("source", "target", src_dir_fd=0)
2024
2025 with self.assertRaisesRegex(NotImplementedError, "dst_dir_fd unavailable"):
2026 os.link("source", "target", dst_dir_fd=0)
2027
2028 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd unavailable"):
2029 os.link("source", "target", src_dir_fd=0, dst_dir_fd=0)
2030
2031 # issue 41355: !HAVE_LINKAT code path ignores the follow_symlinks flag
2032 with os_helper.temp_dir() as base_path:
2033 link_path = os.path.join(base_path, "link")
2034 target_path = os.path.join(base_path, "target")
2035 source_path = os.path.join(base_path, "source")
2036
2037 with open(source_path, "w") as fp:
2038 fp.write("data")
2039
2040 os.symlink("target", link_path)
2041
2042 # Calling os.link should fail in the link(2) call, and
2043 # should not reject *follow_symlinks* (to match the
2044 # behaviour you'd get when building on a platform without
2045 # linkat)
2046 with self.assertRaises(FileExistsError):
2047 os.link(source_path, link_path, follow_symlinks=True)
2048
2049 with self.assertRaises(FileExistsError):
2050 os.link(source_path, link_path, follow_symlinks=False)
2051
2052
2053 def test_listdir_scandir(self):
2054 self._verify_available("HAVE_FDOPENDIR")
2055 if self.mac_ver >= (10, 10):
2056 self.assertIn("HAVE_FDOPENDIR", posix._have_functions)
2057
2058 else:
2059 self.assertNotIn("HAVE_FDOPENDIR", posix._have_functions)
2060
2061 with self.assertRaisesRegex(TypeError, "listdir: path should be string, bytes, os.PathLike or None, not int"):
2062 os.listdir(0)
2063
2064 with self.assertRaisesRegex(TypeError, "scandir: path should be string, bytes, os.PathLike or None, not int"):
2065 os.scandir(0)
2066
2067 def test_mkdir(self):
2068 self._verify_available("HAVE_MKDIRAT")
2069 if self.mac_ver >= (10, 10):
2070 self.assertIn("HAVE_MKDIRAT", posix._have_functions)
2071
2072 else:
2073 self.assertNotIn("HAVE_MKDIRAT", posix._have_functions)
2074
2075 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2076 os.mkdir("dir", dir_fd=0)
2077
2078 def test_rename_replace(self):
2079 self._verify_available("HAVE_RENAMEAT")
2080 if self.mac_ver >= (10, 10):
2081 self.assertIn("HAVE_RENAMEAT", posix._have_functions)
2082
2083 else:
2084 self.assertNotIn("HAVE_RENAMEAT", posix._have_functions)
2085
2086 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2087 os.rename("a", "b", src_dir_fd=0)
2088
2089 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2090 os.rename("a", "b", dst_dir_fd=0)
2091
2092 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2093 os.replace("a", "b", src_dir_fd=0)
2094
2095 with self.assertRaisesRegex(NotImplementedError, "src_dir_fd and dst_dir_fd unavailable"):
2096 os.replace("a", "b", dst_dir_fd=0)
2097
2098 def test_unlink_rmdir(self):
2099 self._verify_available("HAVE_UNLINKAT")
2100 if self.mac_ver >= (10, 10):
2101 self.assertIn("HAVE_UNLINKAT", posix._have_functions)
2102
2103 else:
2104 self.assertNotIn("HAVE_UNLINKAT", posix._have_functions)
2105
2106 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2107 os.unlink("path", dir_fd=0)
2108
2109 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2110 os.rmdir("path", dir_fd=0)
2111
2112 def test_open(self):
2113 self._verify_available("HAVE_OPENAT")
2114 if self.mac_ver >= (10, 10):
2115 self.assertIn("HAVE_OPENAT", posix._have_functions)
2116
2117 else:
2118 self.assertNotIn("HAVE_OPENAT", posix._have_functions)
2119
2120 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2121 os.open("path", os.O_RDONLY, dir_fd=0)
2122
2123 def test_readlink(self):
2124 self._verify_available("HAVE_READLINKAT")
2125 if self.mac_ver >= (10, 10):
2126 self.assertIn("HAVE_READLINKAT", posix._have_functions)
2127
2128 else:
2129 self.assertNotIn("HAVE_READLINKAT", posix._have_functions)
2130
2131 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2132 os.readlink("path", dir_fd=0)
2133
2134 def test_symlink(self):
2135 self._verify_available("HAVE_SYMLINKAT")
2136 if self.mac_ver >= (10, 10):
2137 self.assertIn("HAVE_SYMLINKAT", posix._have_functions)
2138
2139 else:
2140 self.assertNotIn("HAVE_SYMLINKAT", posix._have_functions)
2141
2142 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2143 os.symlink("a", "b", dir_fd=0)
2144
2145 def test_utime(self):
2146 self._verify_available("HAVE_FUTIMENS")
2147 self._verify_available("HAVE_UTIMENSAT")
2148 if self.mac_ver >= (10, 13):
2149 self.assertIn("HAVE_FUTIMENS", posix._have_functions)
2150 self.assertIn("HAVE_UTIMENSAT", posix._have_functions)
2151
2152 else:
2153 self.assertNotIn("HAVE_FUTIMENS", posix._have_functions)
2154 self.assertNotIn("HAVE_UTIMENSAT", posix._have_functions)
2155
2156 with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"):
2157 os.utime("path", dir_fd=0)
2158
2159
Neal Norwitze241ce82003-02-17 18:17:05 +00002160def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01002161 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002162 support.run_unittest(
2163 PosixTester,
2164 PosixGroupsTester,
2165 TestPosixSpawn,
2166 TestPosixSpawnP,
Ronald Oussoren41761932020-11-08 10:05:27 +01002167 TestPosixWeaklinking
Joannah Nanjekye92b83222019-01-16 16:29:26 +03002168 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01002169 finally:
2170 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00002171
2172if __name__ == '__main__':
2173 test_main()