blob: 5c93d0d507d25274816356c5b19686265e061e46 [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
Antoine Pitrou346cbd32017-05-27 17:50:54 +02004from test.support.script_helper import assert_python_ok
R. David Murrayeb3615d2009-04-22 02:24:39 +00005
6# Skip these tests if there is no posix module.
7posix = support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00008
Antoine Pitroub7572f02009-12-02 20:46:48 +00009import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +000010import sys
Pablo Galindo254a4662018-09-07 16:44:24 +010011import signal
Neal Norwitze241ce82003-02-17 18:17:05 +000012import time
13import os
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020014import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000015import pwd
Benjamin Peterson052a02b2010-08-17 01:27:09 +000016import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
Pablo Galindo254a4662018-09-07 16:44:24 +010020import textwrap
R. David Murraya21e4ca2009-03-31 23:16:50 +000021
Ned Deilyba2eab22011-07-26 13:53:55 -070022_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
23 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000024
Serhiy Storchaka9d572732018-07-31 10:24:54 +030025requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
26 'test is only meaningful on 32-bit builds')
27
Benjamin Petersonc7042222018-09-12 15:12:24 -070028def _supports_sched():
29 if not hasattr(posix, 'sched_getscheduler'):
30 return False
31 try:
32 posix.sched_getscheduler(0)
33 except OSError as e:
34 if e.errno == errno.ENOSYS:
35 return False
36 return True
37
38requires_sched = unittest.skipUnless(_supports_sched(), 'requires POSIX scheduler API')
39
Neal Norwitze241ce82003-02-17 18:17:05 +000040class PosixTester(unittest.TestCase):
41
42 def setUp(self):
43 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000044 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000045 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070046 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000047 self._warnings_manager = support.check_warnings()
48 self._warnings_manager.__enter__()
49 warnings.filterwarnings('ignore', '.* potential security risk .*',
50 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000051
52 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070053 for teardown_file in self.teardown_files:
54 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000055 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000056
57 def testNoArgFunctions(self):
58 # test posix functions which take no arguments and have
59 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000060 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000061 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000062 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020063 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000064 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000065
Neal Norwitze241ce82003-02-17 18:17:05 +000066 for name in NO_ARG_FUNCTIONS:
67 posix_func = getattr(posix, name, None)
68 if posix_func is not None:
69 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000070 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000071
Serhiy Storchaka43767632013-11-03 21:31:38 +020072 @unittest.skipUnless(hasattr(posix, 'getresuid'),
73 'test needs posix.getresuid()')
74 def test_getresuid(self):
75 user_ids = posix.getresuid()
76 self.assertEqual(len(user_ids), 3)
77 for val in user_ids:
78 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000079
Serhiy Storchaka43767632013-11-03 21:31:38 +020080 @unittest.skipUnless(hasattr(posix, 'getresgid'),
81 'test needs posix.getresgid()')
82 def test_getresgid(self):
83 group_ids = posix.getresgid()
84 self.assertEqual(len(group_ids), 3)
85 for val in group_ids:
86 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000087
Serhiy Storchaka43767632013-11-03 21:31:38 +020088 @unittest.skipUnless(hasattr(posix, 'setresuid'),
89 'test needs posix.setresuid()')
90 def test_setresuid(self):
91 current_user_ids = posix.getresuid()
92 self.assertIsNone(posix.setresuid(*current_user_ids))
93 # -1 means don't change that value.
94 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000095
Serhiy Storchaka43767632013-11-03 21:31:38 +020096 @unittest.skipUnless(hasattr(posix, 'setresuid'),
97 'test needs posix.setresuid()')
98 def test_setresuid_exception(self):
99 # Don't do this test if someone is silly enough to run us as root.
100 current_user_ids = posix.getresuid()
101 if 0 not in current_user_ids:
102 new_user_ids = (current_user_ids[0]+1, -1, -1)
103 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000104
Serhiy Storchaka43767632013-11-03 21:31:38 +0200105 @unittest.skipUnless(hasattr(posix, 'setresgid'),
106 'test needs posix.setresgid()')
107 def test_setresgid(self):
108 current_group_ids = posix.getresgid()
109 self.assertIsNone(posix.setresgid(*current_group_ids))
110 # -1 means don't change that value.
111 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000112
Serhiy Storchaka43767632013-11-03 21:31:38 +0200113 @unittest.skipUnless(hasattr(posix, 'setresgid'),
114 'test needs posix.setresgid()')
115 def test_setresgid_exception(self):
116 # Don't do this test if someone is silly enough to run us as root.
117 current_group_ids = posix.getresgid()
118 if 0 not in current_group_ids:
119 new_group_ids = (current_group_ids[0]+1, -1, -1)
120 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000121
Antoine Pitroub7572f02009-12-02 20:46:48 +0000122 @unittest.skipUnless(hasattr(posix, 'initgroups'),
123 "test needs os.initgroups()")
124 def test_initgroups(self):
125 # It takes a string and an integer; check that it raises a TypeError
126 # for other argument lists.
127 self.assertRaises(TypeError, posix.initgroups)
128 self.assertRaises(TypeError, posix.initgroups, None)
129 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
130 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
131
132 # If a non-privileged user invokes it, it should fail with OSError
133 # EPERM.
134 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200135 try:
136 name = pwd.getpwuid(posix.getuid()).pw_name
137 except KeyError:
138 # the current UID may not have a pwd entry
139 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000140 try:
141 posix.initgroups(name, 13)
142 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000143 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000144 else:
145 self.fail("Expected OSError to be raised by initgroups")
146
Serhiy Storchaka43767632013-11-03 21:31:38 +0200147 @unittest.skipUnless(hasattr(posix, 'statvfs'),
148 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000149 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200150 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000151
Serhiy Storchaka43767632013-11-03 21:31:38 +0200152 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
153 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000154 def test_fstatvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200155 fp = open(support.TESTFN)
156 try:
157 self.assertTrue(posix.fstatvfs(fp.fileno()))
158 self.assertTrue(posix.statvfs(fp.fileno()))
159 finally:
160 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000161
Serhiy Storchaka43767632013-11-03 21:31:38 +0200162 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
163 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000164 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200165 fp = open(support.TESTFN, 'w+')
166 try:
167 # we need to have some data to truncate
168 fp.write('test')
169 fp.flush()
170 posix.ftruncate(fp.fileno(), 0)
171 finally:
172 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000173
Ross Lagerwall7807c352011-03-17 20:20:30 +0200174 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
175 def test_truncate(self):
176 with open(support.TESTFN, 'w') as fp:
177 fp.write('test')
178 fp.flush()
179 posix.truncate(support.TESTFN, 0)
180
Larry Hastings9cf065c2012-06-22 16:30:09 -0700181 @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 +0200182 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200183 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200184 def test_fexecve(self):
185 fp = os.open(sys.executable, os.O_RDONLY)
186 try:
187 pid = os.fork()
188 if pid == 0:
189 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700190 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200191 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200192 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200193 finally:
194 os.close(fp)
195
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000196
Ross Lagerwall7807c352011-03-17 20:20:30 +0200197 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
198 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
199 def test_waitid(self):
200 pid = os.fork()
201 if pid == 0:
202 os.chdir(os.path.split(sys.executable)[0])
203 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
204 else:
205 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
206 self.assertEqual(pid, res.si_pid)
207
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200208 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700209 def test_register_at_fork(self):
210 with self.assertRaises(TypeError, msg="Positional args not allowed"):
211 os.register_at_fork(lambda: None)
212 with self.assertRaises(TypeError, msg="Args must be callable"):
213 os.register_at_fork(before=2)
214 with self.assertRaises(TypeError, msg="Args must be callable"):
215 os.register_at_fork(after_in_child="three")
216 with self.assertRaises(TypeError, msg="Args must be callable"):
217 os.register_at_fork(after_in_parent=b"Five")
218 with self.assertRaises(TypeError, msg="Args must not be None"):
219 os.register_at_fork(before=None)
220 with self.assertRaises(TypeError, msg="Args must not be None"):
221 os.register_at_fork(after_in_child=None)
222 with self.assertRaises(TypeError, msg="Args must not be None"):
223 os.register_at_fork(after_in_parent=None)
224 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
225 # Ensure a combination of valid and invalid is an error.
226 os.register_at_fork(before=None, after_in_parent=lambda: 3)
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=lambda: None, after_in_child='')
230 # We test actual registrations in their own process so as not to
231 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200232 code = """if 1:
233 import os
234
235 r, w = os.pipe()
236 fin_r, fin_w = os.pipe()
237
Gregory P. Smith163468a2017-05-29 10:03:41 -0700238 os.register_at_fork(before=lambda: os.write(w, b'A'))
239 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
240 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
241 os.register_at_fork(before=lambda: os.write(w, b'B'),
242 after_in_parent=lambda: os.write(w, b'D'),
243 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200244
245 pid = os.fork()
246 if pid == 0:
247 # At this point, after-forkers have already been executed
248 os.close(w)
249 # Wait for parent to tell us to exit
250 os.read(fin_r, 1)
251 os._exit(0)
252 else:
253 try:
254 os.close(w)
255 with open(r, "rb") as f:
256 data = f.read()
257 assert len(data) == 6, data
258 # Check before-fork callbacks
259 assert data[:2] == b'BA', data
260 # Check after-fork callbacks
261 assert sorted(data[2:]) == list(b'CDEF'), data
262 assert data.index(b'C') < data.index(b'D'), data
263 assert data.index(b'E') < data.index(b'F'), data
264 finally:
265 os.write(fin_w, b'!')
266 """
267 assert_python_ok('-c', code)
268
Ross Lagerwall7807c352011-03-17 20:20:30 +0200269 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
270 def test_lockf(self):
271 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
272 try:
273 os.write(fd, b'test')
274 os.lseek(fd, 0, os.SEEK_SET)
275 posix.lockf(fd, posix.F_LOCK, 4)
276 # section is locked
277 posix.lockf(fd, posix.F_ULOCK, 4)
278 finally:
279 os.close(fd)
280
281 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
282 def test_pread(self):
283 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
284 try:
285 os.write(fd, b'test')
286 os.lseek(fd, 0, os.SEEK_SET)
287 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100288 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200289 self.assertEqual(b'te', posix.read(fd, 2))
290 finally:
291 os.close(fd)
292
Pablo Galindo4defba32018-01-27 16:16:37 +0000293 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
294 def test_preadv(self):
295 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
296 try:
297 os.write(fd, b'test1tt2t3t5t6t6t8')
298 buf = [bytearray(i) for i in [5, 3, 2]]
299 self.assertEqual(posix.preadv(fd, buf, 3), 10)
300 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
301 finally:
302 os.close(fd)
303
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300304 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000305 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
306 def test_preadv_flags(self):
307 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
308 try:
309 os.write(fd, b'test1tt2t3t5t6t6t8')
310 buf = [bytearray(i) for i in [5, 3, 2]]
311 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
312 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
Pablo Galindo46544f62019-04-13 17:06:03 +0100313 except OSError as inst:
314 # Is possible that the macro RWF_HIPRI was defined at compilation time
315 # but the option is not supported by the kernel or the runtime libc shared
316 # library.
317 if inst.errno in {errno.EINVAL, errno.ENOTSUP}:
318 raise unittest.SkipTest("RWF_HIPRI is not supported by the current system")
319 else:
320 raise
Pablo Galindo4defba32018-01-27 16:16:37 +0000321 finally:
322 os.close(fd)
323
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300324 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
325 @requires_32b
326 def test_preadv_overflow_32bits(self):
327 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
328 try:
329 buf = [bytearray(2**16)] * 2**15
330 with self.assertRaises(OSError) as cm:
331 os.preadv(fd, buf, 0)
332 self.assertEqual(cm.exception.errno, errno.EINVAL)
333 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
334 finally:
335 os.close(fd)
336
Ross Lagerwall7807c352011-03-17 20:20:30 +0200337 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
338 def test_pwrite(self):
339 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
340 try:
341 os.write(fd, b'test')
342 os.lseek(fd, 0, os.SEEK_SET)
343 posix.pwrite(fd, b'xx', 1)
344 self.assertEqual(b'txxt', posix.read(fd, 4))
345 finally:
346 os.close(fd)
347
Pablo Galindo4defba32018-01-27 16:16:37 +0000348 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
349 def test_pwritev(self):
350 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
351 try:
352 os.write(fd, b"xx")
353 os.lseek(fd, 0, os.SEEK_SET)
354 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
355 self.assertEqual(n, 10)
356
357 os.lseek(fd, 0, os.SEEK_SET)
358 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
359 finally:
360 os.close(fd)
361
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300362 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000363 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
364 def test_pwritev_flags(self):
365 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
366 try:
367 os.write(fd,b"xx")
368 os.lseek(fd, 0, os.SEEK_SET)
369 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
370 self.assertEqual(n, 10)
371
372 os.lseek(fd, 0, os.SEEK_SET)
373 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
374 finally:
375 os.close(fd)
376
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300377 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
378 @requires_32b
379 def test_pwritev_overflow_32bits(self):
380 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
381 try:
382 with self.assertRaises(OSError) as cm:
383 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
384 self.assertEqual(cm.exception.errno, errno.EINVAL)
385 finally:
386 os.close(fd)
387
Ross Lagerwall7807c352011-03-17 20:20:30 +0200388 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
389 "test needs posix.posix_fallocate()")
390 def test_posix_fallocate(self):
391 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
392 try:
393 posix.posix_fallocate(fd, 0, 10)
394 except OSError as inst:
395 # issue10812, ZFS doesn't appear to support posix_fallocate,
396 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400397 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
398 # often used there.
399 if inst.errno == errno.EINVAL and sys.platform.startswith(
400 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
401 raise unittest.SkipTest("test may fail on ZFS filesystems")
402 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200403 raise
404 finally:
405 os.close(fd)
406
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500407 # issue31106 - posix_fallocate() does not set error in errno.
408 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
409 "test needs posix.posix_fallocate()")
410 def test_posix_fallocate_errno(self):
411 try:
412 posix.posix_fallocate(-42, 0, 10)
413 except OSError as inst:
414 if inst.errno != errno.EBADF:
415 raise
416
Ross Lagerwall7807c352011-03-17 20:20:30 +0200417 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
418 "test needs posix.posix_fadvise()")
419 def test_posix_fadvise(self):
420 fd = os.open(support.TESTFN, os.O_RDONLY)
421 try:
422 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
423 finally:
424 os.close(fd)
425
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500426 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
427 "test needs posix.posix_fadvise()")
428 def test_posix_fadvise_errno(self):
429 try:
430 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
431 except OSError as inst:
432 if inst.errno != errno.EBADF:
433 raise
434
Larry Hastings9cf065c2012-06-22 16:30:09 -0700435 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
436 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200437 now = time.time()
438 fd = os.open(support.TESTFN, os.O_RDONLY)
439 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700440 posix.utime(fd)
441 posix.utime(fd, None)
442 self.assertRaises(TypeError, posix.utime, fd, (None, None))
443 self.assertRaises(TypeError, posix.utime, fd, (now, None))
444 self.assertRaises(TypeError, posix.utime, fd, (None, now))
445 posix.utime(fd, (int(now), int(now)))
446 posix.utime(fd, (now, now))
447 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
448 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
449 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
450 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
451 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
452
Ross Lagerwall7807c352011-03-17 20:20:30 +0200453 finally:
454 os.close(fd)
455
Larry Hastings9cf065c2012-06-22 16:30:09 -0700456 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
457 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200458 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700459 posix.utime(support.TESTFN, None, follow_symlinks=False)
460 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
461 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
462 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
463 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
464 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
465 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200466
467 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
468 def test_writev(self):
469 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
470 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100471 n = os.writev(fd, (b'test1', b'tt2', b't3'))
472 self.assertEqual(n, 10)
473
Ross Lagerwall7807c352011-03-17 20:20:30 +0200474 os.lseek(fd, 0, os.SEEK_SET)
475 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100476
477 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100478 try:
479 size = posix.writev(fd, [])
480 except OSError:
481 # writev(fd, []) raises OSError(22, "Invalid argument")
482 # on OpenIndiana
483 pass
484 else:
485 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200486 finally:
487 os.close(fd)
488
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300489 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
490 @requires_32b
491 def test_writev_overflow_32bits(self):
492 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
493 try:
494 with self.assertRaises(OSError) as cm:
495 os.writev(fd, [b"x" * 2**16] * 2**15)
496 self.assertEqual(cm.exception.errno, errno.EINVAL)
497 finally:
498 os.close(fd)
499
Ross Lagerwall7807c352011-03-17 20:20:30 +0200500 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
501 def test_readv(self):
502 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
503 try:
504 os.write(fd, b'test1tt2t3')
505 os.lseek(fd, 0, os.SEEK_SET)
506 buf = [bytearray(i) for i in [5, 3, 2]]
507 self.assertEqual(posix.readv(fd, buf), 10)
508 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100509
510 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100511 try:
512 size = posix.readv(fd, [])
513 except OSError:
514 # readv(fd, []) raises OSError(22, "Invalid argument")
515 # on OpenIndiana
516 pass
517 else:
518 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200519 finally:
520 os.close(fd)
521
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300522 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
523 @requires_32b
524 def test_readv_overflow_32bits(self):
525 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
526 try:
527 buf = [bytearray(2**16)] * 2**15
528 with self.assertRaises(OSError) as cm:
529 os.readv(fd, buf)
530 self.assertEqual(cm.exception.errno, errno.EINVAL)
531 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
532 finally:
533 os.close(fd)
534
Serhiy Storchaka43767632013-11-03 21:31:38 +0200535 @unittest.skipUnless(hasattr(posix, 'dup'),
536 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000537 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200538 fp = open(support.TESTFN)
539 try:
540 fd = posix.dup(fp.fileno())
541 self.assertIsInstance(fd, int)
542 os.close(fd)
543 finally:
544 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000545
Serhiy Storchaka43767632013-11-03 21:31:38 +0200546 @unittest.skipUnless(hasattr(posix, 'confstr'),
547 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000548 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200549 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
550 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551
Serhiy Storchaka43767632013-11-03 21:31:38 +0200552 @unittest.skipUnless(hasattr(posix, 'dup2'),
553 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000554 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200555 fp1 = open(support.TESTFN)
556 fp2 = open(support.TESTFN)
557 try:
558 posix.dup2(fp1.fileno(), fp2.fileno())
559 finally:
560 fp1.close()
561 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000562
Charles-François Natali1e045b12011-05-22 20:42:32 +0200563 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200564 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200565 def test_oscloexec(self):
566 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
567 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200568 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200569
Serhiy Storchaka43767632013-11-03 21:31:38 +0200570 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
571 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000572 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200573 fd = os.open(support.TESTFN,
574 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
575 self.assertRaises(OSError, os.open, support.TESTFN,
576 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
577 os.close(fd)
578
579 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000580 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200581 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000582 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000583 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
584 os.close(fd)
585
Serhiy Storchaka43767632013-11-03 21:31:38 +0200586 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
587 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000588 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200589 fd1 = os.open(support.TESTFN,
590 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
591 fd2 = os.open(support.TESTFN,
592 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
593 os.close(fd2)
594 os.close(fd1)
595
596 if hasattr(posix, "O_EXLOCK"):
597 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000598 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200599 self.assertRaises(OSError, os.open, support.TESTFN,
600 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
601 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000602
Serhiy Storchaka43767632013-11-03 21:31:38 +0200603 @unittest.skipUnless(hasattr(posix, 'fstat'),
604 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000605 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200606 fp = open(support.TESTFN)
607 try:
608 self.assertTrue(posix.fstat(fp.fileno()))
609 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200610
Serhiy Storchaka43767632013-11-03 21:31:38 +0200611 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700612 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200613 posix.stat, float(fp.fileno()))
614 finally:
615 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000616
617 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200618 self.assertTrue(posix.stat(support.TESTFN))
619 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200620
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300621 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700622 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300623 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200624 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700625 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200626 posix.stat, None)
627 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700628 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200629 posix.stat, list(support.TESTFN))
630 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700631 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200632 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000633
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000634 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
635 def test_mkfifo(self):
636 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100637 try:
638 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
639 except PermissionError as e:
640 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000641 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
642
643 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
644 "don't have mknod()/S_IFIFO")
645 def test_mknod(self):
646 # Test using mknod() to create a FIFO (the only use specified
647 # by POSIX).
648 support.unlink(support.TESTFN)
649 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
650 try:
651 posix.mknod(support.TESTFN, mode, 0)
652 except OSError as e:
653 # Some old systems don't allow unprivileged users to use
654 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100655 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000656 else:
657 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
658
Martin Panterbf19d162015-09-09 01:01:13 +0000659 # Keyword arguments are also supported
660 support.unlink(support.TESTFN)
661 try:
662 posix.mknod(path=support.TESTFN, mode=mode, device=0,
663 dir_fd=None)
664 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100665 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000666
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300667 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
668 def test_makedev(self):
669 st = posix.stat(support.TESTFN)
670 dev = st.st_dev
671 self.assertIsInstance(dev, int)
672 self.assertGreaterEqual(dev, 0)
673
674 major = posix.major(dev)
675 self.assertIsInstance(major, int)
676 self.assertGreaterEqual(major, 0)
677 self.assertEqual(posix.major(dev), major)
678 self.assertRaises(TypeError, posix.major, float(dev))
679 self.assertRaises(TypeError, posix.major)
680 self.assertRaises((ValueError, OverflowError), posix.major, -1)
681
682 minor = posix.minor(dev)
683 self.assertIsInstance(minor, int)
684 self.assertGreaterEqual(minor, 0)
685 self.assertEqual(posix.minor(dev), minor)
686 self.assertRaises(TypeError, posix.minor, float(dev))
687 self.assertRaises(TypeError, posix.minor)
688 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
689
690 self.assertEqual(posix.makedev(major, minor), dev)
691 self.assertRaises(TypeError, posix.makedev, float(major), minor)
692 self.assertRaises(TypeError, posix.makedev, major, float(minor))
693 self.assertRaises(TypeError, posix.makedev, major)
694 self.assertRaises(TypeError, posix.makedev)
695
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200696 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000697 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200698 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200699 if stat_func is not None:
700 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200701 self.assertEqual(stat.st_uid, uid)
702 self.assertEqual(stat.st_gid, gid)
703 uid = os.getuid()
704 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200705 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200706 chown_func(first_param, uid, gid)
707 check_stat(uid, gid)
708 chown_func(first_param, -1, gid)
709 check_stat(uid, gid)
710 chown_func(first_param, uid, -1)
711 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200712
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200713 if uid == 0:
714 # Try an amusingly large uid/gid to make sure we handle
715 # large unsigned values. (chown lets you use any
716 # uid/gid you like, even if they aren't defined.)
717 #
718 # This problem keeps coming up:
719 # http://bugs.python.org/issue1747858
720 # http://bugs.python.org/issue4591
721 # http://bugs.python.org/issue15301
722 # Hopefully the fix in 4591 fixes it for good!
723 #
724 # This part of the test only runs when run as root.
725 # Only scary people run their tests as root.
726
727 big_value = 2**31
728 chown_func(first_param, big_value, big_value)
729 check_stat(big_value, big_value)
730 chown_func(first_param, -1, -1)
731 check_stat(big_value, big_value)
732 chown_func(first_param, uid, gid)
733 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200734 elif platform.system() in ('HP-UX', 'SunOS'):
735 # HP-UX and Solaris can allow a non-root user to chown() to root
736 # (issue #5113)
737 raise unittest.SkipTest("Skipping because of non-standard chown() "
738 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000739 else:
740 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200741 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200742 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200743 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200744 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200745 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200746 self.assertRaises(OSError, chown_func, first_param, -1, 0)
747 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200748 # test illegal types
749 for t in str, float:
750 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
751 check_stat(uid, gid)
752 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
753 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000754
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000755 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
756 def test_chown(self):
757 # raise an OSError if the file does not exist
758 os.unlink(support.TESTFN)
759 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000760
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000761 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200762 support.create_empty_file(support.TESTFN)
Anthony Sottile8377cd42019-02-25 14:32:27 -0800763 self._test_all_chown_common(posix.chown, support.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000764
765 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
766 def test_fchown(self):
767 os.unlink(support.TESTFN)
768
769 # re-create the file
770 test_file = open(support.TESTFN, 'w')
771 try:
772 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200773 self._test_all_chown_common(posix.fchown, fd,
774 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000775 finally:
776 test_file.close()
777
778 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
779 def test_lchown(self):
780 os.unlink(support.TESTFN)
781 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700782 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200783 self._test_all_chown_common(posix.lchown, support.TESTFN,
784 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000785
Serhiy Storchaka43767632013-11-03 21:31:38 +0200786 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000787 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200788 posix.chdir(os.curdir)
789 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000790
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000791 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300792 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000793
794 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700795 # When listdir is called without argument,
796 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300797 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000798
Larry Hastingsfdaea062012-06-25 04:42:23 -0700799 def test_listdir_bytes(self):
800 # When listdir is called with a bytes object,
801 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300802 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
803
804 def test_listdir_bytes_like(self):
805 for cls in bytearray, memoryview:
806 with self.assertWarns(DeprecationWarning):
807 names = posix.listdir(cls(b'.'))
808 self.assertIn(os.fsencode(support.TESTFN), names)
809 for name in names:
810 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700811
812 @unittest.skipUnless(posix.listdir in os.supports_fd,
813 "test needs fd support for posix.listdir()")
814 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000815 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100816 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000817 self.assertEqual(
818 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700819 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000820 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100821 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100822 self.assertEqual(
823 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100825 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000826
Serhiy Storchaka43767632013-11-03 21:31:38 +0200827 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000828 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200829 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000830
Serhiy Storchaka43767632013-11-03 21:31:38 +0200831 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000832 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200833 old_mask = posix.umask(0)
834 self.assertIsInstance(old_mask, int)
835 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000836
Serhiy Storchaka43767632013-11-03 21:31:38 +0200837 @unittest.skipUnless(hasattr(posix, 'strerror'),
838 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000839 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200840 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000841
Serhiy Storchaka43767632013-11-03 21:31:38 +0200842 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000843 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200844 reader, writer = posix.pipe()
845 os.close(reader)
846 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000847
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200848 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200849 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200850 def test_pipe2(self):
851 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
852 self.assertRaises(TypeError, os.pipe2, 0, 0)
853
Charles-François Natali368f34b2011-06-06 19:49:47 +0200854 # try calling with flags = 0, like os.pipe()
855 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200856 os.close(r)
857 os.close(w)
858
859 # test flags
860 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
861 self.addCleanup(os.close, r)
862 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200863 self.assertFalse(os.get_inheritable(r))
864 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200865 self.assertFalse(os.get_blocking(r))
866 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200867 # try reading from an empty pipe: this should fail, not block
868 self.assertRaises(OSError, os.read, r, 1)
869 # try a write big enough to fill-up the pipe: this should either
870 # fail or perform a partial write, not block
871 try:
872 os.write(w, b'x' * support.PIPE_MAX_SIZE)
873 except OSError:
874 pass
875
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200876 @support.cpython_only
877 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
878 @support.requires_linux_version(2, 6, 27)
879 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200880 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200881 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200882 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
883 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
884
Serhiy Storchaka43767632013-11-03 21:31:38 +0200885 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000886 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200887 now = time.time()
888 posix.utime(support.TESTFN, None)
889 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
890 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
891 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
892 posix.utime(support.TESTFN, (int(now), int(now)))
893 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000894
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700896 st = os.stat(target_file)
897 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000898
899 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
900 flags = st.st_flags | stat.UF_IMMUTABLE
901 try:
902 chflags_func(target_file, flags, **kwargs)
903 except OSError as err:
904 if err.errno != errno.EOPNOTSUPP:
905 raise
906 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
907 self.skipTest(msg)
908
Ned Deily3eb67d52011-06-28 00:00:28 -0700909 try:
910 new_st = os.stat(target_file)
911 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
912 try:
913 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200914 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700915 self.assertEqual(e.errno, errno.EPERM)
916 finally:
917 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000918
Ned Deily3eb67d52011-06-28 00:00:28 -0700919 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
920 def test_chflags(self):
921 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
922
923 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
924 def test_lchflags_regular_file(self):
925 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700927
928 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
929 def test_lchflags_symlink(self):
930 testfn_st = os.stat(support.TESTFN)
931
932 self.assertTrue(hasattr(testfn_st, 'st_flags'))
933
934 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
935 self.teardown_files.append(_DUMMY_SYMLINK)
936 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
937
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 def chflags_nofollow(path, flags):
939 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700940
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000942 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
943 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
944 try:
945 fn(_DUMMY_SYMLINK, flags)
946 except OSError as err:
947 if err.errno != errno.EOPNOTSUPP:
948 raise
949 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
950 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 try:
952 new_testfn_st = os.stat(support.TESTFN)
953 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
954
955 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
956 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
957 new_dummy_symlink_st.st_flags)
958 finally:
959 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000960
Guido van Rossum98297ee2007-11-06 21:34:58 +0000961 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000962 if os.name == "nt":
963 item_type = str
964 else:
965 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000966 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000967 self.assertEqual(type(k), item_type)
968 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000969
Serhiy Storchaka77703942017-06-25 07:33:01 +0300970 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
971 def test_putenv(self):
972 with self.assertRaises(ValueError):
973 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
974 with self.assertRaises(ValueError):
975 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
976 with self.assertRaises(ValueError):
977 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
978 with self.assertRaises(ValueError):
979 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
980 with self.assertRaises(ValueError):
981 os.putenv('FRUIT=ORANGE', 'lemon')
982 with self.assertRaises(ValueError):
983 os.putenv(b'FRUIT=ORANGE', b'lemon')
984
Serhiy Storchaka43767632013-11-03 21:31:38 +0200985 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000986 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500987 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
988 curdir = os.getcwd()
989 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000990
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500991 try:
992 os.mkdir(base_path)
993 os.chdir(base_path)
994 except:
995 # Just returning nothing instead of the SkipTest exception, because
996 # the test results in Error in that case. Is that ok?
997 # raise unittest.SkipTest("cannot create directory for testing")
998 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000999
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001000 def _create_and_do_getcwd(dirname, current_path_length = 0):
1001 try:
1002 os.mkdir(dirname)
1003 except:
1004 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001005
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001006 os.chdir(dirname)
1007 try:
1008 os.getcwd()
1009 if current_path_length < 1027:
1010 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1011 finally:
1012 os.chdir('..')
1013 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001014
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001015 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001017 finally:
1018 os.chdir(curdir)
1019 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001020
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001021 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1022 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1023 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1024 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001025 user = pwd.getpwuid(os.getuid())[0]
1026 group = pwd.getpwuid(os.getuid())[3]
1027 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001028
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001029
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001030 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001031 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001032 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001033 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001034 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001035
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001036 try:
1037 idg_groups = set(int(g) for g in groups.split())
1038 except ValueError:
1039 idg_groups = set()
1040 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001041 raise unittest.SkipTest("need working 'id -G'")
1042
Ned Deily028915e2013-02-02 15:08:52 -08001043 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1044 if sys.platform == 'darwin':
1045 import sysconfig
1046 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001047 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001048 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1049
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001050 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001051 # groups, ignoring order, duplicates, and the effective gid.
1052 # #10822/#26944 - It is implementation defined whether
1053 # posix.getgroups() includes the effective gid.
1054 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1055 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001056
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001057 # tests for the posix *at functions follow
1058
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1060 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001061 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1062 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001064 finally:
1065 posix.close(f)
1066
Larry Hastings9cf065c2012-06-22 16:30:09 -07001067 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1068 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001069 os.chmod(support.TESTFN, stat.S_IRUSR)
1070
1071 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1072 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001073 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001074
1075 s = posix.stat(support.TESTFN)
1076 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1077 finally:
1078 posix.close(f)
1079
Larry Hastings9cf065c2012-06-22 16:30:09 -07001080 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1081 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001082 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001083 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001084
1085 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1086 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001088 finally:
1089 posix.close(f)
1090
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1092 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001093 support.unlink(support.TESTFN)
1094 with open(support.TESTFN, 'w') as outfile:
1095 outfile.write("testline\n")
1096
1097 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1098 try:
1099 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001101 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001102 s2 = posix.stat(support.TESTFN, dir_fd=None)
1103 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001104 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001105 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001106 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001107 posix.stat, support.TESTFN, dir_fd=float(f))
1108 self.assertRaises(OverflowError,
1109 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001110 finally:
1111 posix.close(f)
1112
Larry Hastings9cf065c2012-06-22 16:30:09 -07001113 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1114 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001115 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1116 try:
1117 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001118 posix.utime(support.TESTFN, None, dir_fd=f)
1119 posix.utime(support.TESTFN, dir_fd=f)
1120 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1121 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1122 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1123 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1124 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1125 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1126 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1127 posix.utime(support.TESTFN,
1128 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1129 posix.utime(support.TESTFN, dir_fd=f,
1130 times=(int(now), int((now - int(now)) * 1e9)))
1131
Larry Hastings90867a52012-06-22 17:01:41 -07001132 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001133 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001134 try:
1135 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001136 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001137 # whoops! using both together not supported on this platform.
1138 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001140 finally:
1141 posix.close(f)
1142
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1144 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001145 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1146 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001148 except PermissionError as e:
1149 self.skipTest('posix.link(): %s' % e)
1150 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001151 # should have same inodes
1152 self.assertEqual(posix.stat(support.TESTFN)[1],
1153 posix.stat(support.TESTFN + 'link')[1])
1154 finally:
1155 posix.close(f)
1156 support.unlink(support.TESTFN + 'link')
1157
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1159 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001160 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1161 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001162 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001163 posix.stat(support.TESTFN + 'dir') # should not raise exception
1164 finally:
1165 posix.close(f)
1166 support.rmtree(support.TESTFN + 'dir')
1167
Larry Hastings9cf065c2012-06-22 16:30:09 -07001168 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1169 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1170 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001171 # Test using mknodat() to create a FIFO (the only use specified
1172 # by POSIX).
1173 support.unlink(support.TESTFN)
1174 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1175 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1176 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001178 except OSError as e:
1179 # Some old systems don't allow unprivileged users to use
1180 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001181 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001182 else:
1183 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1184 finally:
1185 posix.close(f)
1186
Larry Hastings9cf065c2012-06-22 16:30:09 -07001187 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1188 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001189 support.unlink(support.TESTFN)
1190 with open(support.TESTFN, 'w') as outfile:
1191 outfile.write("testline\n")
1192 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001194 try:
1195 res = posix.read(b, 9).decode(encoding="utf-8")
1196 self.assertEqual("testline\n", res)
1197 finally:
1198 posix.close(a)
1199 posix.close(b)
1200
Larry Hastings9cf065c2012-06-22 16:30:09 -07001201 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1202 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001203 os.symlink(support.TESTFN, support.TESTFN + 'link')
1204 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1205 try:
1206 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001207 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001208 finally:
1209 support.unlink(support.TESTFN + 'link')
1210 posix.close(f)
1211
Larry Hastings9cf065c2012-06-22 16:30:09 -07001212 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1213 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001214 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001215 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001216 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1217 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001218 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001219 except:
1220 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1221 raise
1222 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001223 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001224 finally:
1225 posix.close(f)
1226
Larry Hastings9cf065c2012-06-22 16:30:09 -07001227 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1228 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001229 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1230 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001231 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001232 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1233 finally:
1234 posix.close(f)
1235 support.unlink(support.TESTFN + 'link')
1236
Larry Hastings9cf065c2012-06-22 16:30:09 -07001237 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1238 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001239 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001240 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001241 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001242 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001243 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001244 except:
1245 support.unlink(support.TESTFN + 'del')
1246 raise
1247 else:
1248 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1249 finally:
1250 posix.close(f)
1251
Larry Hastings9cf065c2012-06-22 16:30:09 -07001252 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1253 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001254 support.unlink(support.TESTFN)
1255 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1256 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001257 try:
1258 posix.mkfifo(support.TESTFN,
1259 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1260 except PermissionError as e:
1261 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001262 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1263 finally:
1264 posix.close(f)
1265
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001266 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1267 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001268 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001269 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001270
1271 @requires_sched_h
1272 def test_sched_yield(self):
1273 # This has no error conditions (at least on Linux).
1274 posix.sched_yield()
1275
1276 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001277 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1278 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001279 def test_sched_priority(self):
1280 # Round-robin usually has interesting priorities.
1281 pol = posix.SCHED_RR
1282 lo = posix.sched_get_priority_min(pol)
1283 hi = posix.sched_get_priority_max(pol)
1284 self.assertIsInstance(lo, int)
1285 self.assertIsInstance(hi, int)
1286 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001287 # OSX evidently just returns 15 without checking the argument.
1288 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001289 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1290 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001291
Benjamin Petersonc7042222018-09-12 15:12:24 -07001292 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001293 def test_get_and_set_scheduler_and_param(self):
1294 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1295 if name.startswith("SCHED_")]
1296 mine = posix.sched_getscheduler(0)
1297 self.assertIn(mine, possible_schedulers)
1298 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001299 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001300 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001301 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001302 raise
1303 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001304 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001305 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1306 self.assertRaises(OSError, posix.sched_getparam, -1)
1307 param = posix.sched_getparam(0)
1308 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001309
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001310 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1311 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1312 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1313 if not sys.platform.startswith(('freebsd', 'netbsd')):
1314 try:
1315 posix.sched_setscheduler(0, mine, param)
1316 posix.sched_setparam(0, param)
1317 except OSError as e:
1318 if e.errno != errno.EPERM:
1319 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001320 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1321
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001322 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1323 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1324 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1325 param = posix.sched_param(None)
1326 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1327 large = 214748364700
1328 param = posix.sched_param(large)
1329 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1330 param = posix.sched_param(sched_priority=-large)
1331 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1332
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001333 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001334 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001335 try:
1336 interval = posix.sched_rr_get_interval(0)
1337 except OSError as e:
1338 # This likely means that sched_rr_get_interval is only valid for
1339 # processes with the SCHED_RR scheduler in effect.
1340 if e.errno != errno.EINVAL:
1341 raise
1342 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001343 self.assertIsInstance(interval, float)
1344 # Reasonable constraints, I think.
1345 self.assertGreaterEqual(interval, 0.)
1346 self.assertLess(interval, 1.)
1347
Benjamin Peterson2740af82011-08-02 17:41:34 -05001348 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001349 def test_sched_getaffinity(self):
1350 mask = posix.sched_getaffinity(0)
1351 self.assertIsInstance(mask, set)
1352 self.assertGreaterEqual(len(mask), 1)
1353 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1354 for cpu in mask:
1355 self.assertIsInstance(cpu, int)
1356 self.assertGreaterEqual(cpu, 0)
1357 self.assertLess(cpu, 1 << 32)
1358
1359 @requires_sched_affinity
1360 def test_sched_setaffinity(self):
1361 mask = posix.sched_getaffinity(0)
1362 if len(mask) > 1:
1363 # Empty masks are forbidden
1364 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001365 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001366 self.assertEqual(posix.sched_getaffinity(0), mask)
1367 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1368 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1369 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001370 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1371
Victor Stinner8b905bd2011-10-25 13:34:04 +02001372 def test_rtld_constants(self):
1373 # check presence of major RTLD_* constants
1374 posix.RTLD_LAZY
1375 posix.RTLD_NOW
1376 posix.RTLD_GLOBAL
1377 posix.RTLD_LOCAL
1378
Jesus Cea60c13dd2012-06-23 02:58:14 +02001379 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1380 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001381 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001382 # Even if the filesystem doesn't report holes,
1383 # if the OS supports it the SEEK_* constants
1384 # will be defined and will have a consistent
1385 # behaviour:
1386 # os.SEEK_DATA = current position
1387 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001388 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001389 fp.write(b"hello")
1390 fp.flush()
1391 size = fp.tell()
1392 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001393 try :
1394 for i in range(size):
1395 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1396 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1397 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1398 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1399 except OSError :
1400 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1401 # but it is not true.
1402 # For instance:
1403 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1404 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001405
Larry Hastingsb0827312014-02-09 22:05:19 -08001406 def test_path_error2(self):
1407 """
1408 Test functions that call path_error2(), providing two filenames in their exceptions.
1409 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001410 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001411 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001412 if function is None:
1413 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001414
Victor Stinnerbed04a72014-10-05 17:37:59 +02001415 for dst in ("noodly2", support.TESTFN):
1416 try:
1417 function('doesnotexistfilename', dst)
1418 except OSError as e:
1419 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1420 break
1421 else:
1422 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001423
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001424 def test_path_with_null_character(self):
1425 fn = support.TESTFN
1426 fn_with_NUL = fn + '\0'
1427 self.addCleanup(support.unlink, fn)
1428 support.unlink(fn)
1429 fd = None
1430 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001431 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001432 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1433 finally:
1434 if fd is not None:
1435 os.close(fd)
1436 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001437 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001438 self.assertFalse(os.path.exists(fn))
1439 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001440 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001441
1442 def test_path_with_null_byte(self):
1443 fn = os.fsencode(support.TESTFN)
1444 fn_with_NUL = fn + b'\0'
1445 self.addCleanup(support.unlink, fn)
1446 support.unlink(fn)
1447 fd = None
1448 try:
1449 with self.assertRaises(ValueError):
1450 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1451 finally:
1452 if fd is not None:
1453 os.close(fd)
1454 self.assertFalse(os.path.exists(fn))
1455 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1456 self.assertFalse(os.path.exists(fn))
1457 open(fn, 'wb').close()
1458 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1459
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001460class PosixGroupsTester(unittest.TestCase):
1461
1462 def setUp(self):
1463 if posix.getuid() != 0:
1464 raise unittest.SkipTest("not enough privileges")
1465 if not hasattr(posix, 'getgroups'):
1466 raise unittest.SkipTest("need posix.getgroups")
1467 if sys.platform == 'darwin':
1468 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1469 self.saved_groups = posix.getgroups()
1470
1471 def tearDown(self):
1472 if hasattr(posix, 'setgroups'):
1473 posix.setgroups(self.saved_groups)
1474 elif hasattr(posix, 'initgroups'):
1475 name = pwd.getpwuid(posix.getuid()).pw_name
1476 posix.initgroups(name, self.saved_groups[0])
1477
1478 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1479 "test needs posix.initgroups()")
1480 def test_initgroups(self):
1481 # find missing group
1482
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001483 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001484 name = pwd.getpwuid(posix.getuid()).pw_name
1485 posix.initgroups(name, g)
1486 self.assertIn(g, posix.getgroups())
1487
1488 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1489 "test needs posix.setgroups()")
1490 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001491 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001492 posix.setgroups(groups)
1493 self.assertListEqual(groups, posix.getgroups())
1494
Serhiy Storchakaef347532018-05-01 16:45:04 +03001495
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001496class _PosixSpawnMixin:
1497 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001498 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001499 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001500
1501 def python_args(self, *args):
1502 # Disable site module to avoid side effects. For example,
1503 # on Fedora 28, if the HOME environment variable is not set,
1504 # site._getuserbase() calls pwd.getpwuid() which opens
1505 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1506 # test_close_file() to fail.
1507 return (sys.executable, '-I', '-S', *args)
1508
Serhiy Storchakaef347532018-05-01 16:45:04 +03001509 def test_returns_pid(self):
1510 pidfile = support.TESTFN
1511 self.addCleanup(support.unlink, pidfile)
1512 script = f"""if 1:
1513 import os
1514 with open({pidfile!r}, "w") as pidfile:
1515 pidfile.write(str(os.getpid()))
1516 """
Victor Stinner03824062018-08-30 01:21:11 +02001517 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001518 pid = self.spawn_func(args[0], args, os.environ)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001519 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1520 with open(pidfile) as f:
1521 self.assertEqual(f.read(), str(pid))
1522
1523 def test_no_such_executable(self):
1524 no_such_executable = 'no_such_executable'
1525 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001526 pid = self.spawn_func(no_such_executable,
1527 [no_such_executable],
1528 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001529 # bpo-35794: PermissionError can be raised if there are
1530 # directories in the $PATH that are not accessible.
1531 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001532 self.assertEqual(exc.filename, no_such_executable)
1533 else:
1534 pid2, status = os.waitpid(pid, 0)
1535 self.assertEqual(pid2, pid)
1536 self.assertNotEqual(status, 0)
1537
1538 def test_specify_environment(self):
1539 envfile = support.TESTFN
1540 self.addCleanup(support.unlink, envfile)
1541 script = f"""if 1:
1542 import os
1543 with open({envfile!r}, "w") as envfile:
1544 envfile.write(os.environ['foo'])
1545 """
Victor Stinner03824062018-08-30 01:21:11 +02001546 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001547 pid = self.spawn_func(args[0], args,
1548 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001549 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1550 with open(envfile) as f:
1551 self.assertEqual(f.read(), 'bar')
1552
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001553 def test_none_file_actions(self):
1554 pid = self.spawn_func(
1555 self.NOOP_PROGRAM[0],
1556 self.NOOP_PROGRAM,
1557 os.environ,
1558 file_actions=None
1559 )
1560 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1561
Serhiy Storchakaef347532018-05-01 16:45:04 +03001562 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001563 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001564 self.NOOP_PROGRAM[0],
1565 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001566 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001567 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001568 )
1569 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1570
Pablo Galindo254a4662018-09-07 16:44:24 +01001571 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001572 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001573 sys.executable,
1574 [sys.executable, '-c', 'pass'],
1575 os.environ,
1576 resetids=False
1577 )
1578 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1579
1580 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001581 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001582 sys.executable,
1583 [sys.executable, '-c', 'pass'],
1584 os.environ,
1585 resetids=True
1586 )
1587 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1588
1589 def test_resetids_wrong_type(self):
1590 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001591 self.spawn_func(sys.executable,
1592 [sys.executable, "-c", "pass"],
1593 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001594
1595 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001596 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001597 sys.executable,
1598 [sys.executable, '-c', 'pass'],
1599 os.environ,
1600 setpgroup=os.getpgrp()
1601 )
1602 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1603
1604 def test_setpgroup_wrong_type(self):
1605 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001606 self.spawn_func(sys.executable,
1607 [sys.executable, "-c", "pass"],
1608 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001609
1610 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1611 'need signal.pthread_sigmask()')
1612 def test_setsigmask(self):
1613 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001614 import signal
1615 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001616
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001617 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001618 sys.executable,
1619 [sys.executable, '-c', code],
1620 os.environ,
1621 setsigmask=[signal.SIGUSR1]
1622 )
1623 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1624
1625 def test_setsigmask_wrong_type(self):
1626 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001627 self.spawn_func(sys.executable,
1628 [sys.executable, "-c", "pass"],
1629 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001630 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001631 self.spawn_func(sys.executable,
1632 [sys.executable, "-c", "pass"],
1633 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001634 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001635 self.spawn_func(sys.executable,
1636 [sys.executable, "-c", "pass"],
1637 os.environ, setsigmask=[signal.NSIG,
1638 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001639
Victor Stinner1e39b83f2019-02-01 11:40:26 +01001640 @unittest.skipIf(True,
1641 "FIXME: bpo-35537: test fails is setsid is supported")
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001642 def test_start_new_session(self):
1643 # For code coverage of calling setsid(). We don't care if we get an
1644 # EPERM error from it depending on the test execution environment, that
1645 # still indicates that it was called.
1646 code = "import os; print(os.getpgid(os.getpid()))"
1647 try:
1648 self.spawn_func(sys.executable,
1649 [sys.executable, "-c", code],
1650 os.environ, setsid=True)
1651 except NotImplementedError as exc:
1652 self.skipTest("setsid is not supported: %s" % exc)
1653 else:
1654 parent_pgid = os.getpgid(os.getpid())
1655 child_pgid = int(output)
1656 self.assertNotEqual(parent_pgid, child_pgid)
1657
Pablo Galindo254a4662018-09-07 16:44:24 +01001658 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1659 'need signal.pthread_sigmask()')
1660 def test_setsigdef(self):
1661 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1662 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001663 import signal
1664 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001665 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001666 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001667 sys.executable,
1668 [sys.executable, '-c', code],
1669 os.environ,
1670 setsigdef=[signal.SIGUSR1]
1671 )
1672 finally:
1673 signal.signal(signal.SIGUSR1, original_handler)
1674
1675 pid2, status = os.waitpid(pid, 0)
1676 self.assertEqual(pid2, pid)
1677 self.assertTrue(os.WIFSIGNALED(status), status)
1678 self.assertEqual(os.WTERMSIG(status), signal.SIGUSR1)
1679
1680 def test_setsigdef_wrong_type(self):
1681 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001682 self.spawn_func(sys.executable,
1683 [sys.executable, "-c", "pass"],
1684 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001685 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001686 self.spawn_func(sys.executable,
1687 [sys.executable, "-c", "pass"],
1688 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001689 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001690 self.spawn_func(sys.executable,
1691 [sys.executable, "-c", "pass"],
1692 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001693
Benjamin Petersonc7042222018-09-12 15:12:24 -07001694 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001695 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1696 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001697 def test_setscheduler_only_param(self):
1698 policy = os.sched_getscheduler(0)
1699 priority = os.sched_get_priority_min(policy)
1700 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001701 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001702 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001703 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001704 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001705 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001706 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001707 sys.executable,
1708 [sys.executable, '-c', code],
1709 os.environ,
1710 scheduler=(None, os.sched_param(priority))
1711 )
1712 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1713
Benjamin Petersonc7042222018-09-12 15:12:24 -07001714 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001715 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1716 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001717 def test_setscheduler_with_policy(self):
1718 policy = os.sched_getscheduler(0)
1719 priority = os.sched_get_priority_min(policy)
1720 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001721 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001722 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001723 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001724 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001725 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001726 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001727 sys.executable,
1728 [sys.executable, '-c', code],
1729 os.environ,
1730 scheduler=(policy, os.sched_param(priority))
1731 )
1732 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1733
Serhiy Storchakaef347532018-05-01 16:45:04 +03001734 def test_multiple_file_actions(self):
1735 file_actions = [
1736 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1737 (os.POSIX_SPAWN_CLOSE, 0),
1738 (os.POSIX_SPAWN_DUP2, 1, 4),
1739 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001740 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1741 self.NOOP_PROGRAM,
1742 os.environ,
1743 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001744 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1745
1746 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001747 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001748 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001749 self.spawn_func(args[0], args, os.environ,
1750 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001751 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001752 self.spawn_func(args[0], args, os.environ,
1753 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001754 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001755 self.spawn_func(args[0], args, os.environ,
1756 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001757 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001758 self.spawn_func(args[0], args, os.environ,
1759 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001760 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001761 self.spawn_func(args[0], args, os.environ,
1762 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001763 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001764 self.spawn_func(args[0], args, os.environ,
1765 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001766 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001767 self.spawn_func(args[0], args, os.environ,
1768 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001769 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001770 self.spawn_func(args[0], args, os.environ,
1771 file_actions=[(os.POSIX_SPAWN_OPEN,
1772 3, __file__ + '\0',
1773 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001774
1775 def test_open_file(self):
1776 outfile = support.TESTFN
1777 self.addCleanup(support.unlink, outfile)
1778 script = """if 1:
1779 import sys
1780 sys.stdout.write("hello")
1781 """
1782 file_actions = [
1783 (os.POSIX_SPAWN_OPEN, 1, outfile,
1784 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1785 stat.S_IRUSR | stat.S_IWUSR),
1786 ]
Victor Stinner03824062018-08-30 01:21:11 +02001787 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001788 pid = self.spawn_func(args[0], args, os.environ,
1789 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001790 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1791 with open(outfile) as f:
1792 self.assertEqual(f.read(), 'hello')
1793
1794 def test_close_file(self):
1795 closefile = support.TESTFN
1796 self.addCleanup(support.unlink, closefile)
1797 script = f"""if 1:
1798 import os
1799 try:
1800 os.fstat(0)
1801 except OSError as e:
1802 with open({closefile!r}, 'w') as closefile:
1803 closefile.write('is closed %d' % e.errno)
1804 """
Victor Stinner03824062018-08-30 01:21:11 +02001805 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001806 pid = self.spawn_func(args[0], args, os.environ,
1807 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001808 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1809 with open(closefile) as f:
1810 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1811
1812 def test_dup2(self):
1813 dupfile = support.TESTFN
1814 self.addCleanup(support.unlink, dupfile)
1815 script = """if 1:
1816 import sys
1817 sys.stdout.write("hello")
1818 """
1819 with open(dupfile, "wb") as childfile:
1820 file_actions = [
1821 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1822 ]
Victor Stinner03824062018-08-30 01:21:11 +02001823 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001824 pid = self.spawn_func(args[0], args, os.environ,
1825 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001826 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1827 with open(dupfile) as f:
1828 self.assertEqual(f.read(), 'hello')
1829
1830
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001831@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1832class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1833 spawn_func = getattr(posix, 'posix_spawn', None)
1834
1835
1836@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1837class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1838 spawn_func = getattr(posix, 'posix_spawnp', None)
1839
1840 @support.skip_unless_symlink
1841 def test_posix_spawnp(self):
1842 # Use a symlink to create a program in its own temporary directory
1843 temp_dir = tempfile.mkdtemp()
1844 self.addCleanup(support.rmtree, temp_dir)
1845
1846 program = 'posix_spawnp_test_program.exe'
1847 program_fullpath = os.path.join(temp_dir, program)
1848 os.symlink(sys.executable, program_fullpath)
1849
1850 try:
1851 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1852 except KeyError:
1853 path = temp_dir # PATH is not set
1854
1855 spawn_args = (program, '-I', '-S', '-c', 'pass')
1856 code = textwrap.dedent("""
1857 import os
1858 args = %a
1859 pid = os.posix_spawnp(args[0], args, os.environ)
1860 pid2, status = os.waitpid(pid, 0)
1861 if pid2 != pid:
1862 raise Exception(f"pid {pid2} != {pid}")
1863 if status != 0:
1864 raise Exception(f"status {status} != 0")
1865 """ % (spawn_args,))
1866
1867 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1868 # environment variable: posix_spawnp() uses the current environment
1869 # to locate the program, not its environment argument.
1870 args = ('-c', code)
1871 assert_python_ok(*args, PATH=path)
1872
1873
Neal Norwitze241ce82003-02-17 18:17:05 +00001874def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001875 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001876 support.run_unittest(
1877 PosixTester,
1878 PosixGroupsTester,
1879 TestPosixSpawn,
1880 TestPosixSpawnP,
1881 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01001882 finally:
1883 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001884
1885if __name__ == '__main__':
1886 test_main()