blob: e569f7ae72daaf864a6218185e5befcf280edabd [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
Neal Norwitze241ce82003-02-17 18:17:05 +000011import time
12import os
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020013import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000014import pwd
Benjamin Peterson052a02b2010-08-17 01:27:09 +000015import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070016import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000017import unittest
18import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000019
Ned Deilyba2eab22011-07-26 13:53:55 -070020_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
21 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000022
Serhiy Storchaka9d572732018-07-31 10:24:54 +030023requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
24 'test is only meaningful on 32-bit builds')
25
Neal Norwitze241ce82003-02-17 18:17:05 +000026class PosixTester(unittest.TestCase):
27
28 def setUp(self):
29 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000030 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000031 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070032 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000033 self._warnings_manager = support.check_warnings()
34 self._warnings_manager.__enter__()
35 warnings.filterwarnings('ignore', '.* potential security risk .*',
36 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000037
38 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070039 for teardown_file in self.teardown_files:
40 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000041 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000042
43 def testNoArgFunctions(self):
44 # test posix functions which take no arguments and have
45 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000046 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000047 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000048 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020049 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000050 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000051
Neal Norwitze241ce82003-02-17 18:17:05 +000052 for name in NO_ARG_FUNCTIONS:
53 posix_func = getattr(posix, name, None)
54 if posix_func is not None:
55 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000056 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000057
Serhiy Storchaka43767632013-11-03 21:31:38 +020058 @unittest.skipUnless(hasattr(posix, 'getresuid'),
59 'test needs posix.getresuid()')
60 def test_getresuid(self):
61 user_ids = posix.getresuid()
62 self.assertEqual(len(user_ids), 3)
63 for val in user_ids:
64 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000065
Serhiy Storchaka43767632013-11-03 21:31:38 +020066 @unittest.skipUnless(hasattr(posix, 'getresgid'),
67 'test needs posix.getresgid()')
68 def test_getresgid(self):
69 group_ids = posix.getresgid()
70 self.assertEqual(len(group_ids), 3)
71 for val in group_ids:
72 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000073
Serhiy Storchaka43767632013-11-03 21:31:38 +020074 @unittest.skipUnless(hasattr(posix, 'setresuid'),
75 'test needs posix.setresuid()')
76 def test_setresuid(self):
77 current_user_ids = posix.getresuid()
78 self.assertIsNone(posix.setresuid(*current_user_ids))
79 # -1 means don't change that value.
80 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000081
Serhiy Storchaka43767632013-11-03 21:31:38 +020082 @unittest.skipUnless(hasattr(posix, 'setresuid'),
83 'test needs posix.setresuid()')
84 def test_setresuid_exception(self):
85 # Don't do this test if someone is silly enough to run us as root.
86 current_user_ids = posix.getresuid()
87 if 0 not in current_user_ids:
88 new_user_ids = (current_user_ids[0]+1, -1, -1)
89 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000090
Serhiy Storchaka43767632013-11-03 21:31:38 +020091 @unittest.skipUnless(hasattr(posix, 'setresgid'),
92 'test needs posix.setresgid()')
93 def test_setresgid(self):
94 current_group_ids = posix.getresgid()
95 self.assertIsNone(posix.setresgid(*current_group_ids))
96 # -1 means don't change that value.
97 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000098
Serhiy Storchaka43767632013-11-03 21:31:38 +020099 @unittest.skipUnless(hasattr(posix, 'setresgid'),
100 'test needs posix.setresgid()')
101 def test_setresgid_exception(self):
102 # Don't do this test if someone is silly enough to run us as root.
103 current_group_ids = posix.getresgid()
104 if 0 not in current_group_ids:
105 new_group_ids = (current_group_ids[0]+1, -1, -1)
106 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000107
Antoine Pitroub7572f02009-12-02 20:46:48 +0000108 @unittest.skipUnless(hasattr(posix, 'initgroups'),
109 "test needs os.initgroups()")
110 def test_initgroups(self):
111 # It takes a string and an integer; check that it raises a TypeError
112 # for other argument lists.
113 self.assertRaises(TypeError, posix.initgroups)
114 self.assertRaises(TypeError, posix.initgroups, None)
115 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
116 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
117
118 # If a non-privileged user invokes it, it should fail with OSError
119 # EPERM.
120 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200121 try:
122 name = pwd.getpwuid(posix.getuid()).pw_name
123 except KeyError:
124 # the current UID may not have a pwd entry
125 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000126 try:
127 posix.initgroups(name, 13)
128 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000129 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000130 else:
131 self.fail("Expected OSError to be raised by initgroups")
132
Serhiy Storchaka43767632013-11-03 21:31:38 +0200133 @unittest.skipUnless(hasattr(posix, 'statvfs'),
134 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000135 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200136 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000137
Serhiy Storchaka43767632013-11-03 21:31:38 +0200138 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
139 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000140 def test_fstatvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200141 fp = open(support.TESTFN)
142 try:
143 self.assertTrue(posix.fstatvfs(fp.fileno()))
144 self.assertTrue(posix.statvfs(fp.fileno()))
145 finally:
146 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000147
Serhiy Storchaka43767632013-11-03 21:31:38 +0200148 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
149 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000150 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200151 fp = open(support.TESTFN, 'w+')
152 try:
153 # we need to have some data to truncate
154 fp.write('test')
155 fp.flush()
156 posix.ftruncate(fp.fileno(), 0)
157 finally:
158 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000159
Ross Lagerwall7807c352011-03-17 20:20:30 +0200160 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
161 def test_truncate(self):
162 with open(support.TESTFN, 'w') as fp:
163 fp.write('test')
164 fp.flush()
165 posix.truncate(support.TESTFN, 0)
166
Larry Hastings9cf065c2012-06-22 16:30:09 -0700167 @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 +0200168 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200169 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200170 def test_fexecve(self):
171 fp = os.open(sys.executable, os.O_RDONLY)
172 try:
173 pid = os.fork()
174 if pid == 0:
175 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700176 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200177 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200178 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200179 finally:
180 os.close(fp)
181
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000182
Ross Lagerwall7807c352011-03-17 20:20:30 +0200183 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
184 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
185 def test_waitid(self):
186 pid = os.fork()
187 if pid == 0:
188 os.chdir(os.path.split(sys.executable)[0])
189 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
190 else:
191 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
192 self.assertEqual(pid, res.si_pid)
193
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200194 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700195 def test_register_at_fork(self):
196 with self.assertRaises(TypeError, msg="Positional args not allowed"):
197 os.register_at_fork(lambda: None)
198 with self.assertRaises(TypeError, msg="Args must be callable"):
199 os.register_at_fork(before=2)
200 with self.assertRaises(TypeError, msg="Args must be callable"):
201 os.register_at_fork(after_in_child="three")
202 with self.assertRaises(TypeError, msg="Args must be callable"):
203 os.register_at_fork(after_in_parent=b"Five")
204 with self.assertRaises(TypeError, msg="Args must not be None"):
205 os.register_at_fork(before=None)
206 with self.assertRaises(TypeError, msg="Args must not be None"):
207 os.register_at_fork(after_in_child=None)
208 with self.assertRaises(TypeError, msg="Args must not be None"):
209 os.register_at_fork(after_in_parent=None)
210 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
211 # Ensure a combination of valid and invalid is an error.
212 os.register_at_fork(before=None, after_in_parent=lambda: 3)
213 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
214 # Ensure a combination of valid and invalid is an error.
215 os.register_at_fork(before=lambda: None, after_in_child='')
216 # We test actual registrations in their own process so as not to
217 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200218 code = """if 1:
219 import os
220
221 r, w = os.pipe()
222 fin_r, fin_w = os.pipe()
223
Gregory P. Smith163468a2017-05-29 10:03:41 -0700224 os.register_at_fork(before=lambda: os.write(w, b'A'))
225 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
226 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
227 os.register_at_fork(before=lambda: os.write(w, b'B'),
228 after_in_parent=lambda: os.write(w, b'D'),
229 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200230
231 pid = os.fork()
232 if pid == 0:
233 # At this point, after-forkers have already been executed
234 os.close(w)
235 # Wait for parent to tell us to exit
236 os.read(fin_r, 1)
237 os._exit(0)
238 else:
239 try:
240 os.close(w)
241 with open(r, "rb") as f:
242 data = f.read()
243 assert len(data) == 6, data
244 # Check before-fork callbacks
245 assert data[:2] == b'BA', data
246 # Check after-fork callbacks
247 assert sorted(data[2:]) == list(b'CDEF'), data
248 assert data.index(b'C') < data.index(b'D'), data
249 assert data.index(b'E') < data.index(b'F'), data
250 finally:
251 os.write(fin_w, b'!')
252 """
253 assert_python_ok('-c', code)
254
Ross Lagerwall7807c352011-03-17 20:20:30 +0200255 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
256 def test_lockf(self):
257 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
258 try:
259 os.write(fd, b'test')
260 os.lseek(fd, 0, os.SEEK_SET)
261 posix.lockf(fd, posix.F_LOCK, 4)
262 # section is locked
263 posix.lockf(fd, posix.F_ULOCK, 4)
264 finally:
265 os.close(fd)
266
267 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
268 def test_pread(self):
269 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
270 try:
271 os.write(fd, b'test')
272 os.lseek(fd, 0, os.SEEK_SET)
273 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100274 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200275 self.assertEqual(b'te', posix.read(fd, 2))
276 finally:
277 os.close(fd)
278
Pablo Galindo4defba32018-01-27 16:16:37 +0000279 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
280 def test_preadv(self):
281 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
282 try:
283 os.write(fd, b'test1tt2t3t5t6t6t8')
284 buf = [bytearray(i) for i in [5, 3, 2]]
285 self.assertEqual(posix.preadv(fd, buf, 3), 10)
286 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
287 finally:
288 os.close(fd)
289
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300290 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000291 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
292 def test_preadv_flags(self):
293 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
294 try:
295 os.write(fd, b'test1tt2t3t5t6t6t8')
296 buf = [bytearray(i) for i in [5, 3, 2]]
297 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
298 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
299 finally:
300 os.close(fd)
301
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300302 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
303 @requires_32b
304 def test_preadv_overflow_32bits(self):
305 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
306 try:
307 buf = [bytearray(2**16)] * 2**15
308 with self.assertRaises(OSError) as cm:
309 os.preadv(fd, buf, 0)
310 self.assertEqual(cm.exception.errno, errno.EINVAL)
311 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
312 finally:
313 os.close(fd)
314
Ross Lagerwall7807c352011-03-17 20:20:30 +0200315 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
316 def test_pwrite(self):
317 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
318 try:
319 os.write(fd, b'test')
320 os.lseek(fd, 0, os.SEEK_SET)
321 posix.pwrite(fd, b'xx', 1)
322 self.assertEqual(b'txxt', posix.read(fd, 4))
323 finally:
324 os.close(fd)
325
Pablo Galindo4defba32018-01-27 16:16:37 +0000326 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
327 def test_pwritev(self):
328 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
329 try:
330 os.write(fd, b"xx")
331 os.lseek(fd, 0, os.SEEK_SET)
332 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
333 self.assertEqual(n, 10)
334
335 os.lseek(fd, 0, os.SEEK_SET)
336 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
337 finally:
338 os.close(fd)
339
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300340 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
Pablo Galindo4defba32018-01-27 16:16:37 +0000341 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
342 def test_pwritev_flags(self):
343 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
344 try:
345 os.write(fd,b"xx")
346 os.lseek(fd, 0, os.SEEK_SET)
347 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
348 self.assertEqual(n, 10)
349
350 os.lseek(fd, 0, os.SEEK_SET)
351 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
352 finally:
353 os.close(fd)
354
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300355 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
356 @requires_32b
357 def test_pwritev_overflow_32bits(self):
358 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
359 try:
360 with self.assertRaises(OSError) as cm:
361 os.pwritev(fd, [b"x" * 2**16] * 2**15, 0)
362 self.assertEqual(cm.exception.errno, errno.EINVAL)
363 finally:
364 os.close(fd)
365
Ross Lagerwall7807c352011-03-17 20:20:30 +0200366 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
367 "test needs posix.posix_fallocate()")
368 def test_posix_fallocate(self):
369 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
370 try:
371 posix.posix_fallocate(fd, 0, 10)
372 except OSError as inst:
373 # issue10812, ZFS doesn't appear to support posix_fallocate,
374 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400375 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
376 # often used there.
377 if inst.errno == errno.EINVAL and sys.platform.startswith(
378 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
379 raise unittest.SkipTest("test may fail on ZFS filesystems")
380 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200381 raise
382 finally:
383 os.close(fd)
384
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500385 # issue31106 - posix_fallocate() does not set error in errno.
386 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
387 "test needs posix.posix_fallocate()")
388 def test_posix_fallocate_errno(self):
389 try:
390 posix.posix_fallocate(-42, 0, 10)
391 except OSError as inst:
392 if inst.errno != errno.EBADF:
393 raise
394
Ross Lagerwall7807c352011-03-17 20:20:30 +0200395 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
396 "test needs posix.posix_fadvise()")
397 def test_posix_fadvise(self):
398 fd = os.open(support.TESTFN, os.O_RDONLY)
399 try:
400 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
401 finally:
402 os.close(fd)
403
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500404 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
405 "test needs posix.posix_fadvise()")
406 def test_posix_fadvise_errno(self):
407 try:
408 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
409 except OSError as inst:
410 if inst.errno != errno.EBADF:
411 raise
412
Larry Hastings9cf065c2012-06-22 16:30:09 -0700413 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
414 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200415 now = time.time()
416 fd = os.open(support.TESTFN, os.O_RDONLY)
417 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700418 posix.utime(fd)
419 posix.utime(fd, None)
420 self.assertRaises(TypeError, posix.utime, fd, (None, None))
421 self.assertRaises(TypeError, posix.utime, fd, (now, None))
422 self.assertRaises(TypeError, posix.utime, fd, (None, now))
423 posix.utime(fd, (int(now), int(now)))
424 posix.utime(fd, (now, now))
425 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
426 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
427 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
428 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
429 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
430
Ross Lagerwall7807c352011-03-17 20:20:30 +0200431 finally:
432 os.close(fd)
433
Larry Hastings9cf065c2012-06-22 16:30:09 -0700434 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
435 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200436 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700437 posix.utime(support.TESTFN, None, follow_symlinks=False)
438 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
439 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
440 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
441 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
442 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
443 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200444
445 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
446 def test_writev(self):
447 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
448 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100449 n = os.writev(fd, (b'test1', b'tt2', b't3'))
450 self.assertEqual(n, 10)
451
Ross Lagerwall7807c352011-03-17 20:20:30 +0200452 os.lseek(fd, 0, os.SEEK_SET)
453 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100454
455 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100456 try:
457 size = posix.writev(fd, [])
458 except OSError:
459 # writev(fd, []) raises OSError(22, "Invalid argument")
460 # on OpenIndiana
461 pass
462 else:
463 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200464 finally:
465 os.close(fd)
466
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300467 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
468 @requires_32b
469 def test_writev_overflow_32bits(self):
470 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
471 try:
472 with self.assertRaises(OSError) as cm:
473 os.writev(fd, [b"x" * 2**16] * 2**15)
474 self.assertEqual(cm.exception.errno, errno.EINVAL)
475 finally:
476 os.close(fd)
477
Ross Lagerwall7807c352011-03-17 20:20:30 +0200478 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
479 def test_readv(self):
480 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
481 try:
482 os.write(fd, b'test1tt2t3')
483 os.lseek(fd, 0, os.SEEK_SET)
484 buf = [bytearray(i) for i in [5, 3, 2]]
485 self.assertEqual(posix.readv(fd, buf), 10)
486 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100487
488 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100489 try:
490 size = posix.readv(fd, [])
491 except OSError:
492 # readv(fd, []) raises OSError(22, "Invalid argument")
493 # on OpenIndiana
494 pass
495 else:
496 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200497 finally:
498 os.close(fd)
499
Serhiy Storchaka9d572732018-07-31 10:24:54 +0300500 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
501 @requires_32b
502 def test_readv_overflow_32bits(self):
503 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
504 try:
505 buf = [bytearray(2**16)] * 2**15
506 with self.assertRaises(OSError) as cm:
507 os.readv(fd, buf)
508 self.assertEqual(cm.exception.errno, errno.EINVAL)
509 self.assertEqual(bytes(buf[0]), b'\0'* 2**16)
510 finally:
511 os.close(fd)
512
Serhiy Storchaka43767632013-11-03 21:31:38 +0200513 @unittest.skipUnless(hasattr(posix, 'dup'),
514 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000515 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200516 fp = open(support.TESTFN)
517 try:
518 fd = posix.dup(fp.fileno())
519 self.assertIsInstance(fd, int)
520 os.close(fd)
521 finally:
522 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000523
Serhiy Storchaka43767632013-11-03 21:31:38 +0200524 @unittest.skipUnless(hasattr(posix, 'confstr'),
525 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000526 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200527 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
528 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000529
Serhiy Storchaka43767632013-11-03 21:31:38 +0200530 @unittest.skipUnless(hasattr(posix, 'dup2'),
531 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000532 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200533 fp1 = open(support.TESTFN)
534 fp2 = open(support.TESTFN)
535 try:
536 posix.dup2(fp1.fileno(), fp2.fileno())
537 finally:
538 fp1.close()
539 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000540
Charles-François Natali1e045b12011-05-22 20:42:32 +0200541 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200542 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200543 def test_oscloexec(self):
544 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
545 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200546 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200547
Serhiy Storchaka43767632013-11-03 21:31:38 +0200548 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
549 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000550 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200551 fd = os.open(support.TESTFN,
552 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
553 self.assertRaises(OSError, os.open, support.TESTFN,
554 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
555 os.close(fd)
556
557 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000558 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200559 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000560 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000561 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
562 os.close(fd)
563
Serhiy Storchaka43767632013-11-03 21:31:38 +0200564 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
565 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000566 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200567 fd1 = os.open(support.TESTFN,
568 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
569 fd2 = os.open(support.TESTFN,
570 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
571 os.close(fd2)
572 os.close(fd1)
573
574 if hasattr(posix, "O_EXLOCK"):
575 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000576 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200577 self.assertRaises(OSError, os.open, support.TESTFN,
578 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
579 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000580
Serhiy Storchaka43767632013-11-03 21:31:38 +0200581 @unittest.skipUnless(hasattr(posix, 'fstat'),
582 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000583 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200584 fp = open(support.TESTFN)
585 try:
586 self.assertTrue(posix.fstat(fp.fileno()))
587 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200588
Serhiy Storchaka43767632013-11-03 21:31:38 +0200589 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700590 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200591 posix.stat, float(fp.fileno()))
592 finally:
593 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000594
Serhiy Storchaka43767632013-11-03 21:31:38 +0200595 @unittest.skipUnless(hasattr(posix, 'stat'),
596 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000597 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200598 self.assertTrue(posix.stat(support.TESTFN))
599 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200600
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300601 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700602 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300603 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200604 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700605 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200606 posix.stat, None)
607 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700608 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200609 posix.stat, list(support.TESTFN))
610 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700611 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200612 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000613
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000614 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
615 def test_mkfifo(self):
616 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100617 try:
618 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
619 except PermissionError as e:
620 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000621 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
622
623 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
624 "don't have mknod()/S_IFIFO")
625 def test_mknod(self):
626 # Test using mknod() to create a FIFO (the only use specified
627 # by POSIX).
628 support.unlink(support.TESTFN)
629 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
630 try:
631 posix.mknod(support.TESTFN, mode, 0)
632 except OSError as e:
633 # Some old systems don't allow unprivileged users to use
634 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100635 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000636 else:
637 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
638
Martin Panterbf19d162015-09-09 01:01:13 +0000639 # Keyword arguments are also supported
640 support.unlink(support.TESTFN)
641 try:
642 posix.mknod(path=support.TESTFN, mode=mode, device=0,
643 dir_fd=None)
644 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100645 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000646
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300647 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
648 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
649 def test_makedev(self):
650 st = posix.stat(support.TESTFN)
651 dev = st.st_dev
652 self.assertIsInstance(dev, int)
653 self.assertGreaterEqual(dev, 0)
654
655 major = posix.major(dev)
656 self.assertIsInstance(major, int)
657 self.assertGreaterEqual(major, 0)
658 self.assertEqual(posix.major(dev), major)
659 self.assertRaises(TypeError, posix.major, float(dev))
660 self.assertRaises(TypeError, posix.major)
661 self.assertRaises((ValueError, OverflowError), posix.major, -1)
662
663 minor = posix.minor(dev)
664 self.assertIsInstance(minor, int)
665 self.assertGreaterEqual(minor, 0)
666 self.assertEqual(posix.minor(dev), minor)
667 self.assertRaises(TypeError, posix.minor, float(dev))
668 self.assertRaises(TypeError, posix.minor)
669 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
670
671 self.assertEqual(posix.makedev(major, minor), dev)
672 self.assertRaises(TypeError, posix.makedev, float(major), minor)
673 self.assertRaises(TypeError, posix.makedev, major, float(minor))
674 self.assertRaises(TypeError, posix.makedev, major)
675 self.assertRaises(TypeError, posix.makedev)
676
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200677 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000678 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200679 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200680 if stat_func is not None:
681 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200682 self.assertEqual(stat.st_uid, uid)
683 self.assertEqual(stat.st_gid, gid)
684 uid = os.getuid()
685 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200686 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200687 chown_func(first_param, uid, gid)
688 check_stat(uid, gid)
689 chown_func(first_param, -1, gid)
690 check_stat(uid, gid)
691 chown_func(first_param, uid, -1)
692 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200693
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200694 if uid == 0:
695 # Try an amusingly large uid/gid to make sure we handle
696 # large unsigned values. (chown lets you use any
697 # uid/gid you like, even if they aren't defined.)
698 #
699 # This problem keeps coming up:
700 # http://bugs.python.org/issue1747858
701 # http://bugs.python.org/issue4591
702 # http://bugs.python.org/issue15301
703 # Hopefully the fix in 4591 fixes it for good!
704 #
705 # This part of the test only runs when run as root.
706 # Only scary people run their tests as root.
707
708 big_value = 2**31
709 chown_func(first_param, big_value, big_value)
710 check_stat(big_value, big_value)
711 chown_func(first_param, -1, -1)
712 check_stat(big_value, big_value)
713 chown_func(first_param, uid, gid)
714 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200715 elif platform.system() in ('HP-UX', 'SunOS'):
716 # HP-UX and Solaris can allow a non-root user to chown() to root
717 # (issue #5113)
718 raise unittest.SkipTest("Skipping because of non-standard chown() "
719 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000720 else:
721 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200722 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200723 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200724 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200725 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200726 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200727 self.assertRaises(OSError, chown_func, first_param, -1, 0)
728 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200729 # test illegal types
730 for t in str, float:
731 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
732 check_stat(uid, gid)
733 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
734 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000735
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000736 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
737 def test_chown(self):
738 # raise an OSError if the file does not exist
739 os.unlink(support.TESTFN)
740 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000741
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000742 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200743 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200744 self._test_all_chown_common(posix.chown, support.TESTFN,
745 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000746
747 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
748 def test_fchown(self):
749 os.unlink(support.TESTFN)
750
751 # re-create the file
752 test_file = open(support.TESTFN, 'w')
753 try:
754 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200755 self._test_all_chown_common(posix.fchown, fd,
756 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000757 finally:
758 test_file.close()
759
760 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
761 def test_lchown(self):
762 os.unlink(support.TESTFN)
763 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700764 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200765 self._test_all_chown_common(posix.lchown, support.TESTFN,
766 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000767
Serhiy Storchaka43767632013-11-03 21:31:38 +0200768 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000769 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200770 posix.chdir(os.curdir)
771 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000772
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000773 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300774 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000775
776 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700777 # When listdir is called without argument,
778 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300779 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000780
Larry Hastingsfdaea062012-06-25 04:42:23 -0700781 def test_listdir_bytes(self):
782 # When listdir is called with a bytes object,
783 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300784 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
785
786 def test_listdir_bytes_like(self):
787 for cls in bytearray, memoryview:
788 with self.assertWarns(DeprecationWarning):
789 names = posix.listdir(cls(b'.'))
790 self.assertIn(os.fsencode(support.TESTFN), names)
791 for name in names:
792 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700793
794 @unittest.skipUnless(posix.listdir in os.supports_fd,
795 "test needs fd support for posix.listdir()")
796 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000797 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100798 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000799 self.assertEqual(
800 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700801 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000802 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100803 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100804 self.assertEqual(
805 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700806 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100807 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000808
Serhiy Storchaka43767632013-11-03 21:31:38 +0200809 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000810 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200811 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000812
Serhiy Storchaka43767632013-11-03 21:31:38 +0200813 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000814 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200815 old_mask = posix.umask(0)
816 self.assertIsInstance(old_mask, int)
817 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000818
Serhiy Storchaka43767632013-11-03 21:31:38 +0200819 @unittest.skipUnless(hasattr(posix, 'strerror'),
820 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000821 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200822 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000823
Serhiy Storchaka43767632013-11-03 21:31:38 +0200824 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000825 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200826 reader, writer = posix.pipe()
827 os.close(reader)
828 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000829
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200830 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200831 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200832 def test_pipe2(self):
833 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
834 self.assertRaises(TypeError, os.pipe2, 0, 0)
835
Charles-François Natali368f34b2011-06-06 19:49:47 +0200836 # try calling with flags = 0, like os.pipe()
837 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200838 os.close(r)
839 os.close(w)
840
841 # test flags
842 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
843 self.addCleanup(os.close, r)
844 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200845 self.assertFalse(os.get_inheritable(r))
846 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200847 self.assertFalse(os.get_blocking(r))
848 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200849 # try reading from an empty pipe: this should fail, not block
850 self.assertRaises(OSError, os.read, r, 1)
851 # try a write big enough to fill-up the pipe: this should either
852 # fail or perform a partial write, not block
853 try:
854 os.write(w, b'x' * support.PIPE_MAX_SIZE)
855 except OSError:
856 pass
857
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200858 @support.cpython_only
859 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
860 @support.requires_linux_version(2, 6, 27)
861 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200862 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200863 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200864 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
865 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
866
Serhiy Storchaka43767632013-11-03 21:31:38 +0200867 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000868 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200869 now = time.time()
870 posix.utime(support.TESTFN, None)
871 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
872 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
873 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
874 posix.utime(support.TESTFN, (int(now), int(now)))
875 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000876
Larry Hastings9cf065c2012-06-22 16:30:09 -0700877 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700878 st = os.stat(target_file)
879 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000880
881 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
882 flags = st.st_flags | stat.UF_IMMUTABLE
883 try:
884 chflags_func(target_file, flags, **kwargs)
885 except OSError as err:
886 if err.errno != errno.EOPNOTSUPP:
887 raise
888 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
889 self.skipTest(msg)
890
Ned Deily3eb67d52011-06-28 00:00:28 -0700891 try:
892 new_st = os.stat(target_file)
893 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
894 try:
895 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200896 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700897 self.assertEqual(e.errno, errno.EPERM)
898 finally:
899 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000900
Ned Deily3eb67d52011-06-28 00:00:28 -0700901 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
902 def test_chflags(self):
903 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
904
905 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
906 def test_lchflags_regular_file(self):
907 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700909
910 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
911 def test_lchflags_symlink(self):
912 testfn_st = os.stat(support.TESTFN)
913
914 self.assertTrue(hasattr(testfn_st, 'st_flags'))
915
916 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
917 self.teardown_files.append(_DUMMY_SYMLINK)
918 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
919
Larry Hastings9cf065c2012-06-22 16:30:09 -0700920 def chflags_nofollow(path, flags):
921 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700922
Larry Hastings9cf065c2012-06-22 16:30:09 -0700923 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000924 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
925 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
926 try:
927 fn(_DUMMY_SYMLINK, flags)
928 except OSError as err:
929 if err.errno != errno.EOPNOTSUPP:
930 raise
931 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
932 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 try:
934 new_testfn_st = os.stat(support.TESTFN)
935 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
936
937 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
938 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
939 new_dummy_symlink_st.st_flags)
940 finally:
941 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000942
Guido van Rossum98297ee2007-11-06 21:34:58 +0000943 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000944 if os.name == "nt":
945 item_type = str
946 else:
947 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000948 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000949 self.assertEqual(type(k), item_type)
950 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000951
Serhiy Storchaka77703942017-06-25 07:33:01 +0300952 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
953 def test_putenv(self):
954 with self.assertRaises(ValueError):
955 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
956 with self.assertRaises(ValueError):
957 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
958 with self.assertRaises(ValueError):
959 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
960 with self.assertRaises(ValueError):
961 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
962 with self.assertRaises(ValueError):
963 os.putenv('FRUIT=ORANGE', 'lemon')
964 with self.assertRaises(ValueError):
965 os.putenv(b'FRUIT=ORANGE', b'lemon')
966
Serhiy Storchaka43767632013-11-03 21:31:38 +0200967 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000968 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500969 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
970 curdir = os.getcwd()
971 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000972
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500973 try:
974 os.mkdir(base_path)
975 os.chdir(base_path)
976 except:
977 # Just returning nothing instead of the SkipTest exception, because
978 # the test results in Error in that case. Is that ok?
979 # raise unittest.SkipTest("cannot create directory for testing")
980 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000981
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500982 def _create_and_do_getcwd(dirname, current_path_length = 0):
983 try:
984 os.mkdir(dirname)
985 except:
986 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000987
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500988 os.chdir(dirname)
989 try:
990 os.getcwd()
991 if current_path_length < 1027:
992 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
993 finally:
994 os.chdir('..')
995 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000996
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500997 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000998
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500999 finally:
1000 os.chdir(curdir)
1001 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +00001002
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001003 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
1004 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
1005 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
1006 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +00001007 user = pwd.getpwuid(os.getuid())[0]
1008 group = pwd.getpwuid(os.getuid())[3]
1009 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001010
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02001011
Antoine Pitrou318b8f32011-01-12 18:45:27 +00001012 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001013 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +02001014 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001015 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +02001016 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001017
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001018 try:
1019 idg_groups = set(int(g) for g in groups.split())
1020 except ValueError:
1021 idg_groups = set()
1022 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001023 raise unittest.SkipTest("need working 'id -G'")
1024
Ned Deily028915e2013-02-02 15:08:52 -08001025 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
1026 if sys.platform == 'darwin':
1027 import sysconfig
1028 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -07001029 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -08001030 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
1031
Ronald Oussoren7fb6f512010-08-01 19:18:13 +00001032 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +02001033 # groups, ignoring order, duplicates, and the effective gid.
1034 # #10822/#26944 - It is implementation defined whether
1035 # posix.getgroups() includes the effective gid.
1036 symdiff = idg_groups.symmetric_difference(posix.getgroups())
1037 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001038
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001039 # tests for the posix *at functions follow
1040
Larry Hastings9cf065c2012-06-22 16:30:09 -07001041 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
1042 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001043 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1044 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001045 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001046 finally:
1047 posix.close(f)
1048
Larry Hastings9cf065c2012-06-22 16:30:09 -07001049 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
1050 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001051 os.chmod(support.TESTFN, stat.S_IRUSR)
1052
1053 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1054 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001056
1057 s = posix.stat(support.TESTFN)
1058 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1059 finally:
1060 posix.close(f)
1061
Larry Hastings9cf065c2012-06-22 16:30:09 -07001062 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1063 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001064 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001065 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001066
1067 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1068 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001070 finally:
1071 posix.close(f)
1072
Larry Hastings9cf065c2012-06-22 16:30:09 -07001073 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1074 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001075 support.unlink(support.TESTFN)
1076 with open(support.TESTFN, 'w') as outfile:
1077 outfile.write("testline\n")
1078
1079 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1080 try:
1081 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001082 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001083 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001084 s2 = posix.stat(support.TESTFN, dir_fd=None)
1085 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001086 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001087 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
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=float(f))
1090 self.assertRaises(OverflowError,
1091 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001092 finally:
1093 posix.close(f)
1094
Larry Hastings9cf065c2012-06-22 16:30:09 -07001095 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1096 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001097 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1098 try:
1099 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 posix.utime(support.TESTFN, None, dir_fd=f)
1101 posix.utime(support.TESTFN, dir_fd=f)
1102 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1103 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1104 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1105 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1106 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1107 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1108 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1109 posix.utime(support.TESTFN,
1110 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1111 posix.utime(support.TESTFN, dir_fd=f,
1112 times=(int(now), int((now - int(now)) * 1e9)))
1113
Larry Hastings90867a52012-06-22 17:01:41 -07001114 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001115 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001116 try:
1117 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001118 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001119 # whoops! using both together not supported on this platform.
1120 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001121
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001122 finally:
1123 posix.close(f)
1124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1126 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001127 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1128 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001130 except PermissionError as e:
1131 self.skipTest('posix.link(): %s' % e)
1132 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001133 # should have same inodes
1134 self.assertEqual(posix.stat(support.TESTFN)[1],
1135 posix.stat(support.TESTFN + 'link')[1])
1136 finally:
1137 posix.close(f)
1138 support.unlink(support.TESTFN + 'link')
1139
Larry Hastings9cf065c2012-06-22 16:30:09 -07001140 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1141 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001142 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1143 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001144 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001145 posix.stat(support.TESTFN + 'dir') # should not raise exception
1146 finally:
1147 posix.close(f)
1148 support.rmtree(support.TESTFN + 'dir')
1149
Larry Hastings9cf065c2012-06-22 16:30:09 -07001150 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1151 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1152 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001153 # Test using mknodat() to create a FIFO (the only use specified
1154 # by POSIX).
1155 support.unlink(support.TESTFN)
1156 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1157 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1158 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001159 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001160 except OSError as e:
1161 # Some old systems don't allow unprivileged users to use
1162 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001163 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001164 else:
1165 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1166 finally:
1167 posix.close(f)
1168
Larry Hastings9cf065c2012-06-22 16:30:09 -07001169 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1170 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001171 support.unlink(support.TESTFN)
1172 with open(support.TESTFN, 'w') as outfile:
1173 outfile.write("testline\n")
1174 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001175 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001176 try:
1177 res = posix.read(b, 9).decode(encoding="utf-8")
1178 self.assertEqual("testline\n", res)
1179 finally:
1180 posix.close(a)
1181 posix.close(b)
1182
Larry Hastings9cf065c2012-06-22 16:30:09 -07001183 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1184 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001185 os.symlink(support.TESTFN, support.TESTFN + 'link')
1186 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1187 try:
1188 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001189 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001190 finally:
1191 support.unlink(support.TESTFN + 'link')
1192 posix.close(f)
1193
Larry Hastings9cf065c2012-06-22 16:30:09 -07001194 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1195 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001196 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001197 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001198 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1199 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001200 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001201 except:
1202 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1203 raise
1204 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001205 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001206 finally:
1207 posix.close(f)
1208
Larry Hastings9cf065c2012-06-22 16:30:09 -07001209 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1210 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001211 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1212 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001213 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001214 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1215 finally:
1216 posix.close(f)
1217 support.unlink(support.TESTFN + 'link')
1218
Larry Hastings9cf065c2012-06-22 16:30:09 -07001219 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1220 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001221 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001222 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001223 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001224 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001225 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001226 except:
1227 support.unlink(support.TESTFN + 'del')
1228 raise
1229 else:
1230 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1231 finally:
1232 posix.close(f)
1233
Larry Hastings9cf065c2012-06-22 16:30:09 -07001234 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1235 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001236 support.unlink(support.TESTFN)
1237 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1238 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001239 try:
1240 posix.mkfifo(support.TESTFN,
1241 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1242 except PermissionError as e:
1243 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001244 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1245 finally:
1246 posix.close(f)
1247
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001248 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1249 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001250 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001251 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001252
1253 @requires_sched_h
1254 def test_sched_yield(self):
1255 # This has no error conditions (at least on Linux).
1256 posix.sched_yield()
1257
1258 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001259 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1260 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001261 def test_sched_priority(self):
1262 # Round-robin usually has interesting priorities.
1263 pol = posix.SCHED_RR
1264 lo = posix.sched_get_priority_min(pol)
1265 hi = posix.sched_get_priority_max(pol)
1266 self.assertIsInstance(lo, int)
1267 self.assertIsInstance(hi, int)
1268 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001269 # OSX evidently just returns 15 without checking the argument.
1270 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001271 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1272 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001273
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001274 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001275 def test_get_and_set_scheduler_and_param(self):
1276 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1277 if name.startswith("SCHED_")]
1278 mine = posix.sched_getscheduler(0)
1279 self.assertIn(mine, possible_schedulers)
1280 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001281 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001282 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001283 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001284 raise
1285 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001286 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001287 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1288 self.assertRaises(OSError, posix.sched_getparam, -1)
1289 param = posix.sched_getparam(0)
1290 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001291
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001292 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1293 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1294 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1295 if not sys.platform.startswith(('freebsd', 'netbsd')):
1296 try:
1297 posix.sched_setscheduler(0, mine, param)
1298 posix.sched_setparam(0, param)
1299 except OSError as e:
1300 if e.errno != errno.EPERM:
1301 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001302 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1303
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001304 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1305 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1306 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1307 param = posix.sched_param(None)
1308 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1309 large = 214748364700
1310 param = posix.sched_param(large)
1311 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1312 param = posix.sched_param(sched_priority=-large)
1313 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1314
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001315 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001316 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001317 try:
1318 interval = posix.sched_rr_get_interval(0)
1319 except OSError as e:
1320 # This likely means that sched_rr_get_interval is only valid for
1321 # processes with the SCHED_RR scheduler in effect.
1322 if e.errno != errno.EINVAL:
1323 raise
1324 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001325 self.assertIsInstance(interval, float)
1326 # Reasonable constraints, I think.
1327 self.assertGreaterEqual(interval, 0.)
1328 self.assertLess(interval, 1.)
1329
Benjamin Peterson2740af82011-08-02 17:41:34 -05001330 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001331 def test_sched_getaffinity(self):
1332 mask = posix.sched_getaffinity(0)
1333 self.assertIsInstance(mask, set)
1334 self.assertGreaterEqual(len(mask), 1)
1335 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1336 for cpu in mask:
1337 self.assertIsInstance(cpu, int)
1338 self.assertGreaterEqual(cpu, 0)
1339 self.assertLess(cpu, 1 << 32)
1340
1341 @requires_sched_affinity
1342 def test_sched_setaffinity(self):
1343 mask = posix.sched_getaffinity(0)
1344 if len(mask) > 1:
1345 # Empty masks are forbidden
1346 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001347 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001348 self.assertEqual(posix.sched_getaffinity(0), mask)
1349 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1350 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1351 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001352 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1353
Victor Stinner8b905bd2011-10-25 13:34:04 +02001354 def test_rtld_constants(self):
1355 # check presence of major RTLD_* constants
1356 posix.RTLD_LAZY
1357 posix.RTLD_NOW
1358 posix.RTLD_GLOBAL
1359 posix.RTLD_LOCAL
1360
Jesus Cea60c13dd2012-06-23 02:58:14 +02001361 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1362 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001363 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001364 # Even if the filesystem doesn't report holes,
1365 # if the OS supports it the SEEK_* constants
1366 # will be defined and will have a consistent
1367 # behaviour:
1368 # os.SEEK_DATA = current position
1369 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001370 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001371 fp.write(b"hello")
1372 fp.flush()
1373 size = fp.tell()
1374 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001375 try :
1376 for i in range(size):
1377 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1378 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1379 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1380 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1381 except OSError :
1382 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1383 # but it is not true.
1384 # For instance:
1385 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1386 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001387
Larry Hastingsb0827312014-02-09 22:05:19 -08001388 def test_path_error2(self):
1389 """
1390 Test functions that call path_error2(), providing two filenames in their exceptions.
1391 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001392 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001393 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001394 if function is None:
1395 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001396
Victor Stinnerbed04a72014-10-05 17:37:59 +02001397 for dst in ("noodly2", support.TESTFN):
1398 try:
1399 function('doesnotexistfilename', dst)
1400 except OSError as e:
1401 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1402 break
1403 else:
1404 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001405
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001406 def test_path_with_null_character(self):
1407 fn = support.TESTFN
1408 fn_with_NUL = fn + '\0'
1409 self.addCleanup(support.unlink, fn)
1410 support.unlink(fn)
1411 fd = None
1412 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001413 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001414 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1415 finally:
1416 if fd is not None:
1417 os.close(fd)
1418 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001419 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001420 self.assertFalse(os.path.exists(fn))
1421 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001422 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001423
1424 def test_path_with_null_byte(self):
1425 fn = os.fsencode(support.TESTFN)
1426 fn_with_NUL = fn + b'\0'
1427 self.addCleanup(support.unlink, fn)
1428 support.unlink(fn)
1429 fd = None
1430 try:
1431 with self.assertRaises(ValueError):
1432 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1433 finally:
1434 if fd is not None:
1435 os.close(fd)
1436 self.assertFalse(os.path.exists(fn))
1437 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1438 self.assertFalse(os.path.exists(fn))
1439 open(fn, 'wb').close()
1440 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1441
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001442class PosixGroupsTester(unittest.TestCase):
1443
1444 def setUp(self):
1445 if posix.getuid() != 0:
1446 raise unittest.SkipTest("not enough privileges")
1447 if not hasattr(posix, 'getgroups'):
1448 raise unittest.SkipTest("need posix.getgroups")
1449 if sys.platform == 'darwin':
1450 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1451 self.saved_groups = posix.getgroups()
1452
1453 def tearDown(self):
1454 if hasattr(posix, 'setgroups'):
1455 posix.setgroups(self.saved_groups)
1456 elif hasattr(posix, 'initgroups'):
1457 name = pwd.getpwuid(posix.getuid()).pw_name
1458 posix.initgroups(name, self.saved_groups[0])
1459
1460 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1461 "test needs posix.initgroups()")
1462 def test_initgroups(self):
1463 # find missing group
1464
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001465 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001466 name = pwd.getpwuid(posix.getuid()).pw_name
1467 posix.initgroups(name, g)
1468 self.assertIn(g, posix.getgroups())
1469
1470 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1471 "test needs posix.setgroups()")
1472 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001473 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001474 posix.setgroups(groups)
1475 self.assertListEqual(groups, posix.getgroups())
1476
Serhiy Storchakaef347532018-05-01 16:45:04 +03001477
1478@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1479class TestPosixSpawn(unittest.TestCase):
1480 def test_returns_pid(self):
1481 pidfile = support.TESTFN
1482 self.addCleanup(support.unlink, pidfile)
1483 script = f"""if 1:
1484 import os
1485 with open({pidfile!r}, "w") as pidfile:
1486 pidfile.write(str(os.getpid()))
1487 """
1488 pid = posix.posix_spawn(sys.executable,
1489 [sys.executable, '-c', script],
1490 os.environ)
1491 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1492 with open(pidfile) as f:
1493 self.assertEqual(f.read(), str(pid))
1494
1495 def test_no_such_executable(self):
1496 no_such_executable = 'no_such_executable'
1497 try:
1498 pid = posix.posix_spawn(no_such_executable,
1499 [no_such_executable],
1500 os.environ)
1501 except FileNotFoundError as exc:
1502 self.assertEqual(exc.filename, no_such_executable)
1503 else:
1504 pid2, status = os.waitpid(pid, 0)
1505 self.assertEqual(pid2, pid)
1506 self.assertNotEqual(status, 0)
1507
1508 def test_specify_environment(self):
1509 envfile = support.TESTFN
1510 self.addCleanup(support.unlink, envfile)
1511 script = f"""if 1:
1512 import os
1513 with open({envfile!r}, "w") as envfile:
1514 envfile.write(os.environ['foo'])
1515 """
1516 pid = posix.posix_spawn(sys.executable,
1517 [sys.executable, '-c', script],
Miro Hrončok7ec8f282018-05-11 07:40:43 +02001518 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001519 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1520 with open(envfile) as f:
1521 self.assertEqual(f.read(), 'bar')
1522
1523 def test_empty_file_actions(self):
1524 pid = posix.posix_spawn(
1525 sys.executable,
1526 [sys.executable, '-c', 'pass'],
1527 os.environ,
1528 []
1529 )
1530 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1531
1532 def test_multiple_file_actions(self):
1533 file_actions = [
1534 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1535 (os.POSIX_SPAWN_CLOSE, 0),
1536 (os.POSIX_SPAWN_DUP2, 1, 4),
1537 ]
1538 pid = posix.posix_spawn(sys.executable,
1539 [sys.executable, "-c", "pass"],
1540 os.environ, file_actions)
1541 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1542
1543 def test_bad_file_actions(self):
1544 with self.assertRaises(TypeError):
1545 posix.posix_spawn(sys.executable,
1546 [sys.executable, "-c", "pass"],
1547 os.environ, [None])
1548 with self.assertRaises(TypeError):
1549 posix.posix_spawn(sys.executable,
1550 [sys.executable, "-c", "pass"],
1551 os.environ, [()])
1552 with self.assertRaises(TypeError):
1553 posix.posix_spawn(sys.executable,
1554 [sys.executable, "-c", "pass"],
1555 os.environ, [(None,)])
1556 with self.assertRaises(TypeError):
1557 posix.posix_spawn(sys.executable,
1558 [sys.executable, "-c", "pass"],
1559 os.environ, [(12345,)])
1560 with self.assertRaises(TypeError):
1561 posix.posix_spawn(sys.executable,
1562 [sys.executable, "-c", "pass"],
1563 os.environ, [(os.POSIX_SPAWN_CLOSE,)])
1564 with self.assertRaises(TypeError):
1565 posix.posix_spawn(sys.executable,
1566 [sys.executable, "-c", "pass"],
1567 os.environ, [(os.POSIX_SPAWN_CLOSE, 1, 2)])
1568 with self.assertRaises(TypeError):
1569 posix.posix_spawn(sys.executable,
1570 [sys.executable, "-c", "pass"],
1571 os.environ, [(os.POSIX_SPAWN_CLOSE, None)])
1572 with self.assertRaises(ValueError):
1573 posix.posix_spawn(sys.executable,
1574 [sys.executable, "-c", "pass"],
1575 os.environ,
1576 [(os.POSIX_SPAWN_OPEN, 3, __file__ + '\0',
1577 os.O_RDONLY, 0)])
1578
1579 def test_open_file(self):
1580 outfile = support.TESTFN
1581 self.addCleanup(support.unlink, outfile)
1582 script = """if 1:
1583 import sys
1584 sys.stdout.write("hello")
1585 """
1586 file_actions = [
1587 (os.POSIX_SPAWN_OPEN, 1, outfile,
1588 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1589 stat.S_IRUSR | stat.S_IWUSR),
1590 ]
1591 pid = posix.posix_spawn(sys.executable,
1592 [sys.executable, '-c', script],
1593 os.environ, file_actions)
1594 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1595 with open(outfile) as f:
1596 self.assertEqual(f.read(), 'hello')
1597
1598 def test_close_file(self):
1599 closefile = support.TESTFN
1600 self.addCleanup(support.unlink, closefile)
1601 script = f"""if 1:
1602 import os
1603 try:
1604 os.fstat(0)
1605 except OSError as e:
1606 with open({closefile!r}, 'w') as closefile:
1607 closefile.write('is closed %d' % e.errno)
1608 """
1609 pid = posix.posix_spawn(sys.executable,
1610 [sys.executable, '-c', script],
1611 os.environ,
1612 [(os.POSIX_SPAWN_CLOSE, 0),])
1613 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1614 with open(closefile) as f:
1615 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1616
1617 def test_dup2(self):
1618 dupfile = support.TESTFN
1619 self.addCleanup(support.unlink, dupfile)
1620 script = """if 1:
1621 import sys
1622 sys.stdout.write("hello")
1623 """
1624 with open(dupfile, "wb") as childfile:
1625 file_actions = [
1626 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1627 ]
1628 pid = posix.posix_spawn(sys.executable,
1629 [sys.executable, '-c', script],
1630 os.environ, file_actions)
1631 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1632 with open(dupfile) as f:
1633 self.assertEqual(f.read(), 'hello')
1634
1635
Neal Norwitze241ce82003-02-17 18:17:05 +00001636def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001637 try:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001638 support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn)
Antoine Pitrou68c95922011-03-20 17:33:57 +01001639 finally:
1640 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001641
1642if __name__ == '__main__':
1643 test_main()