blob: 17e4ded2e2d6950fcd79b6ed1c43d9986b103a6d [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))
Benjamin Peterson44867bb2019-06-11 10:15:31 -0700313 except NotImplementedError:
314 self.skipTest("preadv2 not available")
Pablo Galindo46544f62019-04-13 17:06:03 +0100315 except OSError as inst:
316 # Is possible that the macro RWF_HIPRI was defined at compilation time
317 # but the option is not supported by the kernel or the runtime libc shared
318 # library.
319 if inst.errno in {errno.EINVAL, errno.ENOTSUP}:
320 raise unittest.SkipTest("RWF_HIPRI is not supported by the current system")
321 else:
322 raise
Pablo Galindo4defba32018-01-27 16:16:37 +0000323 finally:
324 os.close(fd)
325
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300326 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
327 @requires_32b
328 def test_preadv_overflow_32bits(self):
329 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
330 try:
331 buf = [bytearray(2**16)] * 2**15
332 with self.assertRaises(OSError) as cm:
333 os.preadv(fd, buf, 0)
334 self.assertEqual(cm.exception.errno, errno.EINVAL)
335 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
336 finally:
337 os.close(fd)
338
Ross Lagerwall7807c352011-03-17 20:20:30 +0200339 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
340 def test_pwrite(self):
341 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
342 try:
343 os.write(fd, b'test')
344 os.lseek(fd, 0, os.SEEK_SET)
345 posix.pwrite(fd, b'xx', 1)
346 self.assertEqual(b'txxt', posix.read(fd, 4))
347 finally:
348 os.close(fd)
349
Pablo Galindo4defba32018-01-27 16:16:37 +0000350 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
351 def test_pwritev(self):
352 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
353 try:
354 os.write(fd, b"xx")
355 os.lseek(fd, 0, os.SEEK_SET)
356 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
357 self.assertEqual(n, 10)
358
359 os.lseek(fd, 0, os.SEEK_SET)
360 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
361 finally:
362 os.close(fd)
363
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300364 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000365 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
366 def test_pwritev_flags(self):
367 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
368 try:
369 os.write(fd,b"xx")
370 os.lseek(fd, 0, os.SEEK_SET)
371 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
372 self.assertEqual(n, 10)
373
374 os.lseek(fd, 0, os.SEEK_SET)
375 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
376 finally:
377 os.close(fd)
378
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300379 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
380 @requires_32b
381 def test_pwritev_overflow_32bits(self):
382 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
383 try:
384 with self.assertRaises(OSError) as cm:
385 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
386 self.assertEqual(cm.exception.errno, errno.EINVAL)
387 finally:
388 os.close(fd)
389
Ross Lagerwall7807c352011-03-17 20:20:30 +0200390 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
391 "test needs posix.posix_fallocate()")
392 def test_posix_fallocate(self):
393 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
394 try:
395 posix.posix_fallocate(fd, 0, 10)
396 except OSError as inst:
397 # issue10812, ZFS doesn't appear to support posix_fallocate,
398 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400399 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
400 # often used there.
401 if inst.errno == errno.EINVAL and sys.platform.startswith(
402 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
403 raise unittest.SkipTest("test may fail on ZFS filesystems")
404 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200405 raise
406 finally:
407 os.close(fd)
408
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500409 # issue31106 - posix_fallocate() does not set error in errno.
410 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
411 "test needs posix.posix_fallocate()")
412 def test_posix_fallocate_errno(self):
413 try:
414 posix.posix_fallocate(-42, 0, 10)
415 except OSError as inst:
416 if inst.errno != errno.EBADF:
417 raise
418
Ross Lagerwall7807c352011-03-17 20:20:30 +0200419 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
420 "test needs posix.posix_fadvise()")
421 def test_posix_fadvise(self):
422 fd = os.open(support.TESTFN, os.O_RDONLY)
423 try:
424 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
425 finally:
426 os.close(fd)
427
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500428 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
429 "test needs posix.posix_fadvise()")
430 def test_posix_fadvise_errno(self):
431 try:
432 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
433 except OSError as inst:
434 if inst.errno != errno.EBADF:
435 raise
436
Larry Hastings9cf065c2012-06-22 16:30:09 -0700437 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
438 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200439 now = time.time()
440 fd = os.open(support.TESTFN, os.O_RDONLY)
441 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700442 posix.utime(fd)
443 posix.utime(fd, None)
444 self.assertRaises(TypeError, posix.utime, fd, (None, None))
445 self.assertRaises(TypeError, posix.utime, fd, (now, None))
446 self.assertRaises(TypeError, posix.utime, fd, (None, now))
447 posix.utime(fd, (int(now), int(now)))
448 posix.utime(fd, (now, now))
449 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
450 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
451 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
452 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
453 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
454
Ross Lagerwall7807c352011-03-17 20:20:30 +0200455 finally:
456 os.close(fd)
457
Larry Hastings9cf065c2012-06-22 16:30:09 -0700458 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
459 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200460 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700461 posix.utime(support.TESTFN, None, follow_symlinks=False)
462 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
463 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
464 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
465 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
466 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
467 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200468
469 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
470 def test_writev(self):
471 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
472 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100473 n = os.writev(fd, (b'test1', b'tt2', b't3'))
474 self.assertEqual(n, 10)
475
Ross Lagerwall7807c352011-03-17 20:20:30 +0200476 os.lseek(fd, 0, os.SEEK_SET)
477 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100478
479 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100480 try:
481 size = posix.writev(fd, [])
482 except OSError:
483 # writev(fd, []) raises OSError(22, "Invalid argument")
484 # on OpenIndiana
485 pass
486 else:
487 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200488 finally:
489 os.close(fd)
490
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300491 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
492 @requires_32b
493 def test_writev_overflow_32bits(self):
494 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
495 try:
496 with self.assertRaises(OSError) as cm:
497 os.writev(fd, [b"x" * 2**16] * 2**15)
498 self.assertEqual(cm.exception.errno, errno.EINVAL)
499 finally:
500 os.close(fd)
501
Ross Lagerwall7807c352011-03-17 20:20:30 +0200502 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
503 def test_readv(self):
504 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
505 try:
506 os.write(fd, b'test1tt2t3')
507 os.lseek(fd, 0, os.SEEK_SET)
508 buf = [bytearray(i) for i in [5, 3, 2]]
509 self.assertEqual(posix.readv(fd, buf), 10)
510 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100511
512 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100513 try:
514 size = posix.readv(fd, [])
515 except OSError:
516 # readv(fd, []) raises OSError(22, "Invalid argument")
517 # on OpenIndiana
518 pass
519 else:
520 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200521 finally:
522 os.close(fd)
523
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300524 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
525 @requires_32b
526 def test_readv_overflow_32bits(self):
527 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
528 try:
529 buf = [bytearray(2**16)] * 2**15
530 with self.assertRaises(OSError) as cm:
531 os.readv(fd, buf)
532 self.assertEqual(cm.exception.errno, errno.EINVAL)
533 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
534 finally:
535 os.close(fd)
536
Serhiy Storchaka43767632013-11-03 21:31:38 +0200537 @unittest.skipUnless(hasattr(posix, 'dup'),
538 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000539 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200540 fp = open(support.TESTFN)
541 try:
542 fd = posix.dup(fp.fileno())
543 self.assertIsInstance(fd, int)
544 os.close(fd)
545 finally:
546 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000547
Serhiy Storchaka43767632013-11-03 21:31:38 +0200548 @unittest.skipUnless(hasattr(posix, 'confstr'),
549 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000550 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200551 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
552 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000553
Serhiy Storchaka43767632013-11-03 21:31:38 +0200554 @unittest.skipUnless(hasattr(posix, 'dup2'),
555 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000556 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200557 fp1 = open(support.TESTFN)
558 fp2 = open(support.TESTFN)
559 try:
560 posix.dup2(fp1.fileno(), fp2.fileno())
561 finally:
562 fp1.close()
563 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000564
Charles-François Natali1e045b12011-05-22 20:42:32 +0200565 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200566 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200567 def test_oscloexec(self):
568 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
569 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200570 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200571
Serhiy Storchaka43767632013-11-03 21:31:38 +0200572 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
573 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000574 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200575 fd = os.open(support.TESTFN,
576 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
577 self.assertRaises(OSError, os.open, support.TESTFN,
578 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
579 os.close(fd)
580
581 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000582 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200583 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000584 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000585 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
586 os.close(fd)
587
Serhiy Storchaka43767632013-11-03 21:31:38 +0200588 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
589 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000590 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200591 fd1 = os.open(support.TESTFN,
592 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
593 fd2 = os.open(support.TESTFN,
594 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
595 os.close(fd2)
596 os.close(fd1)
597
598 if hasattr(posix, "O_EXLOCK"):
599 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000600 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200601 self.assertRaises(OSError, os.open, support.TESTFN,
602 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
603 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000604
Serhiy Storchaka43767632013-11-03 21:31:38 +0200605 @unittest.skipUnless(hasattr(posix, 'fstat'),
606 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000607 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200608 fp = open(support.TESTFN)
609 try:
610 self.assertTrue(posix.fstat(fp.fileno()))
611 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200612
Serhiy Storchaka43767632013-11-03 21:31:38 +0200613 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700614 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200615 posix.stat, float(fp.fileno()))
616 finally:
617 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000618
619 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200620 self.assertTrue(posix.stat(support.TESTFN))
621 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200622
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300623 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700624 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300625 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200626 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700627 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200628 posix.stat, None)
629 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700630 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200631 posix.stat, list(support.TESTFN))
632 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700633 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200634 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000635
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000636 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
637 def test_mkfifo(self):
638 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100639 try:
640 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
641 except PermissionError as e:
642 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000643 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
644
645 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
646 "don't have mknod()/S_IFIFO")
647 def test_mknod(self):
648 # Test using mknod() to create a FIFO (the only use specified
649 # by POSIX).
650 support.unlink(support.TESTFN)
651 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
652 try:
653 posix.mknod(support.TESTFN, mode, 0)
654 except OSError as e:
655 # Some old systems don't allow unprivileged users to use
656 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100657 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000658 else:
659 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
660
Martin Panterbf19d162015-09-09 01:01:13 +0000661 # Keyword arguments are also supported
662 support.unlink(support.TESTFN)
663 try:
664 posix.mknod(path=support.TESTFN, mode=mode, device=0,
665 dir_fd=None)
666 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100667 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000668
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300669 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
670 def test_makedev(self):
671 st = posix.stat(support.TESTFN)
672 dev = st.st_dev
673 self.assertIsInstance(dev, int)
674 self.assertGreaterEqual(dev, 0)
675
676 major = posix.major(dev)
677 self.assertIsInstance(major, int)
678 self.assertGreaterEqual(major, 0)
679 self.assertEqual(posix.major(dev), major)
680 self.assertRaises(TypeError, posix.major, float(dev))
681 self.assertRaises(TypeError, posix.major)
682 self.assertRaises((ValueError, OverflowError), posix.major, -1)
683
684 minor = posix.minor(dev)
685 self.assertIsInstance(minor, int)
686 self.assertGreaterEqual(minor, 0)
687 self.assertEqual(posix.minor(dev), minor)
688 self.assertRaises(TypeError, posix.minor, float(dev))
689 self.assertRaises(TypeError, posix.minor)
690 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
691
692 self.assertEqual(posix.makedev(major, minor), dev)
693 self.assertRaises(TypeError, posix.makedev, float(major), minor)
694 self.assertRaises(TypeError, posix.makedev, major, float(minor))
695 self.assertRaises(TypeError, posix.makedev, major)
696 self.assertRaises(TypeError, posix.makedev)
697
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200698 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000699 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200700 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200701 if stat_func is not None:
702 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200703 self.assertEqual(stat.st_uid, uid)
704 self.assertEqual(stat.st_gid, gid)
705 uid = os.getuid()
706 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200707 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200708 chown_func(first_param, uid, gid)
709 check_stat(uid, gid)
710 chown_func(first_param, -1, gid)
711 check_stat(uid, gid)
712 chown_func(first_param, uid, -1)
713 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200714
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200715 if uid == 0:
716 # Try an amusingly large uid/gid to make sure we handle
717 # large unsigned values. (chown lets you use any
718 # uid/gid you like, even if they aren't defined.)
719 #
720 # This problem keeps coming up:
721 # http://bugs.python.org/issue1747858
722 # http://bugs.python.org/issue4591
723 # http://bugs.python.org/issue15301
724 # Hopefully the fix in 4591 fixes it for good!
725 #
726 # This part of the test only runs when run as root.
727 # Only scary people run their tests as root.
728
729 big_value = 2**31
730 chown_func(first_param, big_value, big_value)
731 check_stat(big_value, big_value)
732 chown_func(first_param, -1, -1)
733 check_stat(big_value, big_value)
734 chown_func(first_param, uid, gid)
735 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200736 elif platform.system() in ('HP-UX', 'SunOS'):
737 # HP-UX and Solaris can allow a non-root user to chown() to root
738 # (issue #5113)
739 raise unittest.SkipTest("Skipping because of non-standard chown() "
740 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000741 else:
742 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200743 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200744 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200745 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200746 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200747 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200748 self.assertRaises(OSError, chown_func, first_param, -1, 0)
749 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200750 # test illegal types
751 for t in str, float:
752 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
753 check_stat(uid, gid)
754 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
755 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000756
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000757 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
758 def test_chown(self):
759 # raise an OSError if the file does not exist
760 os.unlink(support.TESTFN)
761 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000762
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000763 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200764 support.create_empty_file(support.TESTFN)
Anthony Sottile8377cd42019-02-25 14:32:27 -0800765 self._test_all_chown_common(posix.chown, support.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000766
767 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
768 def test_fchown(self):
769 os.unlink(support.TESTFN)
770
771 # re-create the file
772 test_file = open(support.TESTFN, 'w')
773 try:
774 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200775 self._test_all_chown_common(posix.fchown, fd,
776 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000777 finally:
778 test_file.close()
779
780 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
781 def test_lchown(self):
782 os.unlink(support.TESTFN)
783 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700784 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200785 self._test_all_chown_common(posix.lchown, support.TESTFN,
786 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000787
Serhiy Storchaka43767632013-11-03 21:31:38 +0200788 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000789 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200790 posix.chdir(os.curdir)
791 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000792
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000793 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300794 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000795
796 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700797 # When listdir is called without argument,
798 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300799 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000800
Larry Hastingsfdaea062012-06-25 04:42:23 -0700801 def test_listdir_bytes(self):
802 # When listdir is called with a bytes object,
803 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300804 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
805
806 def test_listdir_bytes_like(self):
807 for cls in bytearray, memoryview:
808 with self.assertWarns(DeprecationWarning):
809 names = posix.listdir(cls(b'.'))
810 self.assertIn(os.fsencode(support.TESTFN), names)
811 for name in names:
812 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700813
814 @unittest.skipUnless(posix.listdir in os.supports_fd,
815 "test needs fd support for posix.listdir()")
816 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000817 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100818 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000819 self.assertEqual(
820 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000822 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100823 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100824 self.assertEqual(
825 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100827 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000828
Serhiy Storchaka43767632013-11-03 21:31:38 +0200829 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000830 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200831 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000832
Serhiy Storchaka43767632013-11-03 21:31:38 +0200833 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000834 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200835 old_mask = posix.umask(0)
836 self.assertIsInstance(old_mask, int)
837 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000838
Serhiy Storchaka43767632013-11-03 21:31:38 +0200839 @unittest.skipUnless(hasattr(posix, 'strerror'),
840 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000841 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200842 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000843
Serhiy Storchaka43767632013-11-03 21:31:38 +0200844 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000845 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200846 reader, writer = posix.pipe()
847 os.close(reader)
848 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000849
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200850 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200851 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200852 def test_pipe2(self):
853 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
854 self.assertRaises(TypeError, os.pipe2, 0, 0)
855
Charles-François Natali368f34b2011-06-06 19:49:47 +0200856 # try calling with flags = 0, like os.pipe()
857 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200858 os.close(r)
859 os.close(w)
860
861 # test flags
862 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
863 self.addCleanup(os.close, r)
864 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200865 self.assertFalse(os.get_inheritable(r))
866 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200867 self.assertFalse(os.get_blocking(r))
868 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200869 # try reading from an empty pipe: this should fail, not block
870 self.assertRaises(OSError, os.read, r, 1)
871 # try a write big enough to fill-up the pipe: this should either
872 # fail or perform a partial write, not block
873 try:
874 os.write(w, b'x' * support.PIPE_MAX_SIZE)
875 except OSError:
876 pass
877
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200878 @support.cpython_only
879 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
880 @support.requires_linux_version(2, 6, 27)
881 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200882 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200883 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200884 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
885 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
886
Serhiy Storchaka43767632013-11-03 21:31:38 +0200887 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000888 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200889 now = time.time()
890 posix.utime(support.TESTFN, None)
891 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
892 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
893 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
894 posix.utime(support.TESTFN, (int(now), int(now)))
895 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000896
Larry Hastings9cf065c2012-06-22 16:30:09 -0700897 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700898 st = os.stat(target_file)
899 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000900
901 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
902 flags = st.st_flags | stat.UF_IMMUTABLE
903 try:
904 chflags_func(target_file, flags, **kwargs)
905 except OSError as err:
906 if err.errno != errno.EOPNOTSUPP:
907 raise
908 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
909 self.skipTest(msg)
910
Ned Deily3eb67d52011-06-28 00:00:28 -0700911 try:
912 new_st = os.stat(target_file)
913 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
914 try:
915 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200916 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700917 self.assertEqual(e.errno, errno.EPERM)
918 finally:
919 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000920
Ned Deily3eb67d52011-06-28 00:00:28 -0700921 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
922 def test_chflags(self):
923 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
924
925 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
926 def test_lchflags_regular_file(self):
927 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700929
930 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
931 def test_lchflags_symlink(self):
932 testfn_st = os.stat(support.TESTFN)
933
934 self.assertTrue(hasattr(testfn_st, 'st_flags'))
935
936 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
937 self.teardown_files.append(_DUMMY_SYMLINK)
938 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
939
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 def chflags_nofollow(path, flags):
941 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700942
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000944 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
945 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
946 try:
947 fn(_DUMMY_SYMLINK, flags)
948 except OSError as err:
949 if err.errno != errno.EOPNOTSUPP:
950 raise
951 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
952 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700953 try:
954 new_testfn_st = os.stat(support.TESTFN)
955 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
956
957 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
958 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
959 new_dummy_symlink_st.st_flags)
960 finally:
961 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000962
Guido van Rossum98297ee2007-11-06 21:34:58 +0000963 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000964 if os.name == "nt":
965 item_type = str
966 else:
967 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000968 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000969 self.assertEqual(type(k), item_type)
970 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000971
Serhiy Storchaka77703942017-06-25 07:33:01 +0300972 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
973 def test_putenv(self):
974 with self.assertRaises(ValueError):
975 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
976 with self.assertRaises(ValueError):
977 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
978 with self.assertRaises(ValueError):
979 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
980 with self.assertRaises(ValueError):
981 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
982 with self.assertRaises(ValueError):
983 os.putenv('FRUIT=ORANGE', 'lemon')
984 with self.assertRaises(ValueError):
985 os.putenv(b'FRUIT=ORANGE', b'lemon')
986
Serhiy Storchaka43767632013-11-03 21:31:38 +0200987 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000988 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500989 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
990 curdir = os.getcwd()
991 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000992
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500993 try:
994 os.mkdir(base_path)
995 os.chdir(base_path)
996 except:
997 # Just returning nothing instead of the SkipTest exception, because
998 # the test results in Error in that case. Is that ok?
999 # raise unittest.SkipTest("cannot create directory for testing")
1000 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001001
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001002 def _create_and_do_getcwd(dirname, current_path_length = 0):
1003 try:
1004 os.mkdir(dirname)
1005 except:
1006 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001007
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001008 os.chdir(dirname)
1009 try:
1010 os.getcwd()
1011 if current_path_length < 1027:
1012 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1013 finally:
1014 os.chdir('..')
1015 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001017 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001018
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001019 finally:
1020 os.chdir(curdir)
1021 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001022
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001023 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1024 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1025 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1026 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001027 user = pwd.getpwuid(os.getuid())[0]
1028 group = pwd.getpwuid(os.getuid())[3]
1029 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001030
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001031
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001032 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001033 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001034 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001035 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001036 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001037
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001038 try:
1039 idg_groups = set(int(g) for g in groups.split())
1040 except ValueError:
1041 idg_groups = set()
1042 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001043 raise unittest.SkipTest("need working 'id -G'")
1044
Ned Deily028915e2013-02-02 15:08:52 -08001045 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1046 if sys.platform == 'darwin':
1047 import sysconfig
1048 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001049 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001050 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1051
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001052 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001053 # groups, ignoring order, duplicates, and the effective gid.
1054 # #10822/#26944 - It is implementation defined whether
1055 # posix.getgroups() includes the effective gid.
1056 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1057 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001058
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001059 # tests for the posix *at functions follow
1060
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1062 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001063 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1064 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001066 finally:
1067 posix.close(f)
1068
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1070 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001071 os.chmod(support.TESTFN, stat.S_IRUSR)
1072
1073 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1074 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001076
1077 s = posix.stat(support.TESTFN)
1078 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1079 finally:
1080 posix.close(f)
1081
Larry Hastings9cf065c2012-06-22 16:30:09 -07001082 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1083 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001084 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001085 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001086
1087 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1088 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001089 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001090 finally:
1091 posix.close(f)
1092
Larry Hastings9cf065c2012-06-22 16:30:09 -07001093 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1094 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001095 support.unlink(support.TESTFN)
1096 with open(support.TESTFN, 'w') as outfile:
1097 outfile.write("testline\n")
1098
1099 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1100 try:
1101 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001102 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001103 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001104 s2 = posix.stat(support.TESTFN, dir_fd=None)
1105 self.assertEqual(s1, s2)
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=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001108 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001109 posix.stat, support.TESTFN, dir_fd=float(f))
1110 self.assertRaises(OverflowError,
1111 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001112 finally:
1113 posix.close(f)
1114
Larry Hastings9cf065c2012-06-22 16:30:09 -07001115 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1116 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001117 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1118 try:
1119 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001120 posix.utime(support.TESTFN, None, dir_fd=f)
1121 posix.utime(support.TESTFN, dir_fd=f)
1122 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1123 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1124 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1125 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1126 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1127 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1128 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1129 posix.utime(support.TESTFN,
1130 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1131 posix.utime(support.TESTFN, dir_fd=f,
1132 times=(int(now), int((now - int(now)) * 1e9)))
1133
Larry Hastings90867a52012-06-22 17:01:41 -07001134 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001135 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001136 try:
1137 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001138 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001139 # whoops! using both together not supported on this platform.
1140 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001142 finally:
1143 posix.close(f)
1144
Larry Hastings9cf065c2012-06-22 16:30:09 -07001145 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1146 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001147 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1148 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001149 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001150 except PermissionError as e:
1151 self.skipTest('posix.link(): %s' % e)
1152 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001153 # should have same inodes
1154 self.assertEqual(posix.stat(support.TESTFN)[1],
1155 posix.stat(support.TESTFN + 'link')[1])
1156 finally:
1157 posix.close(f)
1158 support.unlink(support.TESTFN + 'link')
1159
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1161 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001162 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1163 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001164 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001165 posix.stat(support.TESTFN + 'dir') # should not raise exception
1166 finally:
1167 posix.close(f)
1168 support.rmtree(support.TESTFN + 'dir')
1169
Larry Hastings9cf065c2012-06-22 16:30:09 -07001170 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1171 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1172 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001173 # Test using mknodat() to create a FIFO (the only use specified
1174 # by POSIX).
1175 support.unlink(support.TESTFN)
1176 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1177 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1178 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001179 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001180 except OSError as e:
1181 # Some old systems don't allow unprivileged users to use
1182 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001183 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001184 else:
1185 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1186 finally:
1187 posix.close(f)
1188
Larry Hastings9cf065c2012-06-22 16:30:09 -07001189 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1190 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001191 support.unlink(support.TESTFN)
1192 with open(support.TESTFN, 'w') as outfile:
1193 outfile.write("testline\n")
1194 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001195 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001196 try:
1197 res = posix.read(b, 9).decode(encoding="utf-8")
1198 self.assertEqual("testline\n", res)
1199 finally:
1200 posix.close(a)
1201 posix.close(b)
1202
Larry Hastings9cf065c2012-06-22 16:30:09 -07001203 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1204 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001205 os.symlink(support.TESTFN, support.TESTFN + 'link')
1206 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1207 try:
1208 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001209 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001210 finally:
1211 support.unlink(support.TESTFN + 'link')
1212 posix.close(f)
1213
Larry Hastings9cf065c2012-06-22 16:30:09 -07001214 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1215 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001216 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001217 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001218 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1219 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001220 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001221 except:
1222 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1223 raise
1224 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001225 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001226 finally:
1227 posix.close(f)
1228
Dong-hee Na2eba6ad2019-10-21 16:01:05 +09001229 @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal')
1230 @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result")
1231 def test_cld_xxxx_constants(self):
1232 os.CLD_EXITED
1233 os.CLD_KILLED
1234 os.CLD_DUMPED
1235 os.CLD_TRAPPED
1236 os.CLD_STOPPED
1237 os.CLD_CONTINUED
1238
Larry Hastings9cf065c2012-06-22 16:30:09 -07001239 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1240 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001241 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1242 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001243 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001244 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1245 finally:
1246 posix.close(f)
1247 support.unlink(support.TESTFN + 'link')
1248
Larry Hastings9cf065c2012-06-22 16:30:09 -07001249 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1250 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001251 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001252 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001253 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001254 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001256 except:
1257 support.unlink(support.TESTFN + 'del')
1258 raise
1259 else:
1260 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1261 finally:
1262 posix.close(f)
1263
Larry Hastings9cf065c2012-06-22 16:30:09 -07001264 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1265 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001266 support.unlink(support.TESTFN)
1267 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1268 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001269 try:
1270 posix.mkfifo(support.TESTFN,
1271 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1272 except PermissionError as e:
1273 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001274 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1275 finally:
1276 posix.close(f)
1277
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001278 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1279 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001280 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001281 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001282
1283 @requires_sched_h
1284 def test_sched_yield(self):
1285 # This has no error conditions (at least on Linux).
1286 posix.sched_yield()
1287
1288 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001289 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1290 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001291 def test_sched_priority(self):
1292 # Round-robin usually has interesting priorities.
1293 pol = posix.SCHED_RR
1294 lo = posix.sched_get_priority_min(pol)
1295 hi = posix.sched_get_priority_max(pol)
1296 self.assertIsInstance(lo, int)
1297 self.assertIsInstance(hi, int)
1298 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001299 # OSX evidently just returns 15 without checking the argument.
1300 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001301 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1302 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001303
Benjamin Petersonc7042222018-09-12 15:12:24 -07001304 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001305 def test_get_and_set_scheduler_and_param(self):
1306 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1307 if name.startswith("SCHED_")]
1308 mine = posix.sched_getscheduler(0)
1309 self.assertIn(mine, possible_schedulers)
1310 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001311 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001312 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001313 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001314 raise
1315 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001316 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001317 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1318 self.assertRaises(OSError, posix.sched_getparam, -1)
1319 param = posix.sched_getparam(0)
1320 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001321
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001322 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1323 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1324 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1325 if not sys.platform.startswith(('freebsd', 'netbsd')):
1326 try:
1327 posix.sched_setscheduler(0, mine, param)
1328 posix.sched_setparam(0, param)
1329 except OSError as e:
1330 if e.errno != errno.EPERM:
1331 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001332 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1333
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001334 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1335 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1336 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1337 param = posix.sched_param(None)
1338 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1339 large = 214748364700
1340 param = posix.sched_param(large)
1341 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1342 param = posix.sched_param(sched_priority=-large)
1343 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1344
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001345 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001346 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001347 try:
1348 interval = posix.sched_rr_get_interval(0)
1349 except OSError as e:
1350 # This likely means that sched_rr_get_interval is only valid for
1351 # processes with the SCHED_RR scheduler in effect.
1352 if e.errno != errno.EINVAL:
1353 raise
1354 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001355 self.assertIsInstance(interval, float)
1356 # Reasonable constraints, I think.
1357 self.assertGreaterEqual(interval, 0.)
1358 self.assertLess(interval, 1.)
1359
Benjamin Peterson2740af82011-08-02 17:41:34 -05001360 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001361 def test_sched_getaffinity(self):
1362 mask = posix.sched_getaffinity(0)
1363 self.assertIsInstance(mask, set)
1364 self.assertGreaterEqual(len(mask), 1)
1365 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1366 for cpu in mask:
1367 self.assertIsInstance(cpu, int)
1368 self.assertGreaterEqual(cpu, 0)
1369 self.assertLess(cpu, 1 << 32)
1370
1371 @requires_sched_affinity
1372 def test_sched_setaffinity(self):
1373 mask = posix.sched_getaffinity(0)
1374 if len(mask) > 1:
1375 # Empty masks are forbidden
1376 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001377 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001378 self.assertEqual(posix.sched_getaffinity(0), mask)
1379 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1380 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
Brandt Bucher45a30af2019-06-27 09:10:57 -07001381 self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X"))
Antoine Pitrou84869872012-08-04 16:16:35 +02001382 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001383 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1384
Victor Stinner8b905bd2011-10-25 13:34:04 +02001385 def test_rtld_constants(self):
1386 # check presence of major RTLD_* constants
1387 posix.RTLD_LAZY
1388 posix.RTLD_NOW
1389 posix.RTLD_GLOBAL
1390 posix.RTLD_LOCAL
1391
Jesus Cea60c13dd2012-06-23 02:58:14 +02001392 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1393 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001394 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001395 # Even if the filesystem doesn't report holes,
1396 # if the OS supports it the SEEK_* constants
1397 # will be defined and will have a consistent
1398 # behaviour:
1399 # os.SEEK_DATA = current position
1400 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001401 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001402 fp.write(b"hello")
1403 fp.flush()
1404 size = fp.tell()
1405 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001406 try :
1407 for i in range(size):
1408 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1409 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1410 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1411 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1412 except OSError :
1413 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1414 # but it is not true.
1415 # For instance:
1416 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1417 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001418
Larry Hastingsb0827312014-02-09 22:05:19 -08001419 def test_path_error2(self):
1420 """
1421 Test functions that call path_error2(), providing two filenames in their exceptions.
1422 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001423 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001424 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001425 if function is None:
1426 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001427
Victor Stinnerbed04a72014-10-05 17:37:59 +02001428 for dst in ("noodly2", support.TESTFN):
1429 try:
1430 function('doesnotexistfilename', dst)
1431 except OSError as e:
1432 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1433 break
1434 else:
1435 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001436
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001437 def test_path_with_null_character(self):
1438 fn = support.TESTFN
1439 fn_with_NUL = fn + '\0'
1440 self.addCleanup(support.unlink, fn)
1441 support.unlink(fn)
1442 fd = None
1443 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001444 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001445 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1446 finally:
1447 if fd is not None:
1448 os.close(fd)
1449 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001450 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001451 self.assertFalse(os.path.exists(fn))
1452 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001453 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001454
1455 def test_path_with_null_byte(self):
1456 fn = os.fsencode(support.TESTFN)
1457 fn_with_NUL = fn + b'\0'
1458 self.addCleanup(support.unlink, fn)
1459 support.unlink(fn)
1460 fd = None
1461 try:
1462 with self.assertRaises(ValueError):
1463 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1464 finally:
1465 if fd is not None:
1466 os.close(fd)
1467 self.assertFalse(os.path.exists(fn))
1468 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1469 self.assertFalse(os.path.exists(fn))
1470 open(fn, 'wb').close()
1471 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1472
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001473class PosixGroupsTester(unittest.TestCase):
1474
1475 def setUp(self):
1476 if posix.getuid() != 0:
1477 raise unittest.SkipTest("not enough privileges")
1478 if not hasattr(posix, 'getgroups'):
1479 raise unittest.SkipTest("need posix.getgroups")
1480 if sys.platform == 'darwin':
1481 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1482 self.saved_groups = posix.getgroups()
1483
1484 def tearDown(self):
1485 if hasattr(posix, 'setgroups'):
1486 posix.setgroups(self.saved_groups)
1487 elif hasattr(posix, 'initgroups'):
1488 name = pwd.getpwuid(posix.getuid()).pw_name
1489 posix.initgroups(name, self.saved_groups[0])
1490
1491 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1492 "test needs posix.initgroups()")
1493 def test_initgroups(self):
1494 # find missing group
1495
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001496 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001497 name = pwd.getpwuid(posix.getuid()).pw_name
1498 posix.initgroups(name, g)
1499 self.assertIn(g, posix.getgroups())
1500
1501 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1502 "test needs posix.setgroups()")
1503 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001504 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001505 posix.setgroups(groups)
1506 self.assertListEqual(groups, posix.getgroups())
1507
Serhiy Storchakaef347532018-05-01 16:45:04 +03001508
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001509class _PosixSpawnMixin:
1510 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001511 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001512 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001513
1514 def python_args(self, *args):
1515 # Disable site module to avoid side effects. For example,
1516 # on Fedora 28, if the HOME environment variable is not set,
1517 # site._getuserbase() calls pwd.getpwuid() which opens
1518 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1519 # test_close_file() to fail.
1520 return (sys.executable, '-I', '-S', *args)
1521
Serhiy Storchakaef347532018-05-01 16:45:04 +03001522 def test_returns_pid(self):
1523 pidfile = support.TESTFN
1524 self.addCleanup(support.unlink, pidfile)
1525 script = f"""if 1:
1526 import os
1527 with open({pidfile!r}, "w") as pidfile:
1528 pidfile.write(str(os.getpid()))
1529 """
Victor Stinner03824062018-08-30 01:21:11 +02001530 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001531 pid = self.spawn_func(args[0], args, os.environ)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001532 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1533 with open(pidfile) as f:
1534 self.assertEqual(f.read(), str(pid))
1535
1536 def test_no_such_executable(self):
1537 no_such_executable = 'no_such_executable'
1538 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001539 pid = self.spawn_func(no_such_executable,
1540 [no_such_executable],
1541 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001542 # bpo-35794: PermissionError can be raised if there are
1543 # directories in the $PATH that are not accessible.
1544 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001545 self.assertEqual(exc.filename, no_such_executable)
1546 else:
1547 pid2, status = os.waitpid(pid, 0)
1548 self.assertEqual(pid2, pid)
1549 self.assertNotEqual(status, 0)
1550
1551 def test_specify_environment(self):
1552 envfile = support.TESTFN
1553 self.addCleanup(support.unlink, envfile)
1554 script = f"""if 1:
1555 import os
1556 with open({envfile!r}, "w") as envfile:
1557 envfile.write(os.environ['foo'])
1558 """
Victor Stinner03824062018-08-30 01:21:11 +02001559 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001560 pid = self.spawn_func(args[0], args,
1561 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001562 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1563 with open(envfile) as f:
1564 self.assertEqual(f.read(), 'bar')
1565
Anthony Shaw948ed8c2019-05-10 12:00:06 +10001566 def test_none_file_actions(self):
1567 pid = self.spawn_func(
1568 self.NOOP_PROGRAM[0],
1569 self.NOOP_PROGRAM,
1570 os.environ,
1571 file_actions=None
1572 )
1573 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1574
Serhiy Storchakaef347532018-05-01 16:45:04 +03001575 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001576 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001577 self.NOOP_PROGRAM[0],
1578 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001579 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001580 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001581 )
1582 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1583
Pablo Galindo254a4662018-09-07 16:44:24 +01001584 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001585 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001586 sys.executable,
1587 [sys.executable, '-c', 'pass'],
1588 os.environ,
1589 resetids=False
1590 )
1591 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1592
1593 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001594 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001595 sys.executable,
1596 [sys.executable, '-c', 'pass'],
1597 os.environ,
1598 resetids=True
1599 )
1600 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1601
1602 def test_resetids_wrong_type(self):
1603 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001604 self.spawn_func(sys.executable,
1605 [sys.executable, "-c", "pass"],
1606 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001607
1608 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001609 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001610 sys.executable,
1611 [sys.executable, '-c', 'pass'],
1612 os.environ,
1613 setpgroup=os.getpgrp()
1614 )
1615 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1616
1617 def test_setpgroup_wrong_type(self):
1618 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001619 self.spawn_func(sys.executable,
1620 [sys.executable, "-c", "pass"],
1621 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001622
1623 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1624 'need signal.pthread_sigmask()')
1625 def test_setsigmask(self):
1626 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001627 import signal
1628 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001629
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001630 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001631 sys.executable,
1632 [sys.executable, '-c', code],
1633 os.environ,
1634 setsigmask=[signal.SIGUSR1]
1635 )
1636 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1637
1638 def test_setsigmask_wrong_type(self):
1639 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001640 self.spawn_func(sys.executable,
1641 [sys.executable, "-c", "pass"],
1642 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001643 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001644 self.spawn_func(sys.executable,
1645 [sys.executable, "-c", "pass"],
1646 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001647 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001648 self.spawn_func(sys.executable,
1649 [sys.executable, "-c", "pass"],
1650 os.environ, setsigmask=[signal.NSIG,
1651 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001652
Victor Stinner58840432019-06-14 19:31:43 +02001653 def test_setsid(self):
1654 rfd, wfd = os.pipe()
1655 self.addCleanup(os.close, rfd)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001656 try:
Victor Stinner58840432019-06-14 19:31:43 +02001657 os.set_inheritable(wfd, True)
1658
1659 code = textwrap.dedent(f"""
1660 import os
1661 fd = {wfd}
1662 sid = os.getsid(0)
1663 os.write(fd, str(sid).encode())
1664 """)
1665
1666 try:
1667 pid = self.spawn_func(sys.executable,
1668 [sys.executable, "-c", code],
1669 os.environ, setsid=True)
1670 except NotImplementedError as exc:
1671 self.skipTest(f"setsid is not supported: {exc!r}")
1672 except PermissionError as exc:
1673 self.skipTest(f"setsid failed with: {exc!r}")
1674 finally:
1675 os.close(wfd)
1676
1677 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1678 output = os.read(rfd, 100)
1679 child_sid = int(output)
1680 parent_sid = os.getsid(os.getpid())
1681 self.assertNotEqual(parent_sid, child_sid)
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001682
Pablo Galindo254a4662018-09-07 16:44:24 +01001683 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1684 'need signal.pthread_sigmask()')
1685 def test_setsigdef(self):
1686 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1687 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001688 import signal
1689 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001690 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001691 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001692 sys.executable,
1693 [sys.executable, '-c', code],
1694 os.environ,
1695 setsigdef=[signal.SIGUSR1]
1696 )
1697 finally:
1698 signal.signal(signal.SIGUSR1, original_handler)
1699
1700 pid2, status = os.waitpid(pid, 0)
1701 self.assertEqual(pid2, pid)
1702 self.assertTrue(os.WIFSIGNALED(status), status)
1703 self.assertEqual(os.WTERMSIG(status), signal.SIGUSR1)
1704
1705 def test_setsigdef_wrong_type(self):
1706 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001707 self.spawn_func(sys.executable,
1708 [sys.executable, "-c", "pass"],
1709 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001710 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001711 self.spawn_func(sys.executable,
1712 [sys.executable, "-c", "pass"],
1713 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001714 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001715 self.spawn_func(sys.executable,
1716 [sys.executable, "-c", "pass"],
1717 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001718
Benjamin Petersonc7042222018-09-12 15:12:24 -07001719 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001720 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1721 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001722 def test_setscheduler_only_param(self):
1723 policy = os.sched_getscheduler(0)
1724 priority = os.sched_get_priority_min(policy)
1725 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001726 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001727 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001728 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001729 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001730 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001731 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001732 sys.executable,
1733 [sys.executable, '-c', code],
1734 os.environ,
1735 scheduler=(None, os.sched_param(priority))
1736 )
1737 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1738
Benjamin Petersonc7042222018-09-12 15:12:24 -07001739 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001740 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1741 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001742 def test_setscheduler_with_policy(self):
1743 policy = os.sched_getscheduler(0)
1744 priority = os.sched_get_priority_min(policy)
1745 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001746 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001747 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001748 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001749 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001750 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001751 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001752 sys.executable,
1753 [sys.executable, '-c', code],
1754 os.environ,
1755 scheduler=(policy, os.sched_param(priority))
1756 )
1757 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1758
Serhiy Storchakaef347532018-05-01 16:45:04 +03001759 def test_multiple_file_actions(self):
1760 file_actions = [
1761 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1762 (os.POSIX_SPAWN_CLOSE, 0),
1763 (os.POSIX_SPAWN_DUP2, 1, 4),
1764 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001765 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1766 self.NOOP_PROGRAM,
1767 os.environ,
1768 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001769 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1770
1771 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001772 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001773 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001774 self.spawn_func(args[0], args, os.environ,
1775 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001776 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001777 self.spawn_func(args[0], args, os.environ,
1778 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001779 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001780 self.spawn_func(args[0], args, os.environ,
1781 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001782 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001783 self.spawn_func(args[0], args, os.environ,
1784 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001785 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001786 self.spawn_func(args[0], args, os.environ,
1787 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001788 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001789 self.spawn_func(args[0], args, os.environ,
1790 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001791 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001792 self.spawn_func(args[0], args, os.environ,
1793 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001794 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001795 self.spawn_func(args[0], args, os.environ,
1796 file_actions=[(os.POSIX_SPAWN_OPEN,
1797 3, __file__ + '\0',
1798 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001799
1800 def test_open_file(self):
1801 outfile = support.TESTFN
1802 self.addCleanup(support.unlink, outfile)
1803 script = """if 1:
1804 import sys
1805 sys.stdout.write("hello")
1806 """
1807 file_actions = [
1808 (os.POSIX_SPAWN_OPEN, 1, outfile,
1809 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1810 stat.S_IRUSR | stat.S_IWUSR),
1811 ]
Victor Stinner03824062018-08-30 01:21:11 +02001812 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001813 pid = self.spawn_func(args[0], args, os.environ,
1814 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001815 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1816 with open(outfile) as f:
1817 self.assertEqual(f.read(), 'hello')
1818
1819 def test_close_file(self):
1820 closefile = support.TESTFN
1821 self.addCleanup(support.unlink, closefile)
1822 script = f"""if 1:
1823 import os
1824 try:
1825 os.fstat(0)
1826 except OSError as e:
1827 with open({closefile!r}, 'w') as closefile:
1828 closefile.write('is closed %d' % e.errno)
1829 """
Victor Stinner03824062018-08-30 01:21:11 +02001830 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001831 pid = self.spawn_func(args[0], args, os.environ,
1832 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001833 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1834 with open(closefile) as f:
1835 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1836
1837 def test_dup2(self):
1838 dupfile = support.TESTFN
1839 self.addCleanup(support.unlink, dupfile)
1840 script = """if 1:
1841 import sys
1842 sys.stdout.write("hello")
1843 """
1844 with open(dupfile, "wb") as childfile:
1845 file_actions = [
1846 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1847 ]
Victor Stinner03824062018-08-30 01:21:11 +02001848 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001849 pid = self.spawn_func(args[0], args, os.environ,
1850 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001851 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1852 with open(dupfile) as f:
1853 self.assertEqual(f.read(), 'hello')
1854
1855
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001856@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1857class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1858 spawn_func = getattr(posix, 'posix_spawn', None)
1859
1860
1861@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1862class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1863 spawn_func = getattr(posix, 'posix_spawnp', None)
1864
1865 @support.skip_unless_symlink
1866 def test_posix_spawnp(self):
1867 # Use a symlink to create a program in its own temporary directory
1868 temp_dir = tempfile.mkdtemp()
1869 self.addCleanup(support.rmtree, temp_dir)
1870
1871 program = 'posix_spawnp_test_program.exe'
1872 program_fullpath = os.path.join(temp_dir, program)
1873 os.symlink(sys.executable, program_fullpath)
1874
1875 try:
1876 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1877 except KeyError:
1878 path = temp_dir # PATH is not set
1879
1880 spawn_args = (program, '-I', '-S', '-c', 'pass')
1881 code = textwrap.dedent("""
1882 import os
1883 args = %a
1884 pid = os.posix_spawnp(args[0], args, os.environ)
1885 pid2, status = os.waitpid(pid, 0)
1886 if pid2 != pid:
1887 raise Exception(f"pid {pid2} != {pid}")
1888 if status != 0:
1889 raise Exception(f"status {status} != 0")
1890 """ % (spawn_args,))
1891
1892 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1893 # environment variable: posix_spawnp() uses the current environment
1894 # to locate the program, not its environment argument.
1895 args = ('-c', code)
1896 assert_python_ok(*args, PATH=path)
1897
1898
Neal Norwitze241ce82003-02-17 18:17:05 +00001899def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001900 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001901 support.run_unittest(
1902 PosixTester,
1903 PosixGroupsTester,
1904 TestPosixSpawn,
1905 TestPosixSpawnP,
1906 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01001907 finally:
1908 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001909
1910if __name__ == '__main__':
1911 test_main()