blob: fe21b21b33854418e13642c1cd8f86ea80e235d7 [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))
313 finally:
314 os.close(fd)
315
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300316 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
317 @requires_32b
318 def test_preadv_overflow_32bits(self):
319 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
320 try:
321 buf = [bytearray(2**16)] * 2**15
322 with self.assertRaises(OSError) as cm:
323 os.preadv(fd, buf, 0)
324 self.assertEqual(cm.exception.errno, errno.EINVAL)
325 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
326 finally:
327 os.close(fd)
328
Ross Lagerwall7807c352011-03-17 20:20:30 +0200329 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
330 def test_pwrite(self):
331 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
332 try:
333 os.write(fd, b'test')
334 os.lseek(fd, 0, os.SEEK_SET)
335 posix.pwrite(fd, b'xx', 1)
336 self.assertEqual(b'txxt', posix.read(fd, 4))
337 finally:
338 os.close(fd)
339
Pablo Galindo4defba32018-01-27 16:16:37 +0000340 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
341 def test_pwritev(self):
342 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
343 try:
344 os.write(fd, b"xx")
345 os.lseek(fd, 0, os.SEEK_SET)
346 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
347 self.assertEqual(n, 10)
348
349 os.lseek(fd, 0, os.SEEK_SET)
350 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
351 finally:
352 os.close(fd)
353
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300354 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000355 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
356 def test_pwritev_flags(self):
357 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
358 try:
359 os.write(fd,b"xx")
360 os.lseek(fd, 0, os.SEEK_SET)
361 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
362 self.assertEqual(n, 10)
363
364 os.lseek(fd, 0, os.SEEK_SET)
365 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
366 finally:
367 os.close(fd)
368
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300369 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
370 @requires_32b
371 def test_pwritev_overflow_32bits(self):
372 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
373 try:
374 with self.assertRaises(OSError) as cm:
375 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
376 self.assertEqual(cm.exception.errno, errno.EINVAL)
377 finally:
378 os.close(fd)
379
Ross Lagerwall7807c352011-03-17 20:20:30 +0200380 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
381 "test needs posix.posix_fallocate()")
382 def test_posix_fallocate(self):
383 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
384 try:
385 posix.posix_fallocate(fd, 0, 10)
386 except OSError as inst:
387 # issue10812, ZFS doesn't appear to support posix_fallocate,
388 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400389 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
390 # often used there.
391 if inst.errno == errno.EINVAL and sys.platform.startswith(
392 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
393 raise unittest.SkipTest("test may fail on ZFS filesystems")
394 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200395 raise
396 finally:
397 os.close(fd)
398
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500399 # issue31106 - posix_fallocate() does not set error in errno.
400 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
401 "test needs posix.posix_fallocate()")
402 def test_posix_fallocate_errno(self):
403 try:
404 posix.posix_fallocate(-42, 0, 10)
405 except OSError as inst:
406 if inst.errno != errno.EBADF:
407 raise
408
Ross Lagerwall7807c352011-03-17 20:20:30 +0200409 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
410 "test needs posix.posix_fadvise()")
411 def test_posix_fadvise(self):
412 fd = os.open(support.TESTFN, os.O_RDONLY)
413 try:
414 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
415 finally:
416 os.close(fd)
417
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500418 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
419 "test needs posix.posix_fadvise()")
420 def test_posix_fadvise_errno(self):
421 try:
422 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
423 except OSError as inst:
424 if inst.errno != errno.EBADF:
425 raise
426
Larry Hastings9cf065c2012-06-22 16:30:09 -0700427 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
428 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200429 now = time.time()
430 fd = os.open(support.TESTFN, os.O_RDONLY)
431 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700432 posix.utime(fd)
433 posix.utime(fd, None)
434 self.assertRaises(TypeError, posix.utime, fd, (None, None))
435 self.assertRaises(TypeError, posix.utime, fd, (now, None))
436 self.assertRaises(TypeError, posix.utime, fd, (None, now))
437 posix.utime(fd, (int(now), int(now)))
438 posix.utime(fd, (now, now))
439 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
440 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
441 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
442 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
443 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
444
Ross Lagerwall7807c352011-03-17 20:20:30 +0200445 finally:
446 os.close(fd)
447
Larry Hastings9cf065c2012-06-22 16:30:09 -0700448 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
449 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200450 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700451 posix.utime(support.TESTFN, None, follow_symlinks=False)
452 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
453 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
454 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
455 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
456 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
457 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200458
459 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
460 def test_writev(self):
461 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
462 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100463 n = os.writev(fd, (b'test1', b'tt2', b't3'))
464 self.assertEqual(n, 10)
465
Ross Lagerwall7807c352011-03-17 20:20:30 +0200466 os.lseek(fd, 0, os.SEEK_SET)
467 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100468
469 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100470 try:
471 size = posix.writev(fd, [])
472 except OSError:
473 # writev(fd, []) raises OSError(22, "Invalid argument")
474 # on OpenIndiana
475 pass
476 else:
477 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200478 finally:
479 os.close(fd)
480
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300481 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
482 @requires_32b
483 def test_writev_overflow_32bits(self):
484 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
485 try:
486 with self.assertRaises(OSError) as cm:
487 os.writev(fd, [b"x" * 2**16] * 2**15)
488 self.assertEqual(cm.exception.errno, errno.EINVAL)
489 finally:
490 os.close(fd)
491
Ross Lagerwall7807c352011-03-17 20:20:30 +0200492 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
493 def test_readv(self):
494 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
495 try:
496 os.write(fd, b'test1tt2t3')
497 os.lseek(fd, 0, os.SEEK_SET)
498 buf = [bytearray(i) for i in [5, 3, 2]]
499 self.assertEqual(posix.readv(fd, buf), 10)
500 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100501
502 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100503 try:
504 size = posix.readv(fd, [])
505 except OSError:
506 # readv(fd, []) raises OSError(22, "Invalid argument")
507 # on OpenIndiana
508 pass
509 else:
510 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200511 finally:
512 os.close(fd)
513
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300514 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
515 @requires_32b
516 def test_readv_overflow_32bits(self):
517 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
518 try:
519 buf = [bytearray(2**16)] * 2**15
520 with self.assertRaises(OSError) as cm:
521 os.readv(fd, buf)
522 self.assertEqual(cm.exception.errno, errno.EINVAL)
523 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
524 finally:
525 os.close(fd)
526
Serhiy Storchaka43767632013-11-03 21:31:38 +0200527 @unittest.skipUnless(hasattr(posix, 'dup'),
528 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000529 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200530 fp = open(support.TESTFN)
531 try:
532 fd = posix.dup(fp.fileno())
533 self.assertIsInstance(fd, int)
534 os.close(fd)
535 finally:
536 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000537
Serhiy Storchaka43767632013-11-03 21:31:38 +0200538 @unittest.skipUnless(hasattr(posix, 'confstr'),
539 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000540 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200541 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
542 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000543
Serhiy Storchaka43767632013-11-03 21:31:38 +0200544 @unittest.skipUnless(hasattr(posix, 'dup2'),
545 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000546 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200547 fp1 = open(support.TESTFN)
548 fp2 = open(support.TESTFN)
549 try:
550 posix.dup2(fp1.fileno(), fp2.fileno())
551 finally:
552 fp1.close()
553 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000554
Charles-François Natali1e045b12011-05-22 20:42:32 +0200555 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200556 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200557 def test_oscloexec(self):
558 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
559 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200560 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200561
Serhiy Storchaka43767632013-11-03 21:31:38 +0200562 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
563 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000564 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200565 fd = os.open(support.TESTFN,
566 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
567 self.assertRaises(OSError, os.open, support.TESTFN,
568 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
569 os.close(fd)
570
571 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000572 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200573 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000574 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000575 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
576 os.close(fd)
577
Serhiy Storchaka43767632013-11-03 21:31:38 +0200578 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
579 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000580 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200581 fd1 = os.open(support.TESTFN,
582 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
583 fd2 = os.open(support.TESTFN,
584 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
585 os.close(fd2)
586 os.close(fd1)
587
588 if hasattr(posix, "O_EXLOCK"):
589 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000590 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200591 self.assertRaises(OSError, os.open, support.TESTFN,
592 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
593 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000594
Serhiy Storchaka43767632013-11-03 21:31:38 +0200595 @unittest.skipUnless(hasattr(posix, 'fstat'),
596 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000597 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200598 fp = open(support.TESTFN)
599 try:
600 self.assertTrue(posix.fstat(fp.fileno()))
601 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200602
Serhiy Storchaka43767632013-11-03 21:31:38 +0200603 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700604 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200605 posix.stat, float(fp.fileno()))
606 finally:
607 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000608
609 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200610 self.assertTrue(posix.stat(support.TESTFN))
611 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200612
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300613 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700614 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300615 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200616 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700617 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200618 posix.stat, None)
619 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700620 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200621 posix.stat, list(support.TESTFN))
622 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700623 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200624 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000625
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000626 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
627 def test_mkfifo(self):
628 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100629 try:
630 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
631 except PermissionError as e:
632 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000633 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
634
635 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
636 "don't have mknod()/S_IFIFO")
637 def test_mknod(self):
638 # Test using mknod() to create a FIFO (the only use specified
639 # by POSIX).
640 support.unlink(support.TESTFN)
641 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
642 try:
643 posix.mknod(support.TESTFN, mode, 0)
644 except OSError as e:
645 # Some old systems don't allow unprivileged users to use
646 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100647 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000648 else:
649 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
650
Martin Panterbf19d162015-09-09 01:01:13 +0000651 # Keyword arguments are also supported
652 support.unlink(support.TESTFN)
653 try:
654 posix.mknod(path=support.TESTFN, mode=mode, device=0,
655 dir_fd=None)
656 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100657 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000658
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300659 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
660 def test_makedev(self):
661 st = posix.stat(support.TESTFN)
662 dev = st.st_dev
663 self.assertIsInstance(dev, int)
664 self.assertGreaterEqual(dev, 0)
665
666 major = posix.major(dev)
667 self.assertIsInstance(major, int)
668 self.assertGreaterEqual(major, 0)
669 self.assertEqual(posix.major(dev), major)
670 self.assertRaises(TypeError, posix.major, float(dev))
671 self.assertRaises(TypeError, posix.major)
672 self.assertRaises((ValueError, OverflowError), posix.major, -1)
673
674 minor = posix.minor(dev)
675 self.assertIsInstance(minor, int)
676 self.assertGreaterEqual(minor, 0)
677 self.assertEqual(posix.minor(dev), minor)
678 self.assertRaises(TypeError, posix.minor, float(dev))
679 self.assertRaises(TypeError, posix.minor)
680 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
681
682 self.assertEqual(posix.makedev(major, minor), dev)
683 self.assertRaises(TypeError, posix.makedev, float(major), minor)
684 self.assertRaises(TypeError, posix.makedev, major, float(minor))
685 self.assertRaises(TypeError, posix.makedev, major)
686 self.assertRaises(TypeError, posix.makedev)
687
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200688 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000689 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200690 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 if stat_func is not None:
692 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200693 self.assertEqual(stat.st_uid, uid)
694 self.assertEqual(stat.st_gid, gid)
695 uid = os.getuid()
696 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200697 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200698 chown_func(first_param, uid, gid)
699 check_stat(uid, gid)
700 chown_func(first_param, -1, gid)
701 check_stat(uid, gid)
702 chown_func(first_param, uid, -1)
703 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200704
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200705 if uid == 0:
706 # Try an amusingly large uid/gid to make sure we handle
707 # large unsigned values. (chown lets you use any
708 # uid/gid you like, even if they aren't defined.)
709 #
710 # This problem keeps coming up:
711 # http://bugs.python.org/issue1747858
712 # http://bugs.python.org/issue4591
713 # http://bugs.python.org/issue15301
714 # Hopefully the fix in 4591 fixes it for good!
715 #
716 # This part of the test only runs when run as root.
717 # Only scary people run their tests as root.
718
719 big_value = 2**31
720 chown_func(first_param, big_value, big_value)
721 check_stat(big_value, big_value)
722 chown_func(first_param, -1, -1)
723 check_stat(big_value, big_value)
724 chown_func(first_param, uid, gid)
725 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200726 elif platform.system() in ('HP-UX', 'SunOS'):
727 # HP-UX and Solaris can allow a non-root user to chown() to root
728 # (issue #5113)
729 raise unittest.SkipTest("Skipping because of non-standard chown() "
730 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000731 else:
732 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200733 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200734 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200735 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200736 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200737 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200738 self.assertRaises(OSError, chown_func, first_param, -1, 0)
739 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200740 # test illegal types
741 for t in str, float:
742 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
743 check_stat(uid, gid)
744 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
745 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000746
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000747 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
748 def test_chown(self):
749 # raise an OSError if the file does not exist
750 os.unlink(support.TESTFN)
751 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000752
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000753 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200754 support.create_empty_file(support.TESTFN)
Anthony Sottile8377cd42019-02-25 14:32:27 -0800755 self._test_all_chown_common(posix.chown, support.TESTFN, posix.stat)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000756
757 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
758 def test_fchown(self):
759 os.unlink(support.TESTFN)
760
761 # re-create the file
762 test_file = open(support.TESTFN, 'w')
763 try:
764 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200765 self._test_all_chown_common(posix.fchown, fd,
766 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000767 finally:
768 test_file.close()
769
770 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
771 def test_lchown(self):
772 os.unlink(support.TESTFN)
773 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700774 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200775 self._test_all_chown_common(posix.lchown, support.TESTFN,
776 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000777
Serhiy Storchaka43767632013-11-03 21:31:38 +0200778 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000779 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200780 posix.chdir(os.curdir)
781 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000782
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000783 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300784 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000785
786 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700787 # When listdir is called without argument,
788 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300789 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000790
Larry Hastingsfdaea062012-06-25 04:42:23 -0700791 def test_listdir_bytes(self):
792 # When listdir is called with a bytes object,
793 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300794 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
795
796 def test_listdir_bytes_like(self):
797 for cls in bytearray, memoryview:
798 with self.assertWarns(DeprecationWarning):
799 names = posix.listdir(cls(b'.'))
800 self.assertIn(os.fsencode(support.TESTFN), names)
801 for name in names:
802 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700803
804 @unittest.skipUnless(posix.listdir in os.supports_fd,
805 "test needs fd support for posix.listdir()")
806 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000807 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100808 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000809 self.assertEqual(
810 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000812 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100813 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100814 self.assertEqual(
815 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100817 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000818
Serhiy Storchaka43767632013-11-03 21:31:38 +0200819 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000820 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200821 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000822
Serhiy Storchaka43767632013-11-03 21:31:38 +0200823 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000824 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200825 old_mask = posix.umask(0)
826 self.assertIsInstance(old_mask, int)
827 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000828
Serhiy Storchaka43767632013-11-03 21:31:38 +0200829 @unittest.skipUnless(hasattr(posix, 'strerror'),
830 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000831 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200832 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000833
Serhiy Storchaka43767632013-11-03 21:31:38 +0200834 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000835 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200836 reader, writer = posix.pipe()
837 os.close(reader)
838 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000839
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200840 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200841 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200842 def test_pipe2(self):
843 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
844 self.assertRaises(TypeError, os.pipe2, 0, 0)
845
Charles-François Natali368f34b2011-06-06 19:49:47 +0200846 # try calling with flags = 0, like os.pipe()
847 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200848 os.close(r)
849 os.close(w)
850
851 # test flags
852 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
853 self.addCleanup(os.close, r)
854 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200855 self.assertFalse(os.get_inheritable(r))
856 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200857 self.assertFalse(os.get_blocking(r))
858 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200859 # try reading from an empty pipe: this should fail, not block
860 self.assertRaises(OSError, os.read, r, 1)
861 # try a write big enough to fill-up the pipe: this should either
862 # fail or perform a partial write, not block
863 try:
864 os.write(w, b'x' * support.PIPE_MAX_SIZE)
865 except OSError:
866 pass
867
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200868 @support.cpython_only
869 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
870 @support.requires_linux_version(2, 6, 27)
871 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200872 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200873 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200874 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
875 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
876
Serhiy Storchaka43767632013-11-03 21:31:38 +0200877 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000878 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200879 now = time.time()
880 posix.utime(support.TESTFN, None)
881 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
882 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
883 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
884 posix.utime(support.TESTFN, (int(now), int(now)))
885 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000886
Larry Hastings9cf065c2012-06-22 16:30:09 -0700887 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700888 st = os.stat(target_file)
889 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000890
891 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
892 flags = st.st_flags | stat.UF_IMMUTABLE
893 try:
894 chflags_func(target_file, flags, **kwargs)
895 except OSError as err:
896 if err.errno != errno.EOPNOTSUPP:
897 raise
898 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
899 self.skipTest(msg)
900
Ned Deily3eb67d52011-06-28 00:00:28 -0700901 try:
902 new_st = os.stat(target_file)
903 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
904 try:
905 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200906 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700907 self.assertEqual(e.errno, errno.EPERM)
908 finally:
909 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000910
Ned Deily3eb67d52011-06-28 00:00:28 -0700911 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
912 def test_chflags(self):
913 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
914
915 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
916 def test_lchflags_regular_file(self):
917 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700918 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700919
920 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
921 def test_lchflags_symlink(self):
922 testfn_st = os.stat(support.TESTFN)
923
924 self.assertTrue(hasattr(testfn_st, 'st_flags'))
925
926 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
927 self.teardown_files.append(_DUMMY_SYMLINK)
928 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
929
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 def chflags_nofollow(path, flags):
931 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700932
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000934 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
935 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
936 try:
937 fn(_DUMMY_SYMLINK, flags)
938 except OSError as err:
939 if err.errno != errno.EOPNOTSUPP:
940 raise
941 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
942 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700943 try:
944 new_testfn_st = os.stat(support.TESTFN)
945 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
946
947 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
948 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
949 new_dummy_symlink_st.st_flags)
950 finally:
951 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000952
Guido van Rossum98297ee2007-11-06 21:34:58 +0000953 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000954 if os.name == "nt":
955 item_type = str
956 else:
957 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000958 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000959 self.assertEqual(type(k), item_type)
960 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000961
Serhiy Storchaka77703942017-06-25 07:33:01 +0300962 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
963 def test_putenv(self):
964 with self.assertRaises(ValueError):
965 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
966 with self.assertRaises(ValueError):
967 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
968 with self.assertRaises(ValueError):
969 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
970 with self.assertRaises(ValueError):
971 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
972 with self.assertRaises(ValueError):
973 os.putenv('FRUIT=ORANGE', 'lemon')
974 with self.assertRaises(ValueError):
975 os.putenv(b'FRUIT=ORANGE', b'lemon')
976
Serhiy Storchaka43767632013-11-03 21:31:38 +0200977 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000978 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500979 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
980 curdir = os.getcwd()
981 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000982
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500983 try:
984 os.mkdir(base_path)
985 os.chdir(base_path)
986 except:
987 # Just returning nothing instead of the SkipTest exception, because
988 # the test results in Error in that case. Is that ok?
989 # raise unittest.SkipTest("cannot create directory for testing")
990 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000991
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500992 def _create_and_do_getcwd(dirname, current_path_length = 0):
993 try:
994 os.mkdir(dirname)
995 except:
996 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000997
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500998 os.chdir(dirname)
999 try:
1000 os.getcwd()
1001 if current_path_length < 1027:
1002 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1003 finally:
1004 os.chdir('..')
1005 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001006
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001007 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001008
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001009 finally:
1010 os.chdir(curdir)
1011 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001012
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001013 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1014 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1015 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1016 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001017 user = pwd.getpwuid(os.getuid())[0]
1018 group = pwd.getpwuid(os.getuid())[3]
1019 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001020
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001021
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001022 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001023 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001024 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001025 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001026 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001027
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001028 try:
1029 idg_groups = set(int(g) for g in groups.split())
1030 except ValueError:
1031 idg_groups = set()
1032 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001033 raise unittest.SkipTest("need working 'id -G'")
1034
Ned Deily028915e2013-02-02 15:08:52 -08001035 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1036 if sys.platform == 'darwin':
1037 import sysconfig
1038 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001039 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001040 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1041
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001042 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001043 # groups, ignoring order, duplicates, and the effective gid.
1044 # #10822/#26944 - It is implementation defined whether
1045 # posix.getgroups() includes the effective gid.
1046 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1047 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001048
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001049 # tests for the posix *at functions follow
1050
Larry Hastings9cf065c2012-06-22 16:30:09 -07001051 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1052 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001053 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1054 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001056 finally:
1057 posix.close(f)
1058
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1060 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001061 os.chmod(support.TESTFN, stat.S_IRUSR)
1062
1063 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1064 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001066
1067 s = posix.stat(support.TESTFN)
1068 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1069 finally:
1070 posix.close(f)
1071
Larry Hastings9cf065c2012-06-22 16:30:09 -07001072 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1073 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001074 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001075 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001076
1077 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1078 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001080 finally:
1081 posix.close(f)
1082
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1084 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001085 support.unlink(support.TESTFN)
1086 with open(support.TESTFN, 'w') as outfile:
1087 outfile.write("testline\n")
1088
1089 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1090 try:
1091 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001092 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001093 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001094 s2 = posix.stat(support.TESTFN, dir_fd=None)
1095 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001096 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001097 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001098 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001099 posix.stat, support.TESTFN, dir_fd=float(f))
1100 self.assertRaises(OverflowError,
1101 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001102 finally:
1103 posix.close(f)
1104
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1106 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001107 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1108 try:
1109 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001110 posix.utime(support.TESTFN, None, dir_fd=f)
1111 posix.utime(support.TESTFN, dir_fd=f)
1112 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1113 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1114 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1115 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1116 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1117 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1118 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1119 posix.utime(support.TESTFN,
1120 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1121 posix.utime(support.TESTFN, dir_fd=f,
1122 times=(int(now), int((now - int(now)) * 1e9)))
1123
Larry Hastings90867a52012-06-22 17:01:41 -07001124 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001126 try:
1127 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001128 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001129 # whoops! using both together not supported on this platform.
1130 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001131
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001132 finally:
1133 posix.close(f)
1134
Larry Hastings9cf065c2012-06-22 16:30:09 -07001135 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1136 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001137 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1138 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001140 except PermissionError as e:
1141 self.skipTest('posix.link(): %s' % e)
1142 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001143 # should have same inodes
1144 self.assertEqual(posix.stat(support.TESTFN)[1],
1145 posix.stat(support.TESTFN + 'link')[1])
1146 finally:
1147 posix.close(f)
1148 support.unlink(support.TESTFN + 'link')
1149
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1151 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001152 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1153 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001155 posix.stat(support.TESTFN + 'dir') # should not raise exception
1156 finally:
1157 posix.close(f)
1158 support.rmtree(support.TESTFN + 'dir')
1159
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1161 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1162 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001163 # Test using mknodat() to create a FIFO (the only use specified
1164 # by POSIX).
1165 support.unlink(support.TESTFN)
1166 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1167 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1168 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001169 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001170 except OSError as e:
1171 # Some old systems don't allow unprivileged users to use
1172 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001173 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001174 else:
1175 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1176 finally:
1177 posix.close(f)
1178
Larry Hastings9cf065c2012-06-22 16:30:09 -07001179 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1180 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001181 support.unlink(support.TESTFN)
1182 with open(support.TESTFN, 'w') as outfile:
1183 outfile.write("testline\n")
1184 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001185 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001186 try:
1187 res = posix.read(b, 9).decode(encoding="utf-8")
1188 self.assertEqual("testline\n", res)
1189 finally:
1190 posix.close(a)
1191 posix.close(b)
1192
Larry Hastings9cf065c2012-06-22 16:30:09 -07001193 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1194 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001195 os.symlink(support.TESTFN, support.TESTFN + 'link')
1196 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1197 try:
1198 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001199 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001200 finally:
1201 support.unlink(support.TESTFN + 'link')
1202 posix.close(f)
1203
Larry Hastings9cf065c2012-06-22 16:30:09 -07001204 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1205 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001206 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001207 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001208 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1209 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001210 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001211 except:
1212 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1213 raise
1214 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001215 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001216 finally:
1217 posix.close(f)
1218
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1220 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001221 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1222 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001224 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1225 finally:
1226 posix.close(f)
1227 support.unlink(support.TESTFN + 'link')
1228
Larry Hastings9cf065c2012-06-22 16:30:09 -07001229 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1230 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001231 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001232 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001233 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001234 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001235 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001236 except:
1237 support.unlink(support.TESTFN + 'del')
1238 raise
1239 else:
1240 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1241 finally:
1242 posix.close(f)
1243
Larry Hastings9cf065c2012-06-22 16:30:09 -07001244 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1245 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001246 support.unlink(support.TESTFN)
1247 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1248 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001249 try:
1250 posix.mkfifo(support.TESTFN,
1251 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1252 except PermissionError as e:
1253 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001254 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1255 finally:
1256 posix.close(f)
1257
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001258 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1259 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001260 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001261 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001262
1263 @requires_sched_h
1264 def test_sched_yield(self):
1265 # This has no error conditions (at least on Linux).
1266 posix.sched_yield()
1267
1268 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001269 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1270 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001271 def test_sched_priority(self):
1272 # Round-robin usually has interesting priorities.
1273 pol = posix.SCHED_RR
1274 lo = posix.sched_get_priority_min(pol)
1275 hi = posix.sched_get_priority_max(pol)
1276 self.assertIsInstance(lo, int)
1277 self.assertIsInstance(hi, int)
1278 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001279 # OSX evidently just returns 15 without checking the argument.
1280 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001281 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1282 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001283
Benjamin Petersonc7042222018-09-12 15:12:24 -07001284 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001285 def test_get_and_set_scheduler_and_param(self):
1286 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1287 if name.startswith("SCHED_")]
1288 mine = posix.sched_getscheduler(0)
1289 self.assertIn(mine, possible_schedulers)
1290 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001291 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001292 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001293 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001294 raise
1295 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001296 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001297 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1298 self.assertRaises(OSError, posix.sched_getparam, -1)
1299 param = posix.sched_getparam(0)
1300 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001301
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001302 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1303 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1304 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1305 if not sys.platform.startswith(('freebsd', 'netbsd')):
1306 try:
1307 posix.sched_setscheduler(0, mine, param)
1308 posix.sched_setparam(0, param)
1309 except OSError as e:
1310 if e.errno != errno.EPERM:
1311 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001312 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1313
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001314 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1315 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1316 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1317 param = posix.sched_param(None)
1318 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1319 large = 214748364700
1320 param = posix.sched_param(large)
1321 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1322 param = posix.sched_param(sched_priority=-large)
1323 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1324
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001325 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001326 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001327 try:
1328 interval = posix.sched_rr_get_interval(0)
1329 except OSError as e:
1330 # This likely means that sched_rr_get_interval is only valid for
1331 # processes with the SCHED_RR scheduler in effect.
1332 if e.errno != errno.EINVAL:
1333 raise
1334 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001335 self.assertIsInstance(interval, float)
1336 # Reasonable constraints, I think.
1337 self.assertGreaterEqual(interval, 0.)
1338 self.assertLess(interval, 1.)
1339
Benjamin Peterson2740af82011-08-02 17:41:34 -05001340 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001341 def test_sched_getaffinity(self):
1342 mask = posix.sched_getaffinity(0)
1343 self.assertIsInstance(mask, set)
1344 self.assertGreaterEqual(len(mask), 1)
1345 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1346 for cpu in mask:
1347 self.assertIsInstance(cpu, int)
1348 self.assertGreaterEqual(cpu, 0)
1349 self.assertLess(cpu, 1 << 32)
1350
1351 @requires_sched_affinity
1352 def test_sched_setaffinity(self):
1353 mask = posix.sched_getaffinity(0)
1354 if len(mask) > 1:
1355 # Empty masks are forbidden
1356 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001357 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001358 self.assertEqual(posix.sched_getaffinity(0), mask)
1359 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1360 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1361 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001362 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1363
Victor Stinner8b905bd2011-10-25 13:34:04 +02001364 def test_rtld_constants(self):
1365 # check presence of major RTLD_* constants
1366 posix.RTLD_LAZY
1367 posix.RTLD_NOW
1368 posix.RTLD_GLOBAL
1369 posix.RTLD_LOCAL
1370
Jesus Cea60c13dd2012-06-23 02:58:14 +02001371 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1372 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001373 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001374 # Even if the filesystem doesn't report holes,
1375 # if the OS supports it the SEEK_* constants
1376 # will be defined and will have a consistent
1377 # behaviour:
1378 # os.SEEK_DATA = current position
1379 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001380 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001381 fp.write(b"hello")
1382 fp.flush()
1383 size = fp.tell()
1384 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001385 try :
1386 for i in range(size):
1387 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1388 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1389 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1390 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1391 except OSError :
1392 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1393 # but it is not true.
1394 # For instance:
1395 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1396 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001397
Larry Hastingsb0827312014-02-09 22:05:19 -08001398 def test_path_error2(self):
1399 """
1400 Test functions that call path_error2(), providing two filenames in their exceptions.
1401 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001402 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001403 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001404 if function is None:
1405 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001406
Victor Stinnerbed04a72014-10-05 17:37:59 +02001407 for dst in ("noodly2", support.TESTFN):
1408 try:
1409 function('doesnotexistfilename', dst)
1410 except OSError as e:
1411 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1412 break
1413 else:
1414 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001415
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001416 def test_path_with_null_character(self):
1417 fn = support.TESTFN
1418 fn_with_NUL = fn + '\0'
1419 self.addCleanup(support.unlink, fn)
1420 support.unlink(fn)
1421 fd = None
1422 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001423 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001424 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1425 finally:
1426 if fd is not None:
1427 os.close(fd)
1428 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001429 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001430 self.assertFalse(os.path.exists(fn))
1431 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001432 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001433
1434 def test_path_with_null_byte(self):
1435 fn = os.fsencode(support.TESTFN)
1436 fn_with_NUL = fn + b'\0'
1437 self.addCleanup(support.unlink, fn)
1438 support.unlink(fn)
1439 fd = None
1440 try:
1441 with self.assertRaises(ValueError):
1442 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1443 finally:
1444 if fd is not None:
1445 os.close(fd)
1446 self.assertFalse(os.path.exists(fn))
1447 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1448 self.assertFalse(os.path.exists(fn))
1449 open(fn, 'wb').close()
1450 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1451
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001452class PosixGroupsTester(unittest.TestCase):
1453
1454 def setUp(self):
1455 if posix.getuid() != 0:
1456 raise unittest.SkipTest("not enough privileges")
1457 if not hasattr(posix, 'getgroups'):
1458 raise unittest.SkipTest("need posix.getgroups")
1459 if sys.platform == 'darwin':
1460 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1461 self.saved_groups = posix.getgroups()
1462
1463 def tearDown(self):
1464 if hasattr(posix, 'setgroups'):
1465 posix.setgroups(self.saved_groups)
1466 elif hasattr(posix, 'initgroups'):
1467 name = pwd.getpwuid(posix.getuid()).pw_name
1468 posix.initgroups(name, self.saved_groups[0])
1469
1470 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1471 "test needs posix.initgroups()")
1472 def test_initgroups(self):
1473 # find missing group
1474
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001475 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001476 name = pwd.getpwuid(posix.getuid()).pw_name
1477 posix.initgroups(name, g)
1478 self.assertIn(g, posix.getgroups())
1479
1480 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1481 "test needs posix.setgroups()")
1482 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001483 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001484 posix.setgroups(groups)
1485 self.assertListEqual(groups, posix.getgroups())
1486
Serhiy Storchakaef347532018-05-01 16:45:04 +03001487
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001488class _PosixSpawnMixin:
1489 # Program which does nothing and exits with status 0 (success)
Victor Stinner03824062018-08-30 01:21:11 +02001490 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001491 spawn_func = None
Victor Stinner03824062018-08-30 01:21:11 +02001492
1493 def python_args(self, *args):
1494 # Disable site module to avoid side effects. For example,
1495 # on Fedora 28, if the HOME environment variable is not set,
1496 # site._getuserbase() calls pwd.getpwuid() which opens
1497 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1498 # test_close_file() to fail.
1499 return (sys.executable, '-I', '-S', *args)
1500
Serhiy Storchakaef347532018-05-01 16:45:04 +03001501 def test_returns_pid(self):
1502 pidfile = support.TESTFN
1503 self.addCleanup(support.unlink, pidfile)
1504 script = f"""if 1:
1505 import os
1506 with open({pidfile!r}, "w") as pidfile:
1507 pidfile.write(str(os.getpid()))
1508 """
Victor Stinner03824062018-08-30 01:21:11 +02001509 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001510 pid = self.spawn_func(args[0], args, os.environ)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001511 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1512 with open(pidfile) as f:
1513 self.assertEqual(f.read(), str(pid))
1514
1515 def test_no_such_executable(self):
1516 no_such_executable = 'no_such_executable'
1517 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001518 pid = self.spawn_func(no_such_executable,
1519 [no_such_executable],
1520 os.environ)
Pablo Galindoe9b185f2a2019-01-21 14:35:43 +00001521 # bpo-35794: PermissionError can be raised if there are
1522 # directories in the $PATH that are not accessible.
1523 except (FileNotFoundError, PermissionError) as exc:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001524 self.assertEqual(exc.filename, no_such_executable)
1525 else:
1526 pid2, status = os.waitpid(pid, 0)
1527 self.assertEqual(pid2, pid)
1528 self.assertNotEqual(status, 0)
1529
1530 def test_specify_environment(self):
1531 envfile = support.TESTFN
1532 self.addCleanup(support.unlink, envfile)
1533 script = f"""if 1:
1534 import os
1535 with open({envfile!r}, "w") as envfile:
1536 envfile.write(os.environ['foo'])
1537 """
Victor Stinner03824062018-08-30 01:21:11 +02001538 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001539 pid = self.spawn_func(args[0], args,
1540 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001541 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1542 with open(envfile) as f:
1543 self.assertEqual(f.read(), 'bar')
1544
1545 def test_empty_file_actions(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001546 pid = self.spawn_func(
Victor Stinner03824062018-08-30 01:21:11 +02001547 self.NOOP_PROGRAM[0],
1548 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001549 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001550 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001551 )
1552 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1553
Pablo Galindo254a4662018-09-07 16:44:24 +01001554 def test_resetids_explicit_default(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001555 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001556 sys.executable,
1557 [sys.executable, '-c', 'pass'],
1558 os.environ,
1559 resetids=False
1560 )
1561 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1562
1563 def test_resetids(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001564 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001565 sys.executable,
1566 [sys.executable, '-c', 'pass'],
1567 os.environ,
1568 resetids=True
1569 )
1570 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1571
1572 def test_resetids_wrong_type(self):
1573 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001574 self.spawn_func(sys.executable,
1575 [sys.executable, "-c", "pass"],
1576 os.environ, resetids=None)
Pablo Galindo254a4662018-09-07 16:44:24 +01001577
1578 def test_setpgroup(self):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001579 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001580 sys.executable,
1581 [sys.executable, '-c', 'pass'],
1582 os.environ,
1583 setpgroup=os.getpgrp()
1584 )
1585 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1586
1587 def test_setpgroup_wrong_type(self):
1588 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001589 self.spawn_func(sys.executable,
1590 [sys.executable, "-c", "pass"],
1591 os.environ, setpgroup="023")
Pablo Galindo254a4662018-09-07 16:44:24 +01001592
1593 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1594 'need signal.pthread_sigmask()')
1595 def test_setsigmask(self):
1596 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001597 import signal
1598 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001599
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001600 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001601 sys.executable,
1602 [sys.executable, '-c', code],
1603 os.environ,
1604 setsigmask=[signal.SIGUSR1]
1605 )
1606 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1607
1608 def test_setsigmask_wrong_type(self):
1609 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001610 self.spawn_func(sys.executable,
1611 [sys.executable, "-c", "pass"],
1612 os.environ, setsigmask=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001613 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001614 self.spawn_func(sys.executable,
1615 [sys.executable, "-c", "pass"],
1616 os.environ, setsigmask=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001617 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001618 self.spawn_func(sys.executable,
1619 [sys.executable, "-c", "pass"],
1620 os.environ, setsigmask=[signal.NSIG,
1621 signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001622
Victor Stinner1e39b83f2019-02-01 11:40:26 +01001623 @unittest.skipIf(True,
1624 "FIXME: bpo-35537: test fails is setsid is supported")
Joannah Nanjekye80c5dfe2019-02-01 13:05:22 +03001625 def test_start_new_session(self):
1626 # For code coverage of calling setsid(). We don't care if we get an
1627 # EPERM error from it depending on the test execution environment, that
1628 # still indicates that it was called.
1629 code = "import os; print(os.getpgid(os.getpid()))"
1630 try:
1631 self.spawn_func(sys.executable,
1632 [sys.executable, "-c", code],
1633 os.environ, setsid=True)
1634 except NotImplementedError as exc:
1635 self.skipTest("setsid is not supported: %s" % exc)
1636 else:
1637 parent_pgid = os.getpgid(os.getpid())
1638 child_pgid = int(output)
1639 self.assertNotEqual(parent_pgid, child_pgid)
1640
Pablo Galindo254a4662018-09-07 16:44:24 +01001641 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1642 'need signal.pthread_sigmask()')
1643 def test_setsigdef(self):
1644 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1645 code = textwrap.dedent("""\
Vladimir Matveevc24c6c22019-01-08 01:58:25 -08001646 import signal
1647 signal.raise_signal(signal.SIGUSR1)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001648 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001649 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001650 sys.executable,
1651 [sys.executable, '-c', code],
1652 os.environ,
1653 setsigdef=[signal.SIGUSR1]
1654 )
1655 finally:
1656 signal.signal(signal.SIGUSR1, original_handler)
1657
1658 pid2, status = os.waitpid(pid, 0)
1659 self.assertEqual(pid2, pid)
1660 self.assertTrue(os.WIFSIGNALED(status), status)
1661 self.assertEqual(os.WTERMSIG(status), signal.SIGUSR1)
1662
1663 def test_setsigdef_wrong_type(self):
1664 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001665 self.spawn_func(sys.executable,
1666 [sys.executable, "-c", "pass"],
1667 os.environ, setsigdef=34)
Pablo Galindo254a4662018-09-07 16:44:24 +01001668 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001669 self.spawn_func(sys.executable,
1670 [sys.executable, "-c", "pass"],
1671 os.environ, setsigdef=["j"])
Pablo Galindo254a4662018-09-07 16:44:24 +01001672 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001673 self.spawn_func(sys.executable,
1674 [sys.executable, "-c", "pass"],
1675 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
Pablo Galindo254a4662018-09-07 16:44:24 +01001676
Benjamin Petersonc7042222018-09-12 15:12:24 -07001677 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001678 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1679 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001680 def test_setscheduler_only_param(self):
1681 policy = os.sched_getscheduler(0)
1682 priority = os.sched_get_priority_min(policy)
1683 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001684 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001685 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001686 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001687 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001688 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001689 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001690 sys.executable,
1691 [sys.executable, '-c', code],
1692 os.environ,
1693 scheduler=(None, os.sched_param(priority))
1694 )
1695 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1696
Benjamin Petersonc7042222018-09-12 15:12:24 -07001697 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001698 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1699 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001700 def test_setscheduler_with_policy(self):
1701 policy = os.sched_getscheduler(0)
1702 priority = os.sched_get_priority_min(policy)
1703 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001704 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001705 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001706 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001707 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001708 sys.exit(102)""")
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001709 pid = self.spawn_func(
Pablo Galindo254a4662018-09-07 16:44:24 +01001710 sys.executable,
1711 [sys.executable, '-c', code],
1712 os.environ,
1713 scheduler=(policy, os.sched_param(priority))
1714 )
1715 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1716
Serhiy Storchakaef347532018-05-01 16:45:04 +03001717 def test_multiple_file_actions(self):
1718 file_actions = [
1719 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1720 (os.POSIX_SPAWN_CLOSE, 0),
1721 (os.POSIX_SPAWN_DUP2, 1, 4),
1722 ]
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001723 pid = self.spawn_func(self.NOOP_PROGRAM[0],
1724 self.NOOP_PROGRAM,
1725 os.environ,
1726 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001727 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1728
1729 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001730 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001731 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001732 self.spawn_func(args[0], args, os.environ,
1733 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001734 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001735 self.spawn_func(args[0], args, os.environ,
1736 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001737 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001738 self.spawn_func(args[0], args, os.environ,
1739 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001740 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001741 self.spawn_func(args[0], args, os.environ,
1742 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001743 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001744 self.spawn_func(args[0], args, os.environ,
1745 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001746 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001747 self.spawn_func(args[0], args, os.environ,
1748 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001749 with self.assertRaises(TypeError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001750 self.spawn_func(args[0], args, os.environ,
1751 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001752 with self.assertRaises(ValueError):
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001753 self.spawn_func(args[0], args, os.environ,
1754 file_actions=[(os.POSIX_SPAWN_OPEN,
1755 3, __file__ + '\0',
1756 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001757
1758 def test_open_file(self):
1759 outfile = support.TESTFN
1760 self.addCleanup(support.unlink, outfile)
1761 script = """if 1:
1762 import sys
1763 sys.stdout.write("hello")
1764 """
1765 file_actions = [
1766 (os.POSIX_SPAWN_OPEN, 1, outfile,
1767 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1768 stat.S_IRUSR | stat.S_IWUSR),
1769 ]
Victor Stinner03824062018-08-30 01:21:11 +02001770 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001771 pid = self.spawn_func(args[0], args, os.environ,
1772 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001773 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1774 with open(outfile) as f:
1775 self.assertEqual(f.read(), 'hello')
1776
1777 def test_close_file(self):
1778 closefile = support.TESTFN
1779 self.addCleanup(support.unlink, closefile)
1780 script = f"""if 1:
1781 import os
1782 try:
1783 os.fstat(0)
1784 except OSError as e:
1785 with open({closefile!r}, 'w') as closefile:
1786 closefile.write('is closed %d' % e.errno)
1787 """
Victor Stinner03824062018-08-30 01:21:11 +02001788 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001789 pid = self.spawn_func(args[0], args, os.environ,
1790 file_actions=[(os.POSIX_SPAWN_CLOSE, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001791 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1792 with open(closefile) as f:
1793 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1794
1795 def test_dup2(self):
1796 dupfile = support.TESTFN
1797 self.addCleanup(support.unlink, dupfile)
1798 script = """if 1:
1799 import sys
1800 sys.stdout.write("hello")
1801 """
1802 with open(dupfile, "wb") as childfile:
1803 file_actions = [
1804 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1805 ]
Victor Stinner03824062018-08-30 01:21:11 +02001806 args = self.python_args('-c', script)
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001807 pid = self.spawn_func(args[0], args, os.environ,
1808 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001809 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1810 with open(dupfile) as f:
1811 self.assertEqual(f.read(), 'hello')
1812
1813
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001814@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1815class TestPosixSpawn(unittest.TestCase, _PosixSpawnMixin):
1816 spawn_func = getattr(posix, 'posix_spawn', None)
1817
1818
1819@unittest.skipUnless(hasattr(os, 'posix_spawnp'), "test needs os.posix_spawnp")
1820class TestPosixSpawnP(unittest.TestCase, _PosixSpawnMixin):
1821 spawn_func = getattr(posix, 'posix_spawnp', None)
1822
1823 @support.skip_unless_symlink
1824 def test_posix_spawnp(self):
1825 # Use a symlink to create a program in its own temporary directory
1826 temp_dir = tempfile.mkdtemp()
1827 self.addCleanup(support.rmtree, temp_dir)
1828
1829 program = 'posix_spawnp_test_program.exe'
1830 program_fullpath = os.path.join(temp_dir, program)
1831 os.symlink(sys.executable, program_fullpath)
1832
1833 try:
1834 path = os.pathsep.join((temp_dir, os.environ['PATH']))
1835 except KeyError:
1836 path = temp_dir # PATH is not set
1837
1838 spawn_args = (program, '-I', '-S', '-c', 'pass')
1839 code = textwrap.dedent("""
1840 import os
1841 args = %a
1842 pid = os.posix_spawnp(args[0], args, os.environ)
1843 pid2, status = os.waitpid(pid, 0)
1844 if pid2 != pid:
1845 raise Exception(f"pid {pid2} != {pid}")
1846 if status != 0:
1847 raise Exception(f"status {status} != 0")
1848 """ % (spawn_args,))
1849
1850 # Use a subprocess to test os.posix_spawnp() with a modified PATH
1851 # environment variable: posix_spawnp() uses the current environment
1852 # to locate the program, not its environment argument.
1853 args = ('-c', code)
1854 assert_python_ok(*args, PATH=path)
1855
1856
Neal Norwitze241ce82003-02-17 18:17:05 +00001857def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001858 try:
Joannah Nanjekye92b83222019-01-16 16:29:26 +03001859 support.run_unittest(
1860 PosixTester,
1861 PosixGroupsTester,
1862 TestPosixSpawn,
1863 TestPosixSpawnP,
1864 )
Antoine Pitrou68c95922011-03-20 17:33:57 +01001865 finally:
1866 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001867
1868if __name__ == '__main__':
1869 test_main()