blob: 7a2fc263cb27dce6aa956aa196ddf65fb526351f [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
Neal Norwitze241ce82003-02-17 18:17:05 +000028class PosixTester(unittest.TestCase):
29
30 def setUp(self):
31 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000032 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000033 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070034 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000035 self._warnings_manager = support.check_warnings()
36 self._warnings_manager.__enter__()
37 warnings.filterwarnings('ignore', '.* potential security risk .*',
38 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000039
40 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070041 for teardown_file in self.teardown_files:
42 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000043 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000044
45 def testNoArgFunctions(self):
46 # test posix functions which take no arguments and have
47 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000048 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000049 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000050 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020051 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000052 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000053
Neal Norwitze241ce82003-02-17 18:17:05 +000054 for name in NO_ARG_FUNCTIONS:
55 posix_func = getattr(posix, name, None)
56 if posix_func is not None:
57 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000058 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000059
Serhiy Storchaka43767632013-11-03 21:31:38 +020060 @unittest.skipUnless(hasattr(posix, 'getresuid'),
61 'test needs posix.getresuid()')
62 def test_getresuid(self):
63 user_ids = posix.getresuid()
64 self.assertEqual(len(user_ids), 3)
65 for val in user_ids:
66 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000067
Serhiy Storchaka43767632013-11-03 21:31:38 +020068 @unittest.skipUnless(hasattr(posix, 'getresgid'),
69 'test needs posix.getresgid()')
70 def test_getresgid(self):
71 group_ids = posix.getresgid()
72 self.assertEqual(len(group_ids), 3)
73 for val in group_ids:
74 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000075
Serhiy Storchaka43767632013-11-03 21:31:38 +020076 @unittest.skipUnless(hasattr(posix, 'setresuid'),
77 'test needs posix.setresuid()')
78 def test_setresuid(self):
79 current_user_ids = posix.getresuid()
80 self.assertIsNone(posix.setresuid(*current_user_ids))
81 # -1 means don't change that value.
82 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000083
Serhiy Storchaka43767632013-11-03 21:31:38 +020084 @unittest.skipUnless(hasattr(posix, 'setresuid'),
85 'test needs posix.setresuid()')
86 def test_setresuid_exception(self):
87 # Don't do this test if someone is silly enough to run us as root.
88 current_user_ids = posix.getresuid()
89 if 0 not in current_user_ids:
90 new_user_ids = (current_user_ids[0]+1, -1, -1)
91 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000092
Serhiy Storchaka43767632013-11-03 21:31:38 +020093 @unittest.skipUnless(hasattr(posix, 'setresgid'),
94 'test needs posix.setresgid()')
95 def test_setresgid(self):
96 current_group_ids = posix.getresgid()
97 self.assertIsNone(posix.setresgid(*current_group_ids))
98 # -1 means don't change that value.
99 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000100
Serhiy Storchaka43767632013-11-03 21:31:38 +0200101 @unittest.skipUnless(hasattr(posix, 'setresgid'),
102 'test needs posix.setresgid()')
103 def test_setresgid_exception(self):
104 # Don't do this test if someone is silly enough to run us as root.
105 current_group_ids = posix.getresgid()
106 if 0 not in current_group_ids:
107 new_group_ids = (current_group_ids[0]+1, -1, -1)
108 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000109
Antoine Pitroub7572f02009-12-02 20:46:48 +0000110 @unittest.skipUnless(hasattr(posix, 'initgroups'),
111 "test needs os.initgroups()")
112 def test_initgroups(self):
113 # It takes a string and an integer; check that it raises a TypeError
114 # for other argument lists.
115 self.assertRaises(TypeError, posix.initgroups)
116 self.assertRaises(TypeError, posix.initgroups, None)
117 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
118 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
119
120 # If a non-privileged user invokes it, it should fail with OSError
121 # EPERM.
122 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200123 try:
124 name = pwd.getpwuid(posix.getuid()).pw_name
125 except KeyError:
126 # the current UID may not have a pwd entry
127 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000128 try:
129 posix.initgroups(name, 13)
130 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000131 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000132 else:
133 self.fail("Expected OSError to be raised by initgroups")
134
Serhiy Storchaka43767632013-11-03 21:31:38 +0200135 @unittest.skipUnless(hasattr(posix, 'statvfs'),
136 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000137 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200138 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000139
Serhiy Storchaka43767632013-11-03 21:31:38 +0200140 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
141 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000142 def test_fstatvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200143 fp = open(support.TESTFN)
144 try:
145 self.assertTrue(posix.fstatvfs(fp.fileno()))
146 self.assertTrue(posix.statvfs(fp.fileno()))
147 finally:
148 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000149
Serhiy Storchaka43767632013-11-03 21:31:38 +0200150 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
151 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000152 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200153 fp = open(support.TESTFN, 'w+')
154 try:
155 # we need to have some data to truncate
156 fp.write('test')
157 fp.flush()
158 posix.ftruncate(fp.fileno(), 0)
159 finally:
160 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000161
Ross Lagerwall7807c352011-03-17 20:20:30 +0200162 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
163 def test_truncate(self):
164 with open(support.TESTFN, 'w') as fp:
165 fp.write('test')
166 fp.flush()
167 posix.truncate(support.TESTFN, 0)
168
Larry Hastings9cf065c2012-06-22 16:30:09 -0700169 @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 +0200170 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200171 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200172 def test_fexecve(self):
173 fp = os.open(sys.executable, os.O_RDONLY)
174 try:
175 pid = os.fork()
176 if pid == 0:
177 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700178 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200179 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200180 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200181 finally:
182 os.close(fp)
183
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000184
Ross Lagerwall7807c352011-03-17 20:20:30 +0200185 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
186 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
187 def test_waitid(self):
188 pid = os.fork()
189 if pid == 0:
190 os.chdir(os.path.split(sys.executable)[0])
191 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
192 else:
193 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
194 self.assertEqual(pid, res.si_pid)
195
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200196 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700197 def test_register_at_fork(self):
198 with self.assertRaises(TypeError, msg="Positional args not allowed"):
199 os.register_at_fork(lambda: None)
200 with self.assertRaises(TypeError, msg="Args must be callable"):
201 os.register_at_fork(before=2)
202 with self.assertRaises(TypeError, msg="Args must be callable"):
203 os.register_at_fork(after_in_child="three")
204 with self.assertRaises(TypeError, msg="Args must be callable"):
205 os.register_at_fork(after_in_parent=b"Five")
206 with self.assertRaises(TypeError, msg="Args must not be None"):
207 os.register_at_fork(before=None)
208 with self.assertRaises(TypeError, msg="Args must not be None"):
209 os.register_at_fork(after_in_child=None)
210 with self.assertRaises(TypeError, msg="Args must not be None"):
211 os.register_at_fork(after_in_parent=None)
212 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
213 # Ensure a combination of valid and invalid is an error.
214 os.register_at_fork(before=None, after_in_parent=lambda: 3)
215 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
216 # Ensure a combination of valid and invalid is an error.
217 os.register_at_fork(before=lambda: None, after_in_child='')
218 # We test actual registrations in their own process so as not to
219 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200220 code = """if 1:
221 import os
222
223 r, w = os.pipe()
224 fin_r, fin_w = os.pipe()
225
Gregory P. Smith163468a2017-05-29 10:03:41 -0700226 os.register_at_fork(before=lambda: os.write(w, b'A'))
227 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
228 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
229 os.register_at_fork(before=lambda: os.write(w, b'B'),
230 after_in_parent=lambda: os.write(w, b'D'),
231 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200232
233 pid = os.fork()
234 if pid == 0:
235 # At this point, after-forkers have already been executed
236 os.close(w)
237 # Wait for parent to tell us to exit
238 os.read(fin_r, 1)
239 os._exit(0)
240 else:
241 try:
242 os.close(w)
243 with open(r, "rb") as f:
244 data = f.read()
245 assert len(data) == 6, data
246 # Check before-fork callbacks
247 assert data[:2] == b'BA', data
248 # Check after-fork callbacks
249 assert sorted(data[2:]) == list(b'CDEF'), data
250 assert data.index(b'C') < data.index(b'D'), data
251 assert data.index(b'E') < data.index(b'F'), data
252 finally:
253 os.write(fin_w, b'!')
254 """
255 assert_python_ok('-c', code)
256
Ross Lagerwall7807c352011-03-17 20:20:30 +0200257 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
258 def test_lockf(self):
259 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
260 try:
261 os.write(fd, b'test')
262 os.lseek(fd, 0, os.SEEK_SET)
263 posix.lockf(fd, posix.F_LOCK, 4)
264 # section is locked
265 posix.lockf(fd, posix.F_ULOCK, 4)
266 finally:
267 os.close(fd)
268
269 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
270 def test_pread(self):
271 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
272 try:
273 os.write(fd, b'test')
274 os.lseek(fd, 0, os.SEEK_SET)
275 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100276 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200277 self.assertEqual(b'te', posix.read(fd, 2))
278 finally:
279 os.close(fd)
280
Pablo Galindo4defba32018-01-27 16:16:37 +0000281 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
282 def test_preadv(self):
283 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
284 try:
285 os.write(fd, b'test1tt2t3t5t6t6t8')
286 buf = [bytearray(i) for i in [5, 3, 2]]
287 self.assertEqual(posix.preadv(fd, buf, 3), 10)
288 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
289 finally:
290 os.close(fd)
291
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300292 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000293 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
294 def test_preadv_flags(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, os.RWF_HIPRI), 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()")
305 @requires_32b
306 def test_preadv_overflow_32bits(self):
307 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
308 try:
309 buf = [bytearray(2**16)] * 2**15
310 with self.assertRaises(OSError) as cm:
311 os.preadv(fd, buf, 0)
312 self.assertEqual(cm.exception.errno, errno.EINVAL)
313 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
314 finally:
315 os.close(fd)
316
Ross Lagerwall7807c352011-03-17 20:20:30 +0200317 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
318 def test_pwrite(self):
319 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
320 try:
321 os.write(fd, b'test')
322 os.lseek(fd, 0, os.SEEK_SET)
323 posix.pwrite(fd, b'xx', 1)
324 self.assertEqual(b'txxt', posix.read(fd, 4))
325 finally:
326 os.close(fd)
327
Pablo Galindo4defba32018-01-27 16:16:37 +0000328 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
329 def test_pwritev(self):
330 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
331 try:
332 os.write(fd, b"xx")
333 os.lseek(fd, 0, os.SEEK_SET)
334 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
335 self.assertEqual(n, 10)
336
337 os.lseek(fd, 0, os.SEEK_SET)
338 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
339 finally:
340 os.close(fd)
341
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300342 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000343 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
344 def test_pwritev_flags(self):
345 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
346 try:
347 os.write(fd,b"xx")
348 os.lseek(fd, 0, os.SEEK_SET)
349 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
350 self.assertEqual(n, 10)
351
352 os.lseek(fd, 0, os.SEEK_SET)
353 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
354 finally:
355 os.close(fd)
356
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300357 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
358 @requires_32b
359 def test_pwritev_overflow_32bits(self):
360 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
361 try:
362 with self.assertRaises(OSError) as cm:
363 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
364 self.assertEqual(cm.exception.errno, errno.EINVAL)
365 finally:
366 os.close(fd)
367
Ross Lagerwall7807c352011-03-17 20:20:30 +0200368 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
369 "test needs posix.posix_fallocate()")
370 def test_posix_fallocate(self):
371 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
372 try:
373 posix.posix_fallocate(fd, 0, 10)
374 except OSError as inst:
375 # issue10812, ZFS doesn't appear to support posix_fallocate,
376 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400377 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
378 # often used there.
379 if inst.errno == errno.EINVAL and sys.platform.startswith(
380 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
381 raise unittest.SkipTest("test may fail on ZFS filesystems")
382 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200383 raise
384 finally:
385 os.close(fd)
386
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500387 # issue31106 - posix_fallocate() does not set error in errno.
388 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
389 "test needs posix.posix_fallocate()")
390 def test_posix_fallocate_errno(self):
391 try:
392 posix.posix_fallocate(-42, 0, 10)
393 except OSError as inst:
394 if inst.errno != errno.EBADF:
395 raise
396
Ross Lagerwall7807c352011-03-17 20:20:30 +0200397 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
398 "test needs posix.posix_fadvise()")
399 def test_posix_fadvise(self):
400 fd = os.open(support.TESTFN, os.O_RDONLY)
401 try:
402 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
403 finally:
404 os.close(fd)
405
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500406 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
407 "test needs posix.posix_fadvise()")
408 def test_posix_fadvise_errno(self):
409 try:
410 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
411 except OSError as inst:
412 if inst.errno != errno.EBADF:
413 raise
414
Larry Hastings9cf065c2012-06-22 16:30:09 -0700415 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
416 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200417 now = time.time()
418 fd = os.open(support.TESTFN, os.O_RDONLY)
419 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700420 posix.utime(fd)
421 posix.utime(fd, None)
422 self.assertRaises(TypeError, posix.utime, fd, (None, None))
423 self.assertRaises(TypeError, posix.utime, fd, (now, None))
424 self.assertRaises(TypeError, posix.utime, fd, (None, now))
425 posix.utime(fd, (int(now), int(now)))
426 posix.utime(fd, (now, now))
427 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
428 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
429 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
430 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
431 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
432
Ross Lagerwall7807c352011-03-17 20:20:30 +0200433 finally:
434 os.close(fd)
435
Larry Hastings9cf065c2012-06-22 16:30:09 -0700436 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
437 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200438 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700439 posix.utime(support.TESTFN, None, follow_symlinks=False)
440 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
441 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
442 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
443 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
444 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
445 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200446
447 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
448 def test_writev(self):
449 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
450 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100451 n = os.writev(fd, (b'test1', b'tt2', b't3'))
452 self.assertEqual(n, 10)
453
Ross Lagerwall7807c352011-03-17 20:20:30 +0200454 os.lseek(fd, 0, os.SEEK_SET)
455 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100456
457 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100458 try:
459 size = posix.writev(fd, [])
460 except OSError:
461 # writev(fd, []) raises OSError(22, "Invalid argument")
462 # on OpenIndiana
463 pass
464 else:
465 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200466 finally:
467 os.close(fd)
468
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300469 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
470 @requires_32b
471 def test_writev_overflow_32bits(self):
472 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
473 try:
474 with self.assertRaises(OSError) as cm:
475 os.writev(fd, [b"x" * 2**16] * 2**15)
476 self.assertEqual(cm.exception.errno, errno.EINVAL)
477 finally:
478 os.close(fd)
479
Ross Lagerwall7807c352011-03-17 20:20:30 +0200480 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
481 def test_readv(self):
482 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
483 try:
484 os.write(fd, b'test1tt2t3')
485 os.lseek(fd, 0, os.SEEK_SET)
486 buf = [bytearray(i) for i in [5, 3, 2]]
487 self.assertEqual(posix.readv(fd, buf), 10)
488 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100489
490 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100491 try:
492 size = posix.readv(fd, [])
493 except OSError:
494 # readv(fd, []) raises OSError(22, "Invalid argument")
495 # on OpenIndiana
496 pass
497 else:
498 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200499 finally:
500 os.close(fd)
501
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300502 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
503 @requires_32b
504 def test_readv_overflow_32bits(self):
505 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
506 try:
507 buf = [bytearray(2**16)] * 2**15
508 with self.assertRaises(OSError) as cm:
509 os.readv(fd, buf)
510 self.assertEqual(cm.exception.errno, errno.EINVAL)
511 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
512 finally:
513 os.close(fd)
514
Serhiy Storchaka43767632013-11-03 21:31:38 +0200515 @unittest.skipUnless(hasattr(posix, 'dup'),
516 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000517 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200518 fp = open(support.TESTFN)
519 try:
520 fd = posix.dup(fp.fileno())
521 self.assertIsInstance(fd, int)
522 os.close(fd)
523 finally:
524 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000525
Serhiy Storchaka43767632013-11-03 21:31:38 +0200526 @unittest.skipUnless(hasattr(posix, 'confstr'),
527 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000528 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200529 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
530 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000531
Serhiy Storchaka43767632013-11-03 21:31:38 +0200532 @unittest.skipUnless(hasattr(posix, 'dup2'),
533 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000534 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200535 fp1 = open(support.TESTFN)
536 fp2 = open(support.TESTFN)
537 try:
538 posix.dup2(fp1.fileno(), fp2.fileno())
539 finally:
540 fp1.close()
541 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000542
Charles-François Natali1e045b12011-05-22 20:42:32 +0200543 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200544 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200545 def test_oscloexec(self):
546 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
547 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200548 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200549
Serhiy Storchaka43767632013-11-03 21:31:38 +0200550 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
551 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000552 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200553 fd = os.open(support.TESTFN,
554 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
555 self.assertRaises(OSError, os.open, support.TESTFN,
556 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
557 os.close(fd)
558
559 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000560 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200561 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000562 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000563 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
564 os.close(fd)
565
Serhiy Storchaka43767632013-11-03 21:31:38 +0200566 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
567 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000568 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200569 fd1 = os.open(support.TESTFN,
570 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
571 fd2 = os.open(support.TESTFN,
572 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
573 os.close(fd2)
574 os.close(fd1)
575
576 if hasattr(posix, "O_EXLOCK"):
577 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000578 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200579 self.assertRaises(OSError, os.open, support.TESTFN,
580 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
581 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000582
Serhiy Storchaka43767632013-11-03 21:31:38 +0200583 @unittest.skipUnless(hasattr(posix, 'fstat'),
584 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000585 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200586 fp = open(support.TESTFN)
587 try:
588 self.assertTrue(posix.fstat(fp.fileno()))
589 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200590
Serhiy Storchaka43767632013-11-03 21:31:38 +0200591 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700592 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200593 posix.stat, float(fp.fileno()))
594 finally:
595 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000596
Serhiy Storchaka43767632013-11-03 21:31:38 +0200597 @unittest.skipUnless(hasattr(posix, 'stat'),
598 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000599 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200600 self.assertTrue(posix.stat(support.TESTFN))
601 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200602
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300603 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700604 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300605 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200606 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700607 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200608 posix.stat, None)
609 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700610 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200611 posix.stat, list(support.TESTFN))
612 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700613 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200614 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000615
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000616 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
617 def test_mkfifo(self):
618 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100619 try:
620 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
621 except PermissionError as e:
622 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000623 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
624
625 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
626 "don't have mknod()/S_IFIFO")
627 def test_mknod(self):
628 # Test using mknod() to create a FIFO (the only use specified
629 # by POSIX).
630 support.unlink(support.TESTFN)
631 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
632 try:
633 posix.mknod(support.TESTFN, mode, 0)
634 except OSError as e:
635 # Some old systems don't allow unprivileged users to use
636 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100637 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000638 else:
639 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
640
Martin Panterbf19d162015-09-09 01:01:13 +0000641 # Keyword arguments are also supported
642 support.unlink(support.TESTFN)
643 try:
644 posix.mknod(path=support.TESTFN, mode=mode, device=0,
645 dir_fd=None)
646 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100647 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000648
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300649 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
650 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
651 def test_makedev(self):
652 st = posix.stat(support.TESTFN)
653 dev = st.st_dev
654 self.assertIsInstance(dev, int)
655 self.assertGreaterEqual(dev, 0)
656
657 major = posix.major(dev)
658 self.assertIsInstance(major, int)
659 self.assertGreaterEqual(major, 0)
660 self.assertEqual(posix.major(dev), major)
661 self.assertRaises(TypeError, posix.major, float(dev))
662 self.assertRaises(TypeError, posix.major)
663 self.assertRaises((ValueError, OverflowError), posix.major, -1)
664
665 minor = posix.minor(dev)
666 self.assertIsInstance(minor, int)
667 self.assertGreaterEqual(minor, 0)
668 self.assertEqual(posix.minor(dev), minor)
669 self.assertRaises(TypeError, posix.minor, float(dev))
670 self.assertRaises(TypeError, posix.minor)
671 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
672
673 self.assertEqual(posix.makedev(major, minor), dev)
674 self.assertRaises(TypeError, posix.makedev, float(major), minor)
675 self.assertRaises(TypeError, posix.makedev, major, float(minor))
676 self.assertRaises(TypeError, posix.makedev, major)
677 self.assertRaises(TypeError, posix.makedev)
678
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200679 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000680 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200681 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200682 if stat_func is not None:
683 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200684 self.assertEqual(stat.st_uid, uid)
685 self.assertEqual(stat.st_gid, gid)
686 uid = os.getuid()
687 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200688 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200689 chown_func(first_param, uid, gid)
690 check_stat(uid, gid)
691 chown_func(first_param, -1, gid)
692 check_stat(uid, gid)
693 chown_func(first_param, uid, -1)
694 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200695
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200696 if uid == 0:
697 # Try an amusingly large uid/gid to make sure we handle
698 # large unsigned values. (chown lets you use any
699 # uid/gid you like, even if they aren't defined.)
700 #
701 # This problem keeps coming up:
702 # http://bugs.python.org/issue1747858
703 # http://bugs.python.org/issue4591
704 # http://bugs.python.org/issue15301
705 # Hopefully the fix in 4591 fixes it for good!
706 #
707 # This part of the test only runs when run as root.
708 # Only scary people run their tests as root.
709
710 big_value = 2**31
711 chown_func(first_param, big_value, big_value)
712 check_stat(big_value, big_value)
713 chown_func(first_param, -1, -1)
714 check_stat(big_value, big_value)
715 chown_func(first_param, uid, gid)
716 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200717 elif platform.system() in ('HP-UX', 'SunOS'):
718 # HP-UX and Solaris can allow a non-root user to chown() to root
719 # (issue #5113)
720 raise unittest.SkipTest("Skipping because of non-standard chown() "
721 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000722 else:
723 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200725 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200726 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200727 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200728 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200729 self.assertRaises(OSError, chown_func, first_param, -1, 0)
730 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200731 # test illegal types
732 for t in str, float:
733 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
734 check_stat(uid, gid)
735 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
736 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000737
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000738 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
739 def test_chown(self):
740 # raise an OSError if the file does not exist
741 os.unlink(support.TESTFN)
742 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000743
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000744 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200745 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200746 self._test_all_chown_common(posix.chown, support.TESTFN,
747 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000748
749 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
750 def test_fchown(self):
751 os.unlink(support.TESTFN)
752
753 # re-create the file
754 test_file = open(support.TESTFN, 'w')
755 try:
756 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200757 self._test_all_chown_common(posix.fchown, fd,
758 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000759 finally:
760 test_file.close()
761
762 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
763 def test_lchown(self):
764 os.unlink(support.TESTFN)
765 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700766 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200767 self._test_all_chown_common(posix.lchown, support.TESTFN,
768 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000769
Serhiy Storchaka43767632013-11-03 21:31:38 +0200770 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000771 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200772 posix.chdir(os.curdir)
773 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000774
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000775 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300776 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000777
778 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700779 # When listdir is called without argument,
780 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300781 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000782
Larry Hastingsfdaea062012-06-25 04:42:23 -0700783 def test_listdir_bytes(self):
784 # When listdir is called with a bytes object,
785 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300786 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
787
788 def test_listdir_bytes_like(self):
789 for cls in bytearray, memoryview:
790 with self.assertWarns(DeprecationWarning):
791 names = posix.listdir(cls(b'.'))
792 self.assertIn(os.fsencode(support.TESTFN), names)
793 for name in names:
794 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700795
796 @unittest.skipUnless(posix.listdir in os.supports_fd,
797 "test needs fd support for posix.listdir()")
798 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000799 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100800 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000801 self.assertEqual(
802 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700803 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000804 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100805 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100806 self.assertEqual(
807 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700808 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100809 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000810
Serhiy Storchaka43767632013-11-03 21:31:38 +0200811 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000812 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200813 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000814
Serhiy Storchaka43767632013-11-03 21:31:38 +0200815 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000816 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200817 old_mask = posix.umask(0)
818 self.assertIsInstance(old_mask, int)
819 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000820
Serhiy Storchaka43767632013-11-03 21:31:38 +0200821 @unittest.skipUnless(hasattr(posix, 'strerror'),
822 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000823 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200824 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000825
Serhiy Storchaka43767632013-11-03 21:31:38 +0200826 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000827 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200828 reader, writer = posix.pipe()
829 os.close(reader)
830 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000831
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200832 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200833 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200834 def test_pipe2(self):
835 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
836 self.assertRaises(TypeError, os.pipe2, 0, 0)
837
Charles-François Natali368f34b2011-06-06 19:49:47 +0200838 # try calling with flags = 0, like os.pipe()
839 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200840 os.close(r)
841 os.close(w)
842
843 # test flags
844 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
845 self.addCleanup(os.close, r)
846 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200847 self.assertFalse(os.get_inheritable(r))
848 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200849 self.assertFalse(os.get_blocking(r))
850 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200851 # try reading from an empty pipe: this should fail, not block
852 self.assertRaises(OSError, os.read, r, 1)
853 # try a write big enough to fill-up the pipe: this should either
854 # fail or perform a partial write, not block
855 try:
856 os.write(w, b'x' * support.PIPE_MAX_SIZE)
857 except OSError:
858 pass
859
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200860 @support.cpython_only
861 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
862 @support.requires_linux_version(2, 6, 27)
863 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200864 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200865 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200866 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
867 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
868
Serhiy Storchaka43767632013-11-03 21:31:38 +0200869 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000870 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200871 now = time.time()
872 posix.utime(support.TESTFN, None)
873 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
874 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
875 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
876 posix.utime(support.TESTFN, (int(now), int(now)))
877 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000878
Larry Hastings9cf065c2012-06-22 16:30:09 -0700879 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700880 st = os.stat(target_file)
881 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000882
883 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
884 flags = st.st_flags | stat.UF_IMMUTABLE
885 try:
886 chflags_func(target_file, flags, **kwargs)
887 except OSError as err:
888 if err.errno != errno.EOPNOTSUPP:
889 raise
890 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
891 self.skipTest(msg)
892
Ned Deily3eb67d52011-06-28 00:00:28 -0700893 try:
894 new_st = os.stat(target_file)
895 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
896 try:
897 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200898 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700899 self.assertEqual(e.errno, errno.EPERM)
900 finally:
901 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000902
Ned Deily3eb67d52011-06-28 00:00:28 -0700903 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
904 def test_chflags(self):
905 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
906
907 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
908 def test_lchflags_regular_file(self):
909 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700910 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700911
912 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
913 def test_lchflags_symlink(self):
914 testfn_st = os.stat(support.TESTFN)
915
916 self.assertTrue(hasattr(testfn_st, 'st_flags'))
917
918 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
919 self.teardown_files.append(_DUMMY_SYMLINK)
920 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
921
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922 def chflags_nofollow(path, flags):
923 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700924
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000926 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
927 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
928 try:
929 fn(_DUMMY_SYMLINK, flags)
930 except OSError as err:
931 if err.errno != errno.EOPNOTSUPP:
932 raise
933 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
934 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935 try:
936 new_testfn_st = os.stat(support.TESTFN)
937 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
938
939 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
940 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
941 new_dummy_symlink_st.st_flags)
942 finally:
943 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000944
Guido van Rossum98297ee2007-11-06 21:34:58 +0000945 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000946 if os.name == "nt":
947 item_type = str
948 else:
949 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000950 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000951 self.assertEqual(type(k), item_type)
952 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000953
Serhiy Storchaka77703942017-06-25 07:33:01 +0300954 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
955 def test_putenv(self):
956 with self.assertRaises(ValueError):
957 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
958 with self.assertRaises(ValueError):
959 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
960 with self.assertRaises(ValueError):
961 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
962 with self.assertRaises(ValueError):
963 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
964 with self.assertRaises(ValueError):
965 os.putenv('FRUIT=ORANGE', 'lemon')
966 with self.assertRaises(ValueError):
967 os.putenv(b'FRUIT=ORANGE', b'lemon')
968
Serhiy Storchaka43767632013-11-03 21:31:38 +0200969 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000970 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500971 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
972 curdir = os.getcwd()
973 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000974
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500975 try:
976 os.mkdir(base_path)
977 os.chdir(base_path)
978 except:
979 # Just returning nothing instead of the SkipTest exception, because
980 # the test results in Error in that case. Is that ok?
981 # raise unittest.SkipTest("cannot create directory for testing")
982 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000983
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500984 def _create_and_do_getcwd(dirname, current_path_length = 0):
985 try:
986 os.mkdir(dirname)
987 except:
988 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000989
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500990 os.chdir(dirname)
991 try:
992 os.getcwd()
993 if current_path_length < 1027:
994 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
995 finally:
996 os.chdir('..')
997 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000998
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500999 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001000
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -05001001 finally:
1002 os.chdir(curdir)
1003 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001004
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001005 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1006 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1007 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1008 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001009 user = pwd.getpwuid(os.getuid())[0]
1010 group = pwd.getpwuid(os.getuid())[3]
1011 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001012
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001013
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001014 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001015 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001016 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001017 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001018 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001019
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001020 try:
1021 idg_groups = set(int(g) for g in groups.split())
1022 except ValueError:
1023 idg_groups = set()
1024 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001025 raise unittest.SkipTest("need working 'id -G'")
1026
Ned Deily028915e2013-02-02 15:08:52 -08001027 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1028 if sys.platform == 'darwin':
1029 import sysconfig
1030 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001031 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001032 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1033
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001034 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001035 # groups, ignoring order, duplicates, and the effective gid.
1036 # #10822/#26944 - It is implementation defined whether
1037 # posix.getgroups() includes the effective gid.
1038 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1039 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001040
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001041 # tests for the posix *at functions follow
1042
Larry Hastings9cf065c2012-06-22 16:30:09 -07001043 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1044 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001045 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1046 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001047 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001048 finally:
1049 posix.close(f)
1050
Larry Hastings9cf065c2012-06-22 16:30:09 -07001051 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1052 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001053 os.chmod(support.TESTFN, stat.S_IRUSR)
1054
1055 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1056 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001058
1059 s = posix.stat(support.TESTFN)
1060 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1061 finally:
1062 posix.close(f)
1063
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1065 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001066 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001067 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001068
1069 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1070 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001072 finally:
1073 posix.close(f)
1074
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1076 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001077 support.unlink(support.TESTFN)
1078 with open(support.TESTFN, 'w') as outfile:
1079 outfile.write("testline\n")
1080
1081 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1082 try:
1083 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001085 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001086 s2 = posix.stat(support.TESTFN, dir_fd=None)
1087 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001088 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001089 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001090 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001091 posix.stat, support.TESTFN, dir_fd=float(f))
1092 self.assertRaises(OverflowError,
1093 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001094 finally:
1095 posix.close(f)
1096
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1098 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001099 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1100 try:
1101 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001102 posix.utime(support.TESTFN, None, dir_fd=f)
1103 posix.utime(support.TESTFN, dir_fd=f)
1104 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1105 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1106 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1107 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1108 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1109 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1110 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1111 posix.utime(support.TESTFN,
1112 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1113 posix.utime(support.TESTFN, dir_fd=f,
1114 times=(int(now), int((now - int(now)) * 1e9)))
1115
Larry Hastings90867a52012-06-22 17:01:41 -07001116 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001118 try:
1119 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001120 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001121 # whoops! using both together not supported on this platform.
1122 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001123
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001124 finally:
1125 posix.close(f)
1126
Larry Hastings9cf065c2012-06-22 16:30:09 -07001127 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1128 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001129 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1130 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001131 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001132 except PermissionError as e:
1133 self.skipTest('posix.link(): %s' % e)
1134 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001135 # should have same inodes
1136 self.assertEqual(posix.stat(support.TESTFN)[1],
1137 posix.stat(support.TESTFN + 'link')[1])
1138 finally:
1139 posix.close(f)
1140 support.unlink(support.TESTFN + 'link')
1141
Larry Hastings9cf065c2012-06-22 16:30:09 -07001142 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1143 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001144 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1145 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001147 posix.stat(support.TESTFN + 'dir') # should not raise exception
1148 finally:
1149 posix.close(f)
1150 support.rmtree(support.TESTFN + 'dir')
1151
Larry Hastings9cf065c2012-06-22 16:30:09 -07001152 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1153 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1154 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001155 # Test using mknodat() to create a FIFO (the only use specified
1156 # by POSIX).
1157 support.unlink(support.TESTFN)
1158 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1159 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1160 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001161 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001162 except OSError as e:
1163 # Some old systems don't allow unprivileged users to use
1164 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001165 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001166 else:
1167 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1168 finally:
1169 posix.close(f)
1170
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1172 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001173 support.unlink(support.TESTFN)
1174 with open(support.TESTFN, 'w') as outfile:
1175 outfile.write("testline\n")
1176 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001177 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001178 try:
1179 res = posix.read(b, 9).decode(encoding="utf-8")
1180 self.assertEqual("testline\n", res)
1181 finally:
1182 posix.close(a)
1183 posix.close(b)
1184
Larry Hastings9cf065c2012-06-22 16:30:09 -07001185 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1186 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001187 os.symlink(support.TESTFN, support.TESTFN + 'link')
1188 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1189 try:
1190 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001191 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001192 finally:
1193 support.unlink(support.TESTFN + 'link')
1194 posix.close(f)
1195
Larry Hastings9cf065c2012-06-22 16:30:09 -07001196 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1197 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001198 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001199 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001200 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1201 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001202 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001203 except:
1204 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1205 raise
1206 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001207 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001208 finally:
1209 posix.close(f)
1210
Larry Hastings9cf065c2012-06-22 16:30:09 -07001211 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1212 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001213 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1214 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001215 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001216 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1217 finally:
1218 posix.close(f)
1219 support.unlink(support.TESTFN + 'link')
1220
Larry Hastings9cf065c2012-06-22 16:30:09 -07001221 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1222 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001223 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001224 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001225 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001226 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001227 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001228 except:
1229 support.unlink(support.TESTFN + 'del')
1230 raise
1231 else:
1232 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1233 finally:
1234 posix.close(f)
1235
Larry Hastings9cf065c2012-06-22 16:30:09 -07001236 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1237 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001238 support.unlink(support.TESTFN)
1239 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1240 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001241 try:
1242 posix.mkfifo(support.TESTFN,
1243 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1244 except PermissionError as e:
1245 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001246 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1247 finally:
1248 posix.close(f)
1249
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001250 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1251 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001252 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001253 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001254
1255 @requires_sched_h
1256 def test_sched_yield(self):
1257 # This has no error conditions (at least on Linux).
1258 posix.sched_yield()
1259
1260 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001261 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1262 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001263 def test_sched_priority(self):
1264 # Round-robin usually has interesting priorities.
1265 pol = posix.SCHED_RR
1266 lo = posix.sched_get_priority_min(pol)
1267 hi = posix.sched_get_priority_max(pol)
1268 self.assertIsInstance(lo, int)
1269 self.assertIsInstance(hi, int)
1270 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001271 # OSX evidently just returns 15 without checking the argument.
1272 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001273 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1274 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001275
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001276 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001277 def test_get_and_set_scheduler_and_param(self):
1278 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1279 if name.startswith("SCHED_")]
1280 mine = posix.sched_getscheduler(0)
1281 self.assertIn(mine, possible_schedulers)
1282 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001283 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001284 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001285 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001286 raise
1287 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001288 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001289 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1290 self.assertRaises(OSError, posix.sched_getparam, -1)
1291 param = posix.sched_getparam(0)
1292 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001293
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001294 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1295 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1296 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1297 if not sys.platform.startswith(('freebsd', 'netbsd')):
1298 try:
1299 posix.sched_setscheduler(0, mine, param)
1300 posix.sched_setparam(0, param)
1301 except OSError as e:
1302 if e.errno != errno.EPERM:
1303 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001304 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1305
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001306 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1307 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1308 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1309 param = posix.sched_param(None)
1310 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1311 large = 214748364700
1312 param = posix.sched_param(large)
1313 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1314 param = posix.sched_param(sched_priority=-large)
1315 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1316
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001317 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001318 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001319 try:
1320 interval = posix.sched_rr_get_interval(0)
1321 except OSError as e:
1322 # This likely means that sched_rr_get_interval is only valid for
1323 # processes with the SCHED_RR scheduler in effect.
1324 if e.errno != errno.EINVAL:
1325 raise
1326 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001327 self.assertIsInstance(interval, float)
1328 # Reasonable constraints, I think.
1329 self.assertGreaterEqual(interval, 0.)
1330 self.assertLess(interval, 1.)
1331
Benjamin Peterson2740af82011-08-02 17:41:34 -05001332 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001333 def test_sched_getaffinity(self):
1334 mask = posix.sched_getaffinity(0)
1335 self.assertIsInstance(mask, set)
1336 self.assertGreaterEqual(len(mask), 1)
1337 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1338 for cpu in mask:
1339 self.assertIsInstance(cpu, int)
1340 self.assertGreaterEqual(cpu, 0)
1341 self.assertLess(cpu, 1 << 32)
1342
1343 @requires_sched_affinity
1344 def test_sched_setaffinity(self):
1345 mask = posix.sched_getaffinity(0)
1346 if len(mask) > 1:
1347 # Empty masks are forbidden
1348 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001349 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001350 self.assertEqual(posix.sched_getaffinity(0), mask)
1351 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1352 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1353 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001354 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1355
Victor Stinner8b905bd2011-10-25 13:34:04 +02001356 def test_rtld_constants(self):
1357 # check presence of major RTLD_* constants
1358 posix.RTLD_LAZY
1359 posix.RTLD_NOW
1360 posix.RTLD_GLOBAL
1361 posix.RTLD_LOCAL
1362
Jesus Cea60c13dd2012-06-23 02:58:14 +02001363 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1364 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001365 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001366 # Even if the filesystem doesn't report holes,
1367 # if the OS supports it the SEEK_* constants
1368 # will be defined and will have a consistent
1369 # behaviour:
1370 # os.SEEK_DATA = current position
1371 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001372 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001373 fp.write(b"hello")
1374 fp.flush()
1375 size = fp.tell()
1376 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001377 try :
1378 for i in range(size):
1379 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1380 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1381 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1382 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1383 except OSError :
1384 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1385 # but it is not true.
1386 # For instance:
1387 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1388 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001389
Larry Hastingsb0827312014-02-09 22:05:19 -08001390 def test_path_error2(self):
1391 """
1392 Test functions that call path_error2(), providing two filenames in their exceptions.
1393 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001394 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001395 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001396 if function is None:
1397 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001398
Victor Stinnerbed04a72014-10-05 17:37:59 +02001399 for dst in ("noodly2", support.TESTFN):
1400 try:
1401 function('doesnotexistfilename', dst)
1402 except OSError as e:
1403 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1404 break
1405 else:
1406 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001407
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001408 def test_path_with_null_character(self):
1409 fn = support.TESTFN
1410 fn_with_NUL = fn + '\0'
1411 self.addCleanup(support.unlink, fn)
1412 support.unlink(fn)
1413 fd = None
1414 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001415 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001416 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1417 finally:
1418 if fd is not None:
1419 os.close(fd)
1420 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001421 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001422 self.assertFalse(os.path.exists(fn))
1423 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001424 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001425
1426 def test_path_with_null_byte(self):
1427 fn = os.fsencode(support.TESTFN)
1428 fn_with_NUL = fn + b'\0'
1429 self.addCleanup(support.unlink, fn)
1430 support.unlink(fn)
1431 fd = None
1432 try:
1433 with self.assertRaises(ValueError):
1434 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1435 finally:
1436 if fd is not None:
1437 os.close(fd)
1438 self.assertFalse(os.path.exists(fn))
1439 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1440 self.assertFalse(os.path.exists(fn))
1441 open(fn, 'wb').close()
1442 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1443
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001444class PosixGroupsTester(unittest.TestCase):
1445
1446 def setUp(self):
1447 if posix.getuid() != 0:
1448 raise unittest.SkipTest("not enough privileges")
1449 if not hasattr(posix, 'getgroups'):
1450 raise unittest.SkipTest("need posix.getgroups")
1451 if sys.platform == 'darwin':
1452 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1453 self.saved_groups = posix.getgroups()
1454
1455 def tearDown(self):
1456 if hasattr(posix, 'setgroups'):
1457 posix.setgroups(self.saved_groups)
1458 elif hasattr(posix, 'initgroups'):
1459 name = pwd.getpwuid(posix.getuid()).pw_name
1460 posix.initgroups(name, self.saved_groups[0])
1461
1462 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1463 "test needs posix.initgroups()")
1464 def test_initgroups(self):
1465 # find missing group
1466
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001467 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001468 name = pwd.getpwuid(posix.getuid()).pw_name
1469 posix.initgroups(name, g)
1470 self.assertIn(g, posix.getgroups())
1471
1472 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1473 "test needs posix.setgroups()")
1474 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001475 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001476 posix.setgroups(groups)
1477 self.assertListEqual(groups, posix.getgroups())
1478
Serhiy Storchakaef347532018-05-01 16:45:04 +03001479
1480@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1481class TestPosixSpawn(unittest.TestCase):
Victor Stinner03824062018-08-30 01:21:11 +02001482 # Program which does nothing and exit with status 0 (success)
1483 NOOP_PROGRAM = (sys.executable, '-I', '-S', '-c', 'pass')
1484
1485 def python_args(self, *args):
1486 # Disable site module to avoid side effects. For example,
1487 # on Fedora 28, if the HOME environment variable is not set,
1488 # site._getuserbase() calls pwd.getpwuid() which opens
1489 # /var/lib/sss/mc/passwd but then leaves the file open which makes
1490 # test_close_file() to fail.
1491 return (sys.executable, '-I', '-S', *args)
1492
Serhiy Storchakaef347532018-05-01 16:45:04 +03001493 def test_returns_pid(self):
1494 pidfile = support.TESTFN
1495 self.addCleanup(support.unlink, pidfile)
1496 script = f"""if 1:
1497 import os
1498 with open({pidfile!r}, "w") as pidfile:
1499 pidfile.write(str(os.getpid()))
1500 """
Victor Stinner03824062018-08-30 01:21:11 +02001501 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001502 pid = posix.posix_spawn(args[0], args, os.environ)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001503 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1504 with open(pidfile) as f:
1505 self.assertEqual(f.read(), str(pid))
1506
1507 def test_no_such_executable(self):
1508 no_such_executable = 'no_such_executable'
1509 try:
1510 pid = posix.posix_spawn(no_such_executable,
1511 [no_such_executable],
1512 os.environ)
1513 except FileNotFoundError as exc:
1514 self.assertEqual(exc.filename, no_such_executable)
1515 else:
1516 pid2, status = os.waitpid(pid, 0)
1517 self.assertEqual(pid2, pid)
1518 self.assertNotEqual(status, 0)
1519
1520 def test_specify_environment(self):
1521 envfile = support.TESTFN
1522 self.addCleanup(support.unlink, envfile)
1523 script = f"""if 1:
1524 import os
1525 with open({envfile!r}, "w") as envfile:
1526 envfile.write(os.environ['foo'])
1527 """
Victor Stinner03824062018-08-30 01:21:11 +02001528 args = self.python_args('-c', script)
1529 pid = posix.posix_spawn(args[0], args,
Miro Hrončok7ec8f282018-05-11 07:40:43 +02001530 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001531 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1532 with open(envfile) as f:
1533 self.assertEqual(f.read(), 'bar')
1534
1535 def test_empty_file_actions(self):
1536 pid = posix.posix_spawn(
Victor Stinner03824062018-08-30 01:21:11 +02001537 self.NOOP_PROGRAM[0],
1538 self.NOOP_PROGRAM,
Serhiy Storchakaef347532018-05-01 16:45:04 +03001539 os.environ,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001540 file_actions=[]
Serhiy Storchakaef347532018-05-01 16:45:04 +03001541 )
1542 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1543
Pablo Galindo254a4662018-09-07 16:44:24 +01001544 def test_resetids_explicit_default(self):
1545 pid = posix.posix_spawn(
1546 sys.executable,
1547 [sys.executable, '-c', 'pass'],
1548 os.environ,
1549 resetids=False
1550 )
1551 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1552
1553 def test_resetids(self):
1554 pid = posix.posix_spawn(
1555 sys.executable,
1556 [sys.executable, '-c', 'pass'],
1557 os.environ,
1558 resetids=True
1559 )
1560 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1561
1562 def test_resetids_wrong_type(self):
1563 with self.assertRaises(TypeError):
1564 posix.posix_spawn(sys.executable,
1565 [sys.executable, "-c", "pass"],
1566 os.environ, resetids=None)
1567
1568 def test_setpgroup(self):
1569 pid = posix.posix_spawn(
1570 sys.executable,
1571 [sys.executable, '-c', 'pass'],
1572 os.environ,
1573 setpgroup=os.getpgrp()
1574 )
1575 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1576
1577 def test_setpgroup_wrong_type(self):
1578 with self.assertRaises(TypeError):
1579 posix.posix_spawn(sys.executable,
1580 [sys.executable, "-c", "pass"],
1581 os.environ, setpgroup="023")
1582
1583 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1584 'need signal.pthread_sigmask()')
1585 def test_setsigmask(self):
1586 code = textwrap.dedent("""\
1587 import _testcapi, signal
1588 _testcapi.raise_signal(signal.SIGUSR1)""")
1589
1590 pid = posix.posix_spawn(
1591 sys.executable,
1592 [sys.executable, '-c', code],
1593 os.environ,
1594 setsigmask=[signal.SIGUSR1]
1595 )
1596 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1597
1598 def test_setsigmask_wrong_type(self):
1599 with self.assertRaises(TypeError):
1600 posix.posix_spawn(sys.executable,
1601 [sys.executable, "-c", "pass"],
1602 os.environ, setsigmask=34)
1603 with self.assertRaises(TypeError):
1604 posix.posix_spawn(sys.executable,
1605 [sys.executable, "-c", "pass"],
1606 os.environ, setsigmask=["j"])
1607 with self.assertRaises(ValueError):
1608 posix.posix_spawn(sys.executable,
1609 [sys.executable, "-c", "pass"],
1610 os.environ, setsigmask=[signal.NSIG,
1611 signal.NSIG+1])
1612
1613 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
1614 'need signal.pthread_sigmask()')
1615 def test_setsigdef(self):
1616 original_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
1617 code = textwrap.dedent("""\
1618 import _testcapi, signal
1619 _testcapi.raise_signal(signal.SIGUSR1)""")
1620 try:
1621 pid = posix.posix_spawn(
1622 sys.executable,
1623 [sys.executable, '-c', code],
1624 os.environ,
1625 setsigdef=[signal.SIGUSR1]
1626 )
1627 finally:
1628 signal.signal(signal.SIGUSR1, original_handler)
1629
1630 pid2, status = os.waitpid(pid, 0)
1631 self.assertEqual(pid2, pid)
1632 self.assertTrue(os.WIFSIGNALED(status), status)
1633 self.assertEqual(os.WTERMSIG(status), signal.SIGUSR1)
1634
1635 def test_setsigdef_wrong_type(self):
1636 with self.assertRaises(TypeError):
1637 posix.posix_spawn(sys.executable,
1638 [sys.executable, "-c", "pass"],
1639 os.environ, setsigdef=34)
1640 with self.assertRaises(TypeError):
1641 posix.posix_spawn(sys.executable,
1642 [sys.executable, "-c", "pass"],
1643 os.environ, setsigdef=["j"])
1644 with self.assertRaises(ValueError):
1645 posix.posix_spawn(sys.executable,
1646 [sys.executable, "-c", "pass"],
1647 os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])
1648
1649 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
1650 def test_setscheduler_only_param(self):
1651 policy = os.sched_getscheduler(0)
1652 priority = os.sched_get_priority_min(policy)
1653 code = textwrap.dedent(f"""\
1654 import os
1655 if os.sched_getscheduler(0) != {policy}:
1656 os.exit(101)
1657 if os.sched_getparam(0).sched_priority != {priority}:
1658 os.exit(102)""")
1659 pid = posix.posix_spawn(
1660 sys.executable,
1661 [sys.executable, '-c', code],
1662 os.environ,
1663 scheduler=(None, os.sched_param(priority))
1664 )
1665 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1666
1667 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
1668 def test_setscheduler_with_policy(self):
1669 policy = os.sched_getscheduler(0)
1670 priority = os.sched_get_priority_min(policy)
1671 code = textwrap.dedent(f"""\
1672 import os
1673 if os.sched_getscheduler(0) != {policy}:
1674 os.exit(101)
1675 if os.sched_getparam(0).sched_priority != {priority}:
1676 os.exit(102)""")
1677 pid = posix.posix_spawn(
1678 sys.executable,
1679 [sys.executable, '-c', code],
1680 os.environ,
1681 scheduler=(policy, os.sched_param(priority))
1682 )
1683 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1684
Serhiy Storchakaef347532018-05-01 16:45:04 +03001685 def test_multiple_file_actions(self):
1686 file_actions = [
1687 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1688 (os.POSIX_SPAWN_CLOSE, 0),
1689 (os.POSIX_SPAWN_DUP2, 1, 4),
1690 ]
Victor Stinner03824062018-08-30 01:21:11 +02001691 pid = posix.posix_spawn(self.NOOP_PROGRAM[0],
1692 self.NOOP_PROGRAM,
Serhiy Storchakad700f972018-09-08 14:48:18 +03001693 os.environ,
1694 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001695 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1696
1697 def test_bad_file_actions(self):
Victor Stinner03824062018-08-30 01:21:11 +02001698 args = self.NOOP_PROGRAM
Serhiy Storchakaef347532018-05-01 16:45:04 +03001699 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001700 posix.posix_spawn(args[0], args, os.environ,
1701 file_actions=[None])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001702 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001703 posix.posix_spawn(args[0], args, os.environ,
1704 file_actions=[()])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001705 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001706 posix.posix_spawn(args[0], args, os.environ,
1707 file_actions=[(None,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001708 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001709 posix.posix_spawn(args[0], args, os.environ,
1710 file_actions=[(12345,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001711 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001712 posix.posix_spawn(args[0], args, os.environ,
1713 file_actions=[(os.POSIX_SPAWN_CLOSE,)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001714 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001715 posix.posix_spawn(args[0], args, os.environ,
1716 file_actions=[(os.POSIX_SPAWN_CLOSE, 1, 2)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001717 with self.assertRaises(TypeError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001718 posix.posix_spawn(args[0], args, os.environ,
1719 file_actions=[(os.POSIX_SPAWN_CLOSE, None)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001720 with self.assertRaises(ValueError):
Serhiy Storchakad700f972018-09-08 14:48:18 +03001721 posix.posix_spawn(args[0], args, os.environ,
1722 file_actions=[(os.POSIX_SPAWN_OPEN,
1723 3, __file__ + '\0',
1724 os.O_RDONLY, 0)])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001725
1726 def test_open_file(self):
1727 outfile = support.TESTFN
1728 self.addCleanup(support.unlink, outfile)
1729 script = """if 1:
1730 import sys
1731 sys.stdout.write("hello")
1732 """
1733 file_actions = [
1734 (os.POSIX_SPAWN_OPEN, 1, outfile,
1735 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1736 stat.S_IRUSR | stat.S_IWUSR),
1737 ]
Victor Stinner03824062018-08-30 01:21:11 +02001738 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001739 pid = posix.posix_spawn(args[0], args, os.environ,
1740 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001741 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1742 with open(outfile) as f:
1743 self.assertEqual(f.read(), 'hello')
1744
1745 def test_close_file(self):
1746 closefile = support.TESTFN
1747 self.addCleanup(support.unlink, closefile)
1748 script = f"""if 1:
1749 import os
1750 try:
1751 os.fstat(0)
1752 except OSError as e:
1753 with open({closefile!r}, 'w') as closefile:
1754 closefile.write('is closed %d' % e.errno)
1755 """
Victor Stinner03824062018-08-30 01:21:11 +02001756 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001757 pid = posix.posix_spawn(args[0], args, os.environ,
1758 file_actions=[(os.POSIX_SPAWN_CLOSE, 0),])
Serhiy Storchakaef347532018-05-01 16:45:04 +03001759 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1760 with open(closefile) as f:
1761 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1762
1763 def test_dup2(self):
1764 dupfile = support.TESTFN
1765 self.addCleanup(support.unlink, dupfile)
1766 script = """if 1:
1767 import sys
1768 sys.stdout.write("hello")
1769 """
1770 with open(dupfile, "wb") as childfile:
1771 file_actions = [
1772 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1773 ]
Victor Stinner03824062018-08-30 01:21:11 +02001774 args = self.python_args('-c', script)
Serhiy Storchakad700f972018-09-08 14:48:18 +03001775 pid = posix.posix_spawn(args[0], args, os.environ,
1776 file_actions=file_actions)
Serhiy Storchakaef347532018-05-01 16:45:04 +03001777 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1778 with open(dupfile) as f:
1779 self.assertEqual(f.read(), 'hello')
1780
1781
Neal Norwitze241ce82003-02-17 18:17:05 +00001782def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001783 try:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001784 support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn)
Antoine Pitrou68c95922011-03-20 17:33:57 +01001785 finally:
1786 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001787
1788if __name__ == '__main__':
1789 test_main()