blob: 86c04b9f324a6c790c9919615523842c3bd11d7f [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
Serhiy Storchaka43767632013-11-03 21:31:38 +0200609 @unittest.skipUnless(hasattr(posix, 'stat'),
610 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000611 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200612 self.assertTrue(posix.stat(support.TESTFN))
613 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200614
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300615 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700616 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300617 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200618 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700619 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200620 posix.stat, None)
621 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700622 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200623 posix.stat, list(support.TESTFN))
624 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700625 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200626 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000627
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000628 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
629 def test_mkfifo(self):
630 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100631 try:
632 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
633 except PermissionError as e:
634 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000635 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
636
637 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
638 "don't have mknod()/S_IFIFO")
639 def test_mknod(self):
640 # Test using mknod() to create a FIFO (the only use specified
641 # by POSIX).
642 support.unlink(support.TESTFN)
643 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
644 try:
645 posix.mknod(support.TESTFN, mode, 0)
646 except OSError as e:
647 # Some old systems don't allow unprivileged users to use
648 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100649 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000650 else:
651 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
652
Martin Panterbf19d162015-09-09 01:01:13 +0000653 # Keyword arguments are also supported
654 support.unlink(support.TESTFN)
655 try:
656 posix.mknod(path=support.TESTFN, mode=mode, device=0,
657 dir_fd=None)
658 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100659 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000660
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300661 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
662 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
663 def test_makedev(self):
664 st = posix.stat(support.TESTFN)
665 dev = st.st_dev
666 self.assertIsInstance(dev, int)
667 self.assertGreaterEqual(dev, 0)
668
669 major = posix.major(dev)
670 self.assertIsInstance(major, int)
671 self.assertGreaterEqual(major, 0)
672 self.assertEqual(posix.major(dev), major)
673 self.assertRaises(TypeError, posix.major, float(dev))
674 self.assertRaises(TypeError, posix.major)
675 self.assertRaises((ValueError, OverflowError), posix.major, -1)
676
677 minor = posix.minor(dev)
678 self.assertIsInstance(minor, int)
679 self.assertGreaterEqual(minor, 0)
680 self.assertEqual(posix.minor(dev), minor)
681 self.assertRaises(TypeError, posix.minor, float(dev))
682 self.assertRaises(TypeError, posix.minor)
683 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
684
685 self.assertEqual(posix.makedev(major, minor), dev)
686 self.assertRaises(TypeError, posix.makedev, float(major), minor)
687 self.assertRaises(TypeError, posix.makedev, major, float(minor))
688 self.assertRaises(TypeError, posix.makedev, major)
689 self.assertRaises(TypeError, posix.makedev)
690
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000692 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200693 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200694 if stat_func is not None:
695 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200696 self.assertEqual(stat.st_uid, uid)
697 self.assertEqual(stat.st_gid, gid)
698 uid = os.getuid()
699 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200700 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200701 chown_func(first_param, uid, gid)
702 check_stat(uid, gid)
703 chown_func(first_param, -1, gid)
704 check_stat(uid, gid)
705 chown_func(first_param, uid, -1)
706 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200707
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200708 if uid == 0:
709 # Try an amusingly large uid/gid to make sure we handle
710 # large unsigned values. (chown lets you use any
711 # uid/gid you like, even if they aren't defined.)
712 #
713 # This problem keeps coming up:
714 # http://bugs.python.org/issue1747858
715 # http://bugs.python.org/issue4591
716 # http://bugs.python.org/issue15301
717 # Hopefully the fix in 4591 fixes it for good!
718 #
719 # This part of the test only runs when run as root.
720 # Only scary people run their tests as root.
721
722 big_value = 2**31
723 chown_func(first_param, big_value, big_value)
724 check_stat(big_value, big_value)
725 chown_func(first_param, -1, -1)
726 check_stat(big_value, big_value)
727 chown_func(first_param, uid, gid)
728 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200729 elif platform.system() in ('HP-UX', 'SunOS'):
730 # HP-UX and Solaris can allow a non-root user to chown() to root
731 # (issue #5113)
732 raise unittest.SkipTest("Skipping because of non-standard chown() "
733 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000734 else:
735 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200736 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200737 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200738 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200739 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200740 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200741 self.assertRaises(OSError, chown_func, first_param, -1, 0)
742 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200743 # test illegal types
744 for t in str, float:
745 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
746 check_stat(uid, gid)
747 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
748 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000749
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000750 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
751 def test_chown(self):
752 # raise an OSError if the file does not exist
753 os.unlink(support.TESTFN)
754 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000755
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000756 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200757 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200758 self._test_all_chown_common(posix.chown, support.TESTFN,
759 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000760
761 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
762 def test_fchown(self):
763 os.unlink(support.TESTFN)
764
765 # re-create the file
766 test_file = open(support.TESTFN, 'w')
767 try:
768 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200769 self._test_all_chown_common(posix.fchown, fd,
770 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000771 finally:
772 test_file.close()
773
774 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
775 def test_lchown(self):
776 os.unlink(support.TESTFN)
777 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700778 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200779 self._test_all_chown_common(posix.lchown, support.TESTFN,
780 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000781
Serhiy Storchaka43767632013-11-03 21:31:38 +0200782 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000783 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200784 posix.chdir(os.curdir)
785 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000786
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000787 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300788 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000789
790 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700791 # When listdir is called without argument,
792 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300793 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000794
Larry Hastingsfdaea062012-06-25 04:42:23 -0700795 def test_listdir_bytes(self):
796 # When listdir is called with a bytes object,
797 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300798 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
799
800 def test_listdir_bytes_like(self):
801 for cls in bytearray, memoryview:
802 with self.assertWarns(DeprecationWarning):
803 names = posix.listdir(cls(b'.'))
804 self.assertIn(os.fsencode(support.TESTFN), names)
805 for name in names:
806 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700807
808 @unittest.skipUnless(posix.listdir in os.supports_fd,
809 "test needs fd support for posix.listdir()")
810 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000811 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100812 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000813 self.assertEqual(
814 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000816 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100817 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100818 self.assertEqual(
819 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100821 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000822
Serhiy Storchaka43767632013-11-03 21:31:38 +0200823 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000824 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200825 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000826
Serhiy Storchaka43767632013-11-03 21:31:38 +0200827 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000828 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200829 old_mask = posix.umask(0)
830 self.assertIsInstance(old_mask, int)
831 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000832
Serhiy Storchaka43767632013-11-03 21:31:38 +0200833 @unittest.skipUnless(hasattr(posix, 'strerror'),
834 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000835 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200836 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000837
Serhiy Storchaka43767632013-11-03 21:31:38 +0200838 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000839 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200840 reader, writer = posix.pipe()
841 os.close(reader)
842 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000843
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200844 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200845 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200846 def test_pipe2(self):
847 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
848 self.assertRaises(TypeError, os.pipe2, 0, 0)
849
Charles-François Natali368f34b2011-06-06 19:49:47 +0200850 # try calling with flags = 0, like os.pipe()
851 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200852 os.close(r)
853 os.close(w)
854
855 # test flags
856 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
857 self.addCleanup(os.close, r)
858 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200859 self.assertFalse(os.get_inheritable(r))
860 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200861 self.assertFalse(os.get_blocking(r))
862 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200863 # try reading from an empty pipe: this should fail, not block
864 self.assertRaises(OSError, os.read, r, 1)
865 # try a write big enough to fill-up the pipe: this should either
866 # fail or perform a partial write, not block
867 try:
868 os.write(w, b'x' * support.PIPE_MAX_SIZE)
869 except OSError:
870 pass
871
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200872 @support.cpython_only
873 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
874 @support.requires_linux_version(2, 6, 27)
875 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200876 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200877 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200878 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
879 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
880
Serhiy Storchaka43767632013-11-03 21:31:38 +0200881 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000882 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200883 now = time.time()
884 posix.utime(support.TESTFN, None)
885 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
886 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
887 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
888 posix.utime(support.TESTFN, (int(now), int(now)))
889 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000890
Larry Hastings9cf065c2012-06-22 16:30:09 -0700891 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700892 st = os.stat(target_file)
893 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000894
895 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
896 flags = st.st_flags | stat.UF_IMMUTABLE
897 try:
898 chflags_func(target_file, flags, **kwargs)
899 except OSError as err:
900 if err.errno != errno.EOPNOTSUPP:
901 raise
902 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
903 self.skipTest(msg)
904
Ned Deily3eb67d52011-06-28 00:00:28 -0700905 try:
906 new_st = os.stat(target_file)
907 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
908 try:
909 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200910 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700911 self.assertEqual(e.errno, errno.EPERM)
912 finally:
913 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000914
Ned Deily3eb67d52011-06-28 00:00:28 -0700915 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
916 def test_chflags(self):
917 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
918
919 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
920 def test_lchflags_regular_file(self):
921 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700923
924 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
925 def test_lchflags_symlink(self):
926 testfn_st = os.stat(support.TESTFN)
927
928 self.assertTrue(hasattr(testfn_st, 'st_flags'))
929
930 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
931 self.teardown_files.append(_DUMMY_SYMLINK)
932 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
933
Larry Hastings9cf065c2012-06-22 16:30:09 -0700934 def chflags_nofollow(path, flags):
935 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700936
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000938 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
939 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
940 try:
941 fn(_DUMMY_SYMLINK, flags)
942 except OSError as err:
943 if err.errno != errno.EOPNOTSUPP:
944 raise
945 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
946 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700947 try:
948 new_testfn_st = os.stat(support.TESTFN)
949 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
950
951 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
952 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
953 new_dummy_symlink_st.st_flags)
954 finally:
955 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000956
Guido van Rossum98297ee2007-11-06 21:34:58 +0000957 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000958 if os.name == "nt":
959 item_type = str
960 else:
961 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000962 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000963 self.assertEqual(type(k), item_type)
964 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000965
Serhiy Storchaka77703942017-06-25 07:33:01 +0300966 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
967 def test_putenv(self):
968 with self.assertRaises(ValueError):
969 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
970 with self.assertRaises(ValueError):
971 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
972 with self.assertRaises(ValueError):
973 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
974 with self.assertRaises(ValueError):
975 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
976 with self.assertRaises(ValueError):
977 os.putenv('FRUIT=ORANGE', 'lemon')
978 with self.assertRaises(ValueError):
979 os.putenv(b'FRUIT=ORANGE', b'lemon')
980
Serhiy Storchaka43767632013-11-03 21:31:38 +0200981 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000982 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500983 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
984 curdir = os.getcwd()
985 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000986
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500987 try:
988 os.mkdir(base_path)
989 os.chdir(base_path)
990 except:
991 # Just returning nothing instead of the SkipTest exception, because
992 # the test results in Error in that case. Is that ok?
993 # raise unittest.SkipTest("cannot create directory for testing")
994 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000995
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500996 def _create_and_do_getcwd(dirname, current_path_length = 0):
997 try:
998 os.mkdir(dirname)
999 except:
1000 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001001
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001002 os.chdir(dirname)
1003 try:
1004 os.getcwd()
1005 if current_path_length < 1027:
1006 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
1007 finally:
1008 os.chdir('..')
1009 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001010
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001011 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001012
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001013 finally:
1014 os.chdir(curdir)
1015 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001016
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001017 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1018 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1019 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1020 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001021 user = pwd.getpwuid(os.getuid())[0]
1022 group = pwd.getpwuid(os.getuid())[3]
1023 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001024
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001025
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001026 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001027 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001028 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001029 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001030 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001031
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001032 try:
1033 idg_groups = set(int(g) for g in groups.split())
1034 except ValueError:
1035 idg_groups = set()
1036 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001037 raise unittest.SkipTest("need working 'id -G'")
1038
Ned Deily028915e2013-02-02 15:08:52 -08001039 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1040 if sys.platform == 'darwin':
1041 import sysconfig
1042 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001043 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001044 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1045
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001046 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001047 # groups, ignoring order, duplicates, and the effective gid.
1048 # #10822/#26944 - It is implementation defined whether
1049 # posix.getgroups() includes the effective gid.
1050 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1051 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001052
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001053 # tests for the posix *at functions follow
1054
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1056 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001057 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1058 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001060 finally:
1061 posix.close(f)
1062
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1064 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001065 os.chmod(support.TESTFN, stat.S_IRUSR)
1066
1067 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1068 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001070
1071 s = posix.stat(support.TESTFN)
1072 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1073 finally:
1074 posix.close(f)
1075
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1077 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001078 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001079 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001080
1081 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1082 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001084 finally:
1085 posix.close(f)
1086
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1088 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001089 support.unlink(support.TESTFN)
1090 with open(support.TESTFN, 'w') as outfile:
1091 outfile.write("testline\n")
1092
1093 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1094 try:
1095 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001097 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001098 s2 = posix.stat(support.TESTFN, dir_fd=None)
1099 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001100 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001101 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001102 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001103 posix.stat, support.TESTFN, dir_fd=float(f))
1104 self.assertRaises(OverflowError,
1105 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001106 finally:
1107 posix.close(f)
1108
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1110 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001111 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1112 try:
1113 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001114 posix.utime(support.TESTFN, None, dir_fd=f)
1115 posix.utime(support.TESTFN, dir_fd=f)
1116 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1117 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1118 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1119 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1120 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1121 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1122 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1123 posix.utime(support.TESTFN,
1124 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1125 posix.utime(support.TESTFN, dir_fd=f,
1126 times=(int(now), int((now - int(now)) * 1e9)))
1127
Larry Hastings90867a52012-06-22 17:01:41 -07001128 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001130 try:
1131 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001132 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001133 # whoops! using both together not supported on this platform.
1134 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001135
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001136 finally:
1137 posix.close(f)
1138
Larry Hastings9cf065c2012-06-22 16:30:09 -07001139 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1140 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001141 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1142 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001144 except PermissionError as e:
1145 self.skipTest('posix.link(): %s' % e)
1146 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001147 # should have same inodes
1148 self.assertEqual(posix.stat(support.TESTFN)[1],
1149 posix.stat(support.TESTFN + 'link')[1])
1150 finally:
1151 posix.close(f)
1152 support.unlink(support.TESTFN + 'link')
1153
Larry Hastings9cf065c2012-06-22 16:30:09 -07001154 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1155 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001156 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1157 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001158 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001159 posix.stat(support.TESTFN + 'dir') # should not raise exception
1160 finally:
1161 posix.close(f)
1162 support.rmtree(support.TESTFN + 'dir')
1163
Larry Hastings9cf065c2012-06-22 16:30:09 -07001164 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1165 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1166 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001167 # Test using mknodat() to create a FIFO (the only use specified
1168 # by POSIX).
1169 support.unlink(support.TESTFN)
1170 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1171 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1172 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001173 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001174 except OSError as e:
1175 # Some old systems don't allow unprivileged users to use
1176 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001177 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001178 else:
1179 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1180 finally:
1181 posix.close(f)
1182
Larry Hastings9cf065c2012-06-22 16:30:09 -07001183 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1184 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001185 support.unlink(support.TESTFN)
1186 with open(support.TESTFN, 'w') as outfile:
1187 outfile.write("testline\n")
1188 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001189 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001190 try:
1191 res = posix.read(b, 9).decode(encoding="utf-8")
1192 self.assertEqual("testline\n", res)
1193 finally:
1194 posix.close(a)
1195 posix.close(b)
1196
Larry Hastings9cf065c2012-06-22 16:30:09 -07001197 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1198 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001199 os.symlink(support.TESTFN, support.TESTFN + 'link')
1200 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1201 try:
1202 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001203 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001204 finally:
1205 support.unlink(support.TESTFN + 'link')
1206 posix.close(f)
1207
Larry Hastings9cf065c2012-06-22 16:30:09 -07001208 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1209 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001210 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001211 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001212 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1213 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001214 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001215 except:
1216 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1217 raise
1218 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001219 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001220 finally:
1221 posix.close(f)
1222
Larry Hastings9cf065c2012-06-22 16:30:09 -07001223 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1224 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001225 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1226 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001227 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001228 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1229 finally:
1230 posix.close(f)
1231 support.unlink(support.TESTFN + 'link')
1232
Larry Hastings9cf065c2012-06-22 16:30:09 -07001233 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1234 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001235 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001236 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001237 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001238 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001239 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001240 except:
1241 support.unlink(support.TESTFN + 'del')
1242 raise
1243 else:
1244 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1245 finally:
1246 posix.close(f)
1247
Larry Hastings9cf065c2012-06-22 16:30:09 -07001248 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1249 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001250 support.unlink(support.TESTFN)
1251 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1252 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001253 try:
1254 posix.mkfifo(support.TESTFN,
1255 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1256 except PermissionError as e:
1257 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001258 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1259 finally:
1260 posix.close(f)
1261
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001262 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1263 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001264 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001265 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001266
1267 @requires_sched_h
1268 def test_sched_yield(self):
1269 # This has no error conditions (at least on Linux).
1270 posix.sched_yield()
1271
1272 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001273 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1274 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001275 def test_sched_priority(self):
1276 # Round-robin usually has interesting priorities.
1277 pol = posix.SCHED_RR
1278 lo = posix.sched_get_priority_min(pol)
1279 hi = posix.sched_get_priority_max(pol)
1280 self.assertIsInstance(lo, int)
1281 self.assertIsInstance(hi, int)
1282 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001283 # OSX evidently just returns 15 without checking the argument.
1284 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001285 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1286 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001287
Benjamin Petersonc7042222018-09-12 15:12:24 -07001288 @requires_sched
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001289 def test_get_and_set_scheduler_and_param(self):
1290 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1291 if name.startswith("SCHED_")]
1292 mine = posix.sched_getscheduler(0)
1293 self.assertIn(mine, possible_schedulers)
1294 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001295 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001296 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001297 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001298 raise
1299 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001300 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001301 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1302 self.assertRaises(OSError, posix.sched_getparam, -1)
1303 param = posix.sched_getparam(0)
1304 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001305
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001306 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1307 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1308 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1309 if not sys.platform.startswith(('freebsd', 'netbsd')):
1310 try:
1311 posix.sched_setscheduler(0, mine, param)
1312 posix.sched_setparam(0, param)
1313 except OSError as e:
1314 if e.errno != errno.EPERM:
1315 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001316 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1317
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001318 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1319 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1320 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1321 param = posix.sched_param(None)
1322 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1323 large = 214748364700
1324 param = posix.sched_param(large)
1325 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1326 param = posix.sched_param(sched_priority=-large)
1327 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1328
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001329 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001330 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001331 try:
1332 interval = posix.sched_rr_get_interval(0)
1333 except OSError as e:
1334 # This likely means that sched_rr_get_interval is only valid for
1335 # processes with the SCHED_RR scheduler in effect.
1336 if e.errno != errno.EINVAL:
1337 raise
1338 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001339 self.assertIsInstance(interval, float)
1340 # Reasonable constraints, I think.
1341 self.assertGreaterEqual(interval, 0.)
1342 self.assertLess(interval, 1.)
1343
Benjamin Peterson2740af82011-08-02 17:41:34 -05001344 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001345 def test_sched_getaffinity(self):
1346 mask = posix.sched_getaffinity(0)
1347 self.assertIsInstance(mask, set)
1348 self.assertGreaterEqual(len(mask), 1)
1349 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1350 for cpu in mask:
1351 self.assertIsInstance(cpu, int)
1352 self.assertGreaterEqual(cpu, 0)
1353 self.assertLess(cpu, 1 << 32)
1354
1355 @requires_sched_affinity
1356 def test_sched_setaffinity(self):
1357 mask = posix.sched_getaffinity(0)
1358 if len(mask) > 1:
1359 # Empty masks are forbidden
1360 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001361 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001362 self.assertEqual(posix.sched_getaffinity(0), mask)
1363 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1364 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1365 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001366 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1367
Victor Stinner8b905bd2011-10-25 13:34:04 +02001368 def test_rtld_constants(self):
1369 # check presence of major RTLD_* constants
1370 posix.RTLD_LAZY
1371 posix.RTLD_NOW
1372 posix.RTLD_GLOBAL
1373 posix.RTLD_LOCAL
1374
Jesus Cea60c13dd2012-06-23 02:58:14 +02001375 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1376 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001377 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001378 # Even if the filesystem doesn't report holes,
1379 # if the OS supports it the SEEK_* constants
1380 # will be defined and will have a consistent
1381 # behaviour:
1382 # os.SEEK_DATA = current position
1383 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001384 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001385 fp.write(b"hello")
1386 fp.flush()
1387 size = fp.tell()
1388 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001389 try :
1390 for i in range(size):
1391 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1392 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1393 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1394 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1395 except OSError :
1396 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1397 # but it is not true.
1398 # For instance:
1399 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1400 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001401
Larry Hastingsb0827312014-02-09 22:05:19 -08001402 def test_path_error2(self):
1403 """
1404 Test functions that call path_error2(), providing two filenames in their exceptions.
1405 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001406 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001407 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001408 if function is None:
1409 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001410
Victor Stinnerbed04a72014-10-05 17:37:59 +02001411 for dst in ("noodly2", support.TESTFN):
1412 try:
1413 function('doesnotexistfilename', dst)
1414 except OSError as e:
1415 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1416 break
1417 else:
1418 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001419
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001420 def test_path_with_null_character(self):
1421 fn = support.TESTFN
1422 fn_with_NUL = fn + '\0'
1423 self.addCleanup(support.unlink, fn)
1424 support.unlink(fn)
1425 fd = None
1426 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001427 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001428 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1429 finally:
1430 if fd is not None:
1431 os.close(fd)
1432 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001433 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001434 self.assertFalse(os.path.exists(fn))
1435 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001436 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001437
1438 def test_path_with_null_byte(self):
1439 fn = os.fsencode(support.TESTFN)
1440 fn_with_NUL = fn + b'\0'
1441 self.addCleanup(support.unlink, fn)
1442 support.unlink(fn)
1443 fd = None
1444 try:
1445 with self.assertRaises(ValueError):
1446 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1447 finally:
1448 if fd is not None:
1449 os.close(fd)
1450 self.assertFalse(os.path.exists(fn))
1451 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1452 self.assertFalse(os.path.exists(fn))
1453 open(fn, 'wb').close()
1454 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1455
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001456class PosixGroupsTester(unittest.TestCase):
1457
1458 def setUp(self):
1459 if posix.getuid() != 0:
1460 raise unittest.SkipTest("not enough privileges")
1461 if not hasattr(posix, 'getgroups'):
1462 raise unittest.SkipTest("need posix.getgroups")
1463 if sys.platform == 'darwin':
1464 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1465 self.saved_groups = posix.getgroups()
1466
1467 def tearDown(self):
1468 if hasattr(posix, 'setgroups'):
1469 posix.setgroups(self.saved_groups)
1470 elif hasattr(posix, 'initgroups'):
1471 name = pwd.getpwuid(posix.getuid()).pw_name
1472 posix.initgroups(name, self.saved_groups[0])
1473
1474 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1475 "test needs posix.initgroups()")
1476 def test_initgroups(self):
1477 # find missing group
1478
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001479 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001480 name = pwd.getpwuid(posix.getuid()).pw_name
1481 posix.initgroups(name, g)
1482 self.assertIn(g, posix.getgroups())
1483
1484 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1485 "test needs posix.setgroups()")
1486 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001487 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001488 posix.setgroups(groups)
1489 self.assertListEqual(groups, posix.getgroups())
1490
Serhiy Storchakaef347532018-05-01 16:45:04 +03001491
1492@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1493class TestPosixSpawn(unittest.TestCase):
Victor Stinner03824062018-08-30 01:21:11 +02001494 # Program which does nothing and exit with status 0 (success)
1495 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
1496
1497 def python_args(self, *args):
1498 # Disable site module to avoid side effects. For example,
1499 # on Fedora 28, if the HOME environment variable is not set,
1500 # site._getuserbase() calls pwd.getpwuid() which opens
1501 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1502 # test_close_file() to fail.
1503 return (sys.executable, '-I', '-S', *args)
1504
Serhiy Storchakaef347532018-05-01 16:45:04 +03001505 def test_returns_pid(self):
1506 pidfile = support.TESTFN
1507 self.addCleanup(support.unlink, pidfile)
1508 script = f"""if 1:
1509 import os
1510 with open({pidfile!r}, "w") as pidfile:
1511 pidfile.write(str(os.getpid()))
1512 """
Victor Stinner03824062018-08-30 01:21:11 +02001513 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001514 pid = posix.posix_spawn(args[0], args, os.environ)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001515 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1516 with open(pidfile) as f:
1517 self.assertEqual(f.read(), str(pid))
1518
1519 def test_no_such_executable(self):
1520 no_such_executable = 'no_such_executable'
1521 try:
1522 pid = posix.posix_spawn(no_such_executable,
1523 [no_such_executable],
1524 os.environ)
1525 except FileNotFoundError as exc:
1526 self.assertEqual(exc.filename, no_such_executable)
1527 else:
1528 pid2, status = os.waitpid(pid, 0)
1529 self.assertEqual(pid2, pid)
1530 self.assertNotEqual(status, 0)
1531
1532 def test_specify_environment(self):
1533 envfile = support.TESTFN
1534 self.addCleanup(support.unlink, envfile)
1535 script = f"""if 1:
1536 import os
1537 with open({envfile!r}, "w") as envfile:
1538 envfile.write(os.environ['foo'])
1539 """
Victor Stinner03824062018-08-30 01:21:11 +02001540 args = self.python_args('-c', script)
1541 pid = posix.posix_spawn(args[0], args,
Miro Hrončok7ec8f282018-05-11 07:40:43 +02001542 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001543 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1544 with open(envfile) as f:
1545 self.assertEqual(f.read(), 'bar')
1546
1547 def test_empty_file_actions(self):
1548 pid = posix.posix_spawn(
Victor Stinner03824062018-08-30 01:21:11 +02001549 self.NOOP_PROGRAM[0],
1550 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001551 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001552 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001553 )
1554 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1555
Pablo Galindo254a4662018-09-07 16:44:24 +01001556 def test_resetids_explicit_default(self):
1557 pid = posix.posix_spawn(
1558 sys.executable,
1559 [sys.executable, '-c', 'pass'],
1560 os.environ,
1561 resetids=False
1562 )
1563 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1564
1565 def test_resetids(self):
1566 pid = posix.posix_spawn(
1567 sys.executable,
1568 [sys.executable, '-c', 'pass'],
1569 os.environ,
1570 resetids=True
1571 )
1572 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1573
1574 def test_resetids_wrong_type(self):
1575 with self.assertRaises(TypeError):
1576 posix.posix_spawn(sys.executable,
1577 [sys.executable, "-c", "pass"],
1578 os.environ, resetids=None)
1579
1580 def test_setpgroup(self):
1581 pid = posix.posix_spawn(
1582 sys.executable,
1583 [sys.executable, '-c', 'pass'],
1584 os.environ,
1585 setpgroup=os.getpgrp()
1586 )
1587 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1588
1589 def test_setpgroup_wrong_type(self):
1590 with self.assertRaises(TypeError):
1591 posix.posix_spawn(sys.executable,
1592 [sys.executable, "-c", "pass"],
1593 os.environ, setpgroup="023")
1594
1595 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1596 'need signal.pthread_sigmask()')
1597 def test_setsigmask(self):
1598 code = textwrap.dedent("""\
1599 import _testcapi, signal
1600 _testcapi.raise_signal(signal.SIGUSR1)""")
1601
1602 pid = posix.posix_spawn(
1603 sys.executable,
1604 [sys.executable, '-c', code],
1605 os.environ,
1606 setsigmask=[signal.SIGUSR1]
1607 )
1608 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1609
1610 def test_setsigmask_wrong_type(self):
1611 with self.assertRaises(TypeError):
1612 posix.posix_spawn(sys.executable,
1613 [sys.executable, "-c", "pass"],
1614 os.environ, setsigmask=34)
1615 with self.assertRaises(TypeError):
1616 posix.posix_spawn(sys.executable,
1617 [sys.executable, "-c", "pass"],
1618 os.environ, setsigmask=["j"])
1619 with self.assertRaises(ValueError):
1620 posix.posix_spawn(sys.executable,
1621 [sys.executable, "-c", "pass"],
1622 os.environ, setsigmask=[signal.NSIG,
1623 signal.NSIG+1])
1624
1625 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1626 'need signal.pthread_sigmask()')
1627 def test_setsigdef(self):
1628 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1629 code = textwrap.dedent("""\
1630 import _testcapi, signal
1631 _testcapi.raise_signal(signal.SIGUSR1)""")
1632 try:
1633 pid = posix.posix_spawn(
1634 sys.executable,
1635 [sys.executable, '-c', code],
1636 os.environ,
1637 setsigdef=[signal.SIGUSR1]
1638 )
1639 finally:
1640 signal.signal(signal.SIGUSR1, original_handler)
1641
1642 pid2, status = os.waitpid(pid, 0)
1643 self.assertEqual(pid2, pid)
1644 self.assertTrue(os.WIFSIGNALED(status), status)
1645 self.assertEqual(os.WTERMSIG(status), signal.SIGUSR1)
1646
1647 def test_setsigdef_wrong_type(self):
1648 with self.assertRaises(TypeError):
1649 posix.posix_spawn(sys.executable,
1650 [sys.executable, "-c", "pass"],
1651 os.environ, setsigdef=34)
1652 with self.assertRaises(TypeError):
1653 posix.posix_spawn(sys.executable,
1654 [sys.executable, "-c", "pass"],
1655 os.environ, setsigdef=["j"])
1656 with self.assertRaises(ValueError):
1657 posix.posix_spawn(sys.executable,
1658 [sys.executable, "-c", "pass"],
1659 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
1660
Benjamin Petersonc7042222018-09-12 15:12:24 -07001661 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001662 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1663 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001664 def test_setscheduler_only_param(self):
1665 policy = os.sched_getscheduler(0)
1666 priority = os.sched_get_priority_min(policy)
1667 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001668 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001669 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001670 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001671 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001672 sys.exit(102)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001673 pid = posix.posix_spawn(
1674 sys.executable,
1675 [sys.executable, '-c', code],
1676 os.environ,
1677 scheduler=(None, os.sched_param(priority))
1678 )
1679 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1680
Benjamin Petersonc7042222018-09-12 15:12:24 -07001681 @requires_sched
Pablo Galindo3d18b502018-09-14 15:12:22 -07001682 @unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
1683 "bpo-34685: test can fail on BSD")
Pablo Galindo254a4662018-09-07 16:44:24 +01001684 def test_setscheduler_with_policy(self):
1685 policy = os.sched_getscheduler(0)
1686 priority = os.sched_get_priority_min(policy)
1687 code = textwrap.dedent(f"""\
Pablo Galindo3d18b502018-09-14 15:12:22 -07001688 import os, sys
Pablo Galindo254a4662018-09-07 16:44:24 +01001689 if os.sched_getscheduler(0) != {policy}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001690 sys.exit(101)
Pablo Galindo254a4662018-09-07 16:44:24 +01001691 if os.sched_getparam(0).sched_priority != {priority}:
Pablo Galindo3d18b502018-09-14 15:12:22 -07001692 sys.exit(102)""")
Pablo Galindo254a4662018-09-07 16:44:24 +01001693 pid = posix.posix_spawn(
1694 sys.executable,
1695 [sys.executable, '-c', code],
1696 os.environ,
1697 scheduler=(policy, os.sched_param(priority))
1698 )
1699 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1700
Serhiy Storchakaef347532018-05-01 16:45:04 +03001701 def test_multiple_file_actions(self):
1702 file_actions = [
1703 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1704 (os.POSIX_SPAWN_CLOSE, 0),
1705 (os.POSIX_SPAWN_DUP2, 1, 4),
1706 ]
Victor Stinner03824062018-08-30 01:21:11 +02001707 pid = posix.posix_spawn(self.NOOP_PROGRAM[0],
1708 self.NOOP_PROGRAM,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001709 os.environ,
1710 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001711 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1712
1713 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001714 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001715 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001716 posix.posix_spawn(args[0], args, os.environ,
1717 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001718 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001719 posix.posix_spawn(args[0], args, os.environ,
1720 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001721 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001722 posix.posix_spawn(args[0], args, os.environ,
1723 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001724 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001725 posix.posix_spawn(args[0], args, os.environ,
1726 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001727 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001728 posix.posix_spawn(args[0], args, os.environ,
1729 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001730 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001731 posix.posix_spawn(args[0], args, os.environ,
1732 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001733 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001734 posix.posix_spawn(args[0], args, os.environ,
1735 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001736 with self.assertRaises(ValueError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001737 posix.posix_spawn(args[0], args, os.environ,
1738 file_actions=[(os.POSIX_SPAWN_OPEN,
1739 3, __file__ + '\0',
1740 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001741
1742 def test_open_file(self):
1743 outfile = support.TESTFN
1744 self.addCleanup(support.unlink, outfile)
1745 script = """if 1:
1746 import sys
1747 sys.stdout.write("hello")
1748 """
1749 file_actions = [
1750 (os.POSIX_SPAWN_OPEN, 1, outfile,
1751 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1752 stat.S_IRUSR | stat.S_IWUSR),
1753 ]
Victor Stinner03824062018-08-30 01:21:11 +02001754 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001755 pid = posix.posix_spawn(args[0], args, os.environ,
1756 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001757 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1758 with open(outfile) as f:
1759 self.assertEqual(f.read(), 'hello')
1760
1761 def test_close_file(self):
1762 closefile = support.TESTFN
1763 self.addCleanup(support.unlink, closefile)
1764 script = f"""if 1:
1765 import os
1766 try:
1767 os.fstat(0)
1768 except OSError as e:
1769 with open({closefile!r}, 'w') as closefile:
1770 closefile.write('is closed %d' % e.errno)
1771 """
Victor Stinner03824062018-08-30 01:21:11 +02001772 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001773 pid = posix.posix_spawn(args[0], args, os.environ,
1774 file_actions=[(os.POSIX_SPAWN_CLOSE, 0),])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001775 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1776 with open(closefile) as f:
1777 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1778
1779 def test_dup2(self):
1780 dupfile = support.TESTFN
1781 self.addCleanup(support.unlink, dupfile)
1782 script = """if 1:
1783 import sys
1784 sys.stdout.write("hello")
1785 """
1786 with open(dupfile, "wb") as childfile:
1787 file_actions = [
1788 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1789 ]
Victor Stinner03824062018-08-30 01:21:11 +02001790 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001791 pid = posix.posix_spawn(args[0], args, os.environ,
1792 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001793 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1794 with open(dupfile) as f:
1795 self.assertEqual(f.read(), 'hello')
1796
1797
Neal Norwitze241ce82003-02-17 18:17:05 +00001798def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001799 try:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001800 support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn)
Antoine Pitrou68c95922011-03-20 17:33:57 +01001801 finally:
1802 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001803
1804if __name__ == '__main__':
1805 test_main()