blob: 4f6abc6f7d6fd930e4f7b2e431930ac6e4e0e016 [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
23class PosixTester(unittest.TestCase):
24
25 def setUp(self):
26 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000028 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070029 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000030 self._warnings_manager = support.check_warnings()
31 self._warnings_manager.__enter__()
32 warnings.filterwarnings('ignore', '.* potential security risk .*',
33 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070036 for teardown_file in self.teardown_files:
37 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000038 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000039
40 def testNoArgFunctions(self):
41 # test posix functions which take no arguments and have
42 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000043 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000044 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000045 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020046 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000047 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000048
Neal Norwitze241ce82003-02-17 18:17:05 +000049 for name in NO_ARG_FUNCTIONS:
50 posix_func = getattr(posix, name, None)
51 if posix_func is not None:
52 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000053 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000054
Serhiy Storchaka43767632013-11-03 21:31:38 +020055 @unittest.skipUnless(hasattr(posix, 'getresuid'),
56 'test needs posix.getresuid()')
57 def test_getresuid(self):
58 user_ids = posix.getresuid()
59 self.assertEqual(len(user_ids), 3)
60 for val in user_ids:
61 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000062
Serhiy Storchaka43767632013-11-03 21:31:38 +020063 @unittest.skipUnless(hasattr(posix, 'getresgid'),
64 'test needs posix.getresgid()')
65 def test_getresgid(self):
66 group_ids = posix.getresgid()
67 self.assertEqual(len(group_ids), 3)
68 for val in group_ids:
69 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000070
Serhiy Storchaka43767632013-11-03 21:31:38 +020071 @unittest.skipUnless(hasattr(posix, 'setresuid'),
72 'test needs posix.setresuid()')
73 def test_setresuid(self):
74 current_user_ids = posix.getresuid()
75 self.assertIsNone(posix.setresuid(*current_user_ids))
76 # -1 means don't change that value.
77 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000078
Serhiy Storchaka43767632013-11-03 21:31:38 +020079 @unittest.skipUnless(hasattr(posix, 'setresuid'),
80 'test needs posix.setresuid()')
81 def test_setresuid_exception(self):
82 # Don't do this test if someone is silly enough to run us as root.
83 current_user_ids = posix.getresuid()
84 if 0 not in current_user_ids:
85 new_user_ids = (current_user_ids[0]+1, -1, -1)
86 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000087
Serhiy Storchaka43767632013-11-03 21:31:38 +020088 @unittest.skipUnless(hasattr(posix, 'setresgid'),
89 'test needs posix.setresgid()')
90 def test_setresgid(self):
91 current_group_ids = posix.getresgid()
92 self.assertIsNone(posix.setresgid(*current_group_ids))
93 # -1 means don't change that value.
94 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000095
Serhiy Storchaka43767632013-11-03 21:31:38 +020096 @unittest.skipUnless(hasattr(posix, 'setresgid'),
97 'test needs posix.setresgid()')
98 def test_setresgid_exception(self):
99 # Don't do this test if someone is silly enough to run us as root.
100 current_group_ids = posix.getresgid()
101 if 0 not in current_group_ids:
102 new_group_ids = (current_group_ids[0]+1, -1, -1)
103 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000104
Antoine Pitroub7572f02009-12-02 20:46:48 +0000105 @unittest.skipUnless(hasattr(posix, 'initgroups'),
106 "test needs os.initgroups()")
107 def test_initgroups(self):
108 # It takes a string and an integer; check that it raises a TypeError
109 # for other argument lists.
110 self.assertRaises(TypeError, posix.initgroups)
111 self.assertRaises(TypeError, posix.initgroups, None)
112 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
113 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
114
115 # If a non-privileged user invokes it, it should fail with OSError
116 # EPERM.
117 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200118 try:
119 name = pwd.getpwuid(posix.getuid()).pw_name
120 except KeyError:
121 # the current UID may not have a pwd entry
122 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000123 try:
124 posix.initgroups(name, 13)
125 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000126 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000127 else:
128 self.fail("Expected OSError to be raised by initgroups")
129
Serhiy Storchaka43767632013-11-03 21:31:38 +0200130 @unittest.skipUnless(hasattr(posix, 'statvfs'),
131 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000132 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200133 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000134
Serhiy Storchaka43767632013-11-03 21:31:38 +0200135 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
136 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000137 def test_fstatvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200138 fp = open(support.TESTFN)
139 try:
140 self.assertTrue(posix.fstatvfs(fp.fileno()))
141 self.assertTrue(posix.statvfs(fp.fileno()))
142 finally:
143 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000144
Serhiy Storchaka43767632013-11-03 21:31:38 +0200145 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
146 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200148 fp = open(support.TESTFN, 'w+')
149 try:
150 # we need to have some data to truncate
151 fp.write('test')
152 fp.flush()
153 posix.ftruncate(fp.fileno(), 0)
154 finally:
155 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000156
Ross Lagerwall7807c352011-03-17 20:20:30 +0200157 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
158 def test_truncate(self):
159 with open(support.TESTFN, 'w') as fp:
160 fp.write('test')
161 fp.flush()
162 posix.truncate(support.TESTFN, 0)
163
Larry Hastings9cf065c2012-06-22 16:30:09 -0700164 @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 +0200165 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200166 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200167 def test_fexecve(self):
168 fp = os.open(sys.executable, os.O_RDONLY)
169 try:
170 pid = os.fork()
171 if pid == 0:
172 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700173 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200174 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200175 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200176 finally:
177 os.close(fp)
178
Pablo Galindo6c6ddf92018-01-29 01:56:10 +0000179
Ross Lagerwall7807c352011-03-17 20:20:30 +0200180 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
181 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
182 def test_waitid(self):
183 pid = os.fork()
184 if pid == 0:
185 os.chdir(os.path.split(sys.executable)[0])
186 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
187 else:
188 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
189 self.assertEqual(pid, res.si_pid)
190
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200191 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700192 def test_register_at_fork(self):
193 with self.assertRaises(TypeError, msg="Positional args not allowed"):
194 os.register_at_fork(lambda: None)
195 with self.assertRaises(TypeError, msg="Args must be callable"):
196 os.register_at_fork(before=2)
197 with self.assertRaises(TypeError, msg="Args must be callable"):
198 os.register_at_fork(after_in_child="three")
199 with self.assertRaises(TypeError, msg="Args must be callable"):
200 os.register_at_fork(after_in_parent=b"Five")
201 with self.assertRaises(TypeError, msg="Args must not be None"):
202 os.register_at_fork(before=None)
203 with self.assertRaises(TypeError, msg="Args must not be None"):
204 os.register_at_fork(after_in_child=None)
205 with self.assertRaises(TypeError, msg="Args must not be None"):
206 os.register_at_fork(after_in_parent=None)
207 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
208 # Ensure a combination of valid and invalid is an error.
209 os.register_at_fork(before=None, after_in_parent=lambda: 3)
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=lambda: None, after_in_child='')
213 # We test actual registrations in their own process so as not to
214 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200215 code = """if 1:
216 import os
217
218 r, w = os.pipe()
219 fin_r, fin_w = os.pipe()
220
Gregory P. Smith163468a2017-05-29 10:03:41 -0700221 os.register_at_fork(before=lambda: os.write(w, b'A'))
222 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
223 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
224 os.register_at_fork(before=lambda: os.write(w, b'B'),
225 after_in_parent=lambda: os.write(w, b'D'),
226 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200227
228 pid = os.fork()
229 if pid == 0:
230 # At this point, after-forkers have already been executed
231 os.close(w)
232 # Wait for parent to tell us to exit
233 os.read(fin_r, 1)
234 os._exit(0)
235 else:
236 try:
237 os.close(w)
238 with open(r, "rb") as f:
239 data = f.read()
240 assert len(data) == 6, data
241 # Check before-fork callbacks
242 assert data[:2] == b'BA', data
243 # Check after-fork callbacks
244 assert sorted(data[2:]) == list(b'CDEF'), data
245 assert data.index(b'C') < data.index(b'D'), data
246 assert data.index(b'E') < data.index(b'F'), data
247 finally:
248 os.write(fin_w, b'!')
249 """
250 assert_python_ok('-c', code)
251
Ross Lagerwall7807c352011-03-17 20:20:30 +0200252 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
253 def test_lockf(self):
254 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
255 try:
256 os.write(fd, b'test')
257 os.lseek(fd, 0, os.SEEK_SET)
258 posix.lockf(fd, posix.F_LOCK, 4)
259 # section is locked
260 posix.lockf(fd, posix.F_ULOCK, 4)
261 finally:
262 os.close(fd)
263
264 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
265 def test_pread(self):
266 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
267 try:
268 os.write(fd, b'test')
269 os.lseek(fd, 0, os.SEEK_SET)
270 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100271 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200272 self.assertEqual(b'te', posix.read(fd, 2))
273 finally:
274 os.close(fd)
275
Pablo Galindo4defba32018-01-27 16:16:37 +0000276 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
277 def test_preadv(self):
278 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
279 try:
280 os.write(fd, b'test1tt2t3t5t6t6t8')
281 buf = [bytearray(i) for i in [5, 3, 2]]
282 self.assertEqual(posix.preadv(fd, buf, 3), 10)
283 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
284 finally:
285 os.close(fd)
286
287 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
288 def test_preadv_flags(self):
289 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
290 try:
291 os.write(fd, b'test1tt2t3t5t6t6t8')
292 buf = [bytearray(i) for i in [5, 3, 2]]
293 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
294 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
295 finally:
296 os.close(fd)
297
Ross Lagerwall7807c352011-03-17 20:20:30 +0200298 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
299 def test_pwrite(self):
300 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
301 try:
302 os.write(fd, b'test')
303 os.lseek(fd, 0, os.SEEK_SET)
304 posix.pwrite(fd, b'xx', 1)
305 self.assertEqual(b'txxt', posix.read(fd, 4))
306 finally:
307 os.close(fd)
308
Pablo Galindo4defba32018-01-27 16:16:37 +0000309 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
310 def test_pwritev(self):
311 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
312 try:
313 os.write(fd, b"xx")
314 os.lseek(fd, 0, os.SEEK_SET)
315 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
316 self.assertEqual(n, 10)
317
318 os.lseek(fd, 0, os.SEEK_SET)
319 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
320 finally:
321 os.close(fd)
322
323 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
324 def test_pwritev_flags(self):
325 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
326 try:
327 os.write(fd,b"xx")
328 os.lseek(fd, 0, os.SEEK_SET)
329 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
330 self.assertEqual(n, 10)
331
332 os.lseek(fd, 0, os.SEEK_SET)
333 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
334 finally:
335 os.close(fd)
336
Ross Lagerwall7807c352011-03-17 20:20:30 +0200337 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
338 "test needs posix.posix_fallocate()")
339 def test_posix_fallocate(self):
340 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
341 try:
342 posix.posix_fallocate(fd, 0, 10)
343 except OSError as inst:
344 # issue10812, ZFS doesn't appear to support posix_fallocate,
345 # so skip Solaris-based since they are likely to have ZFS.
Ned Deily09c4a7d2018-05-26 16:30:46 -0400346 # issue33655: Also ignore EINVAL on *BSD since ZFS is also
347 # often used there.
348 if inst.errno == errno.EINVAL and sys.platform.startswith(
349 ('sunos', 'freebsd', 'netbsd', 'openbsd', 'gnukfreebsd')):
350 raise unittest.SkipTest("test may fail on ZFS filesystems")
351 else:
Ross Lagerwall7807c352011-03-17 20:20:30 +0200352 raise
353 finally:
354 os.close(fd)
355
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500356 # issue31106 - posix_fallocate() does not set error in errno.
357 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
358 "test needs posix.posix_fallocate()")
359 def test_posix_fallocate_errno(self):
360 try:
361 posix.posix_fallocate(-42, 0, 10)
362 except OSError as inst:
363 if inst.errno != errno.EBADF:
364 raise
365
Ross Lagerwall7807c352011-03-17 20:20:30 +0200366 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
367 "test needs posix.posix_fadvise()")
368 def test_posix_fadvise(self):
369 fd = os.open(support.TESTFN, os.O_RDONLY)
370 try:
371 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
372 finally:
373 os.close(fd)
374
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500375 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
376 "test needs posix.posix_fadvise()")
377 def test_posix_fadvise_errno(self):
378 try:
379 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
380 except OSError as inst:
381 if inst.errno != errno.EBADF:
382 raise
383
Larry Hastings9cf065c2012-06-22 16:30:09 -0700384 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
385 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200386 now = time.time()
387 fd = os.open(support.TESTFN, os.O_RDONLY)
388 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700389 posix.utime(fd)
390 posix.utime(fd, None)
391 self.assertRaises(TypeError, posix.utime, fd, (None, None))
392 self.assertRaises(TypeError, posix.utime, fd, (now, None))
393 self.assertRaises(TypeError, posix.utime, fd, (None, now))
394 posix.utime(fd, (int(now), int(now)))
395 posix.utime(fd, (now, now))
396 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
397 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
398 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
399 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
400 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
401
Ross Lagerwall7807c352011-03-17 20:20:30 +0200402 finally:
403 os.close(fd)
404
Larry Hastings9cf065c2012-06-22 16:30:09 -0700405 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
406 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200407 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700408 posix.utime(support.TESTFN, None, follow_symlinks=False)
409 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
410 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
411 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
412 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
413 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
414 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200415
416 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
417 def test_writev(self):
418 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
419 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100420 n = os.writev(fd, (b'test1', b'tt2', b't3'))
421 self.assertEqual(n, 10)
422
Ross Lagerwall7807c352011-03-17 20:20:30 +0200423 os.lseek(fd, 0, os.SEEK_SET)
424 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100425
426 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100427 try:
428 size = posix.writev(fd, [])
429 except OSError:
430 # writev(fd, []) raises OSError(22, "Invalid argument")
431 # on OpenIndiana
432 pass
433 else:
434 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200435 finally:
436 os.close(fd)
437
438 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
439 def test_readv(self):
440 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
441 try:
442 os.write(fd, b'test1tt2t3')
443 os.lseek(fd, 0, os.SEEK_SET)
444 buf = [bytearray(i) for i in [5, 3, 2]]
445 self.assertEqual(posix.readv(fd, buf), 10)
446 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100447
448 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100449 try:
450 size = posix.readv(fd, [])
451 except OSError:
452 # readv(fd, []) raises OSError(22, "Invalid argument")
453 # on OpenIndiana
454 pass
455 else:
456 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200457 finally:
458 os.close(fd)
459
Serhiy Storchaka43767632013-11-03 21:31:38 +0200460 @unittest.skipUnless(hasattr(posix, 'dup'),
461 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000462 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200463 fp = open(support.TESTFN)
464 try:
465 fd = posix.dup(fp.fileno())
466 self.assertIsInstance(fd, int)
467 os.close(fd)
468 finally:
469 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000470
Serhiy Storchaka43767632013-11-03 21:31:38 +0200471 @unittest.skipUnless(hasattr(posix, 'confstr'),
472 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000473 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200474 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
475 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000476
Serhiy Storchaka43767632013-11-03 21:31:38 +0200477 @unittest.skipUnless(hasattr(posix, 'dup2'),
478 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000479 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200480 fp1 = open(support.TESTFN)
481 fp2 = open(support.TESTFN)
482 try:
483 posix.dup2(fp1.fileno(), fp2.fileno())
484 finally:
485 fp1.close()
486 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000487
Charles-François Natali1e045b12011-05-22 20:42:32 +0200488 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200489 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200490 def test_oscloexec(self):
491 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
492 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200493 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200494
Serhiy Storchaka43767632013-11-03 21:31:38 +0200495 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
496 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000497 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200498 fd = os.open(support.TESTFN,
499 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
500 self.assertRaises(OSError, os.open, support.TESTFN,
501 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
502 os.close(fd)
503
504 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000505 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200506 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000507 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000508 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
509 os.close(fd)
510
Serhiy Storchaka43767632013-11-03 21:31:38 +0200511 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
512 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000513 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200514 fd1 = os.open(support.TESTFN,
515 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
516 fd2 = os.open(support.TESTFN,
517 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
518 os.close(fd2)
519 os.close(fd1)
520
521 if hasattr(posix, "O_EXLOCK"):
522 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000523 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200524 self.assertRaises(OSError, os.open, support.TESTFN,
525 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
526 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000527
Serhiy Storchaka43767632013-11-03 21:31:38 +0200528 @unittest.skipUnless(hasattr(posix, 'fstat'),
529 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000530 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200531 fp = open(support.TESTFN)
532 try:
533 self.assertTrue(posix.fstat(fp.fileno()))
534 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200535
Serhiy Storchaka43767632013-11-03 21:31:38 +0200536 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700537 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200538 posix.stat, float(fp.fileno()))
539 finally:
540 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000541
Serhiy Storchaka43767632013-11-03 21:31:38 +0200542 @unittest.skipUnless(hasattr(posix, 'stat'),
543 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000544 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200545 self.assertTrue(posix.stat(support.TESTFN))
546 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200547
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300548 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700549 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300550 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200551 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700552 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200553 posix.stat, None)
554 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700555 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200556 posix.stat, list(support.TESTFN))
557 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700558 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200559 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000560
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000561 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
562 def test_mkfifo(self):
563 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100564 try:
565 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
566 except PermissionError as e:
567 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000568 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
569
570 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
571 "don't have mknod()/S_IFIFO")
572 def test_mknod(self):
573 # Test using mknod() to create a FIFO (the only use specified
574 # by POSIX).
575 support.unlink(support.TESTFN)
576 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
577 try:
578 posix.mknod(support.TESTFN, mode, 0)
579 except OSError as e:
580 # Some old systems don't allow unprivileged users to use
581 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100582 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000583 else:
584 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
585
Martin Panterbf19d162015-09-09 01:01:13 +0000586 # Keyword arguments are also supported
587 support.unlink(support.TESTFN)
588 try:
589 posix.mknod(path=support.TESTFN, mode=mode, device=0,
590 dir_fd=None)
591 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100592 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000593
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300594 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
595 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
596 def test_makedev(self):
597 st = posix.stat(support.TESTFN)
598 dev = st.st_dev
599 self.assertIsInstance(dev, int)
600 self.assertGreaterEqual(dev, 0)
601
602 major = posix.major(dev)
603 self.assertIsInstance(major, int)
604 self.assertGreaterEqual(major, 0)
605 self.assertEqual(posix.major(dev), major)
606 self.assertRaises(TypeError, posix.major, float(dev))
607 self.assertRaises(TypeError, posix.major)
608 self.assertRaises((ValueError, OverflowError), posix.major, -1)
609
610 minor = posix.minor(dev)
611 self.assertIsInstance(minor, int)
612 self.assertGreaterEqual(minor, 0)
613 self.assertEqual(posix.minor(dev), minor)
614 self.assertRaises(TypeError, posix.minor, float(dev))
615 self.assertRaises(TypeError, posix.minor)
616 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
617
618 self.assertEqual(posix.makedev(major, minor), dev)
619 self.assertRaises(TypeError, posix.makedev, float(major), minor)
620 self.assertRaises(TypeError, posix.makedev, major, float(minor))
621 self.assertRaises(TypeError, posix.makedev, major)
622 self.assertRaises(TypeError, posix.makedev)
623
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000625 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200626 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200627 if stat_func is not None:
628 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200629 self.assertEqual(stat.st_uid, uid)
630 self.assertEqual(stat.st_gid, gid)
631 uid = os.getuid()
632 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200633 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200634 chown_func(first_param, uid, gid)
635 check_stat(uid, gid)
636 chown_func(first_param, -1, gid)
637 check_stat(uid, gid)
638 chown_func(first_param, uid, -1)
639 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200640
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200641 if uid == 0:
642 # Try an amusingly large uid/gid to make sure we handle
643 # large unsigned values. (chown lets you use any
644 # uid/gid you like, even if they aren't defined.)
645 #
646 # This problem keeps coming up:
647 # http://bugs.python.org/issue1747858
648 # http://bugs.python.org/issue4591
649 # http://bugs.python.org/issue15301
650 # Hopefully the fix in 4591 fixes it for good!
651 #
652 # This part of the test only runs when run as root.
653 # Only scary people run their tests as root.
654
655 big_value = 2**31
656 chown_func(first_param, big_value, big_value)
657 check_stat(big_value, big_value)
658 chown_func(first_param, -1, -1)
659 check_stat(big_value, big_value)
660 chown_func(first_param, uid, gid)
661 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200662 elif platform.system() in ('HP-UX', 'SunOS'):
663 # HP-UX and Solaris can allow a non-root user to chown() to root
664 # (issue #5113)
665 raise unittest.SkipTest("Skipping because of non-standard chown() "
666 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000667 else:
668 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200669 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200670 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200671 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200672 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200673 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200674 self.assertRaises(OSError, chown_func, first_param, -1, 0)
675 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200676 # test illegal types
677 for t in str, float:
678 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
679 check_stat(uid, gid)
680 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
681 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000682
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000683 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
684 def test_chown(self):
685 # raise an OSError if the file does not exist
686 os.unlink(support.TESTFN)
687 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000688
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000689 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200690 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200691 self._test_all_chown_common(posix.chown, support.TESTFN,
692 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000693
694 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
695 def test_fchown(self):
696 os.unlink(support.TESTFN)
697
698 # re-create the file
699 test_file = open(support.TESTFN, 'w')
700 try:
701 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200702 self._test_all_chown_common(posix.fchown, fd,
703 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000704 finally:
705 test_file.close()
706
707 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
708 def test_lchown(self):
709 os.unlink(support.TESTFN)
710 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700711 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200712 self._test_all_chown_common(posix.lchown, support.TESTFN,
713 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000714
Serhiy Storchaka43767632013-11-03 21:31:38 +0200715 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000716 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200717 posix.chdir(os.curdir)
718 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000719
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000720 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300721 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000722
723 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700724 # When listdir is called without argument,
725 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300726 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000727
Larry Hastingsfdaea062012-06-25 04:42:23 -0700728 def test_listdir_bytes(self):
729 # When listdir is called with a bytes object,
730 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300731 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
732
733 def test_listdir_bytes_like(self):
734 for cls in bytearray, memoryview:
735 with self.assertWarns(DeprecationWarning):
736 names = posix.listdir(cls(b'.'))
737 self.assertIn(os.fsencode(support.TESTFN), names)
738 for name in names:
739 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700740
741 @unittest.skipUnless(posix.listdir in os.supports_fd,
742 "test needs fd support for posix.listdir()")
743 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000744 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100745 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000746 self.assertEqual(
747 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700748 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000749 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100750 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100751 self.assertEqual(
752 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700753 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100754 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000755
Serhiy Storchaka43767632013-11-03 21:31:38 +0200756 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000757 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200758 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000759
Serhiy Storchaka43767632013-11-03 21:31:38 +0200760 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000761 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200762 old_mask = posix.umask(0)
763 self.assertIsInstance(old_mask, int)
764 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000765
Serhiy Storchaka43767632013-11-03 21:31:38 +0200766 @unittest.skipUnless(hasattr(posix, 'strerror'),
767 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000768 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200769 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000770
Serhiy Storchaka43767632013-11-03 21:31:38 +0200771 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000772 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200773 reader, writer = posix.pipe()
774 os.close(reader)
775 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000776
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200777 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200778 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200779 def test_pipe2(self):
780 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
781 self.assertRaises(TypeError, os.pipe2, 0, 0)
782
Charles-François Natali368f34b2011-06-06 19:49:47 +0200783 # try calling with flags = 0, like os.pipe()
784 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200785 os.close(r)
786 os.close(w)
787
788 # test flags
789 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
790 self.addCleanup(os.close, r)
791 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200792 self.assertFalse(os.get_inheritable(r))
793 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200794 self.assertFalse(os.get_blocking(r))
795 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200796 # try reading from an empty pipe: this should fail, not block
797 self.assertRaises(OSError, os.read, r, 1)
798 # try a write big enough to fill-up the pipe: this should either
799 # fail or perform a partial write, not block
800 try:
801 os.write(w, b'x' * support.PIPE_MAX_SIZE)
802 except OSError:
803 pass
804
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200805 @support.cpython_only
806 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
807 @support.requires_linux_version(2, 6, 27)
808 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200809 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200810 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200811 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
812 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
813
Serhiy Storchaka43767632013-11-03 21:31:38 +0200814 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000815 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200816 now = time.time()
817 posix.utime(support.TESTFN, None)
818 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
819 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
820 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
821 posix.utime(support.TESTFN, (int(now), int(now)))
822 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000823
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700825 st = os.stat(target_file)
826 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000827
828 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
829 flags = st.st_flags | stat.UF_IMMUTABLE
830 try:
831 chflags_func(target_file, flags, **kwargs)
832 except OSError as err:
833 if err.errno != errno.EOPNOTSUPP:
834 raise
835 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
836 self.skipTest(msg)
837
Ned Deily3eb67d52011-06-28 00:00:28 -0700838 try:
839 new_st = os.stat(target_file)
840 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
841 try:
842 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200843 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700844 self.assertEqual(e.errno, errno.EPERM)
845 finally:
846 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000847
Ned Deily3eb67d52011-06-28 00:00:28 -0700848 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
849 def test_chflags(self):
850 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
851
852 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
853 def test_lchflags_regular_file(self):
854 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700856
857 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
858 def test_lchflags_symlink(self):
859 testfn_st = os.stat(support.TESTFN)
860
861 self.assertTrue(hasattr(testfn_st, 'st_flags'))
862
863 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
864 self.teardown_files.append(_DUMMY_SYMLINK)
865 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
866
Larry Hastings9cf065c2012-06-22 16:30:09 -0700867 def chflags_nofollow(path, flags):
868 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700869
Larry Hastings9cf065c2012-06-22 16:30:09 -0700870 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000871 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
872 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
873 try:
874 fn(_DUMMY_SYMLINK, flags)
875 except OSError as err:
876 if err.errno != errno.EOPNOTSUPP:
877 raise
878 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
879 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 try:
881 new_testfn_st = os.stat(support.TESTFN)
882 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
883
884 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
885 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
886 new_dummy_symlink_st.st_flags)
887 finally:
888 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000889
Guido van Rossum98297ee2007-11-06 21:34:58 +0000890 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000891 if os.name == "nt":
892 item_type = str
893 else:
894 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000895 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000896 self.assertEqual(type(k), item_type)
897 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000898
Serhiy Storchaka77703942017-06-25 07:33:01 +0300899 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
900 def test_putenv(self):
901 with self.assertRaises(ValueError):
902 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
903 with self.assertRaises(ValueError):
904 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
905 with self.assertRaises(ValueError):
906 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
907 with self.assertRaises(ValueError):
908 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
909 with self.assertRaises(ValueError):
910 os.putenv('FRUIT=ORANGE', 'lemon')
911 with self.assertRaises(ValueError):
912 os.putenv(b'FRUIT=ORANGE', b'lemon')
913
Serhiy Storchaka43767632013-11-03 21:31:38 +0200914 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000915 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500916 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
917 curdir = os.getcwd()
918 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000919
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500920 try:
921 os.mkdir(base_path)
922 os.chdir(base_path)
923 except:
924 # Just returning nothing instead of the SkipTest exception, because
925 # the test results in Error in that case. Is that ok?
926 # raise unittest.SkipTest("cannot create directory for testing")
927 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000928
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500929 def _create_and_do_getcwd(dirname, current_path_length = 0):
930 try:
931 os.mkdir(dirname)
932 except:
933 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000934
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500935 os.chdir(dirname)
936 try:
937 os.getcwd()
938 if current_path_length < 1027:
939 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
940 finally:
941 os.chdir('..')
942 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000943
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500944 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000945
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500946 finally:
947 os.chdir(curdir)
948 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000949
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200950 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
951 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
952 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
953 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +0000954 user = pwd.getpwuid(os.getuid())[0]
955 group = pwd.getpwuid(os.getuid())[3]
956 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200957
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200958
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000959 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000960 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +0200961 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000962 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200963 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000964
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200965 try:
966 idg_groups = set(int(g) for g in groups.split())
967 except ValueError:
968 idg_groups = set()
969 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000970 raise unittest.SkipTest("need working 'id -G'")
971
Ned Deily028915e2013-02-02 15:08:52 -0800972 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
973 if sys.platform == 'darwin':
974 import sysconfig
975 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -0700976 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -0800977 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
978
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000979 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200980 # groups, ignoring order, duplicates, and the effective gid.
981 # #10822/#26944 - It is implementation defined whether
982 # posix.getgroups() includes the effective gid.
983 symdiff = idg_groups.symmetric_difference(posix.getgroups())
984 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000985
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000986 # tests for the posix *at functions follow
987
Larry Hastings9cf065c2012-06-22 16:30:09 -0700988 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
989 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000990 f = posix.open(posix.getcwd(), posix.O_RDONLY)
991 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700992 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000993 finally:
994 posix.close(f)
995
Larry Hastings9cf065c2012-06-22 16:30:09 -0700996 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
997 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000998 os.chmod(support.TESTFN, stat.S_IRUSR)
999
1000 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1001 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001003
1004 s = posix.stat(support.TESTFN)
1005 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1006 finally:
1007 posix.close(f)
1008
Larry Hastings9cf065c2012-06-22 16:30:09 -07001009 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1010 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001011 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001012 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001013
1014 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1015 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001016 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001017 finally:
1018 posix.close(f)
1019
Larry Hastings9cf065c2012-06-22 16:30:09 -07001020 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1021 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001022 support.unlink(support.TESTFN)
1023 with open(support.TESTFN, 'w') as outfile:
1024 outfile.write("testline\n")
1025
1026 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1027 try:
1028 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001029 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001030 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001031 s2 = posix.stat(support.TESTFN, dir_fd=None)
1032 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001033 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001034 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001035 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001036 posix.stat, support.TESTFN, dir_fd=float(f))
1037 self.assertRaises(OverflowError,
1038 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001039 finally:
1040 posix.close(f)
1041
Larry Hastings9cf065c2012-06-22 16:30:09 -07001042 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1043 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001044 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1045 try:
1046 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001047 posix.utime(support.TESTFN, None, dir_fd=f)
1048 posix.utime(support.TESTFN, dir_fd=f)
1049 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1050 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1051 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1052 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1053 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1054 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1055 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1056 posix.utime(support.TESTFN,
1057 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1058 posix.utime(support.TESTFN, dir_fd=f,
1059 times=(int(now), int((now - int(now)) * 1e9)))
1060
Larry Hastings90867a52012-06-22 17:01:41 -07001061 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001062 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001063 try:
1064 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001065 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001066 # whoops! using both together not supported on this platform.
1067 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001068
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001069 finally:
1070 posix.close(f)
1071
Larry Hastings9cf065c2012-06-22 16:30:09 -07001072 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1073 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001074 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1075 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001077 except PermissionError as e:
1078 self.skipTest('posix.link(): %s' % e)
1079 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001080 # should have same inodes
1081 self.assertEqual(posix.stat(support.TESTFN)[1],
1082 posix.stat(support.TESTFN + 'link')[1])
1083 finally:
1084 posix.close(f)
1085 support.unlink(support.TESTFN + 'link')
1086
Larry Hastings9cf065c2012-06-22 16:30:09 -07001087 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1088 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001089 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1090 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001092 posix.stat(support.TESTFN + 'dir') # should not raise exception
1093 finally:
1094 posix.close(f)
1095 support.rmtree(support.TESTFN + 'dir')
1096
Larry Hastings9cf065c2012-06-22 16:30:09 -07001097 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1098 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1099 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001100 # Test using mknodat() to create a FIFO (the only use specified
1101 # by POSIX).
1102 support.unlink(support.TESTFN)
1103 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1104 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1105 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001107 except OSError as e:
1108 # Some old systems don't allow unprivileged users to use
1109 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001110 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001111 else:
1112 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1113 finally:
1114 posix.close(f)
1115
Larry Hastings9cf065c2012-06-22 16:30:09 -07001116 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1117 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001118 support.unlink(support.TESTFN)
1119 with open(support.TESTFN, 'w') as outfile:
1120 outfile.write("testline\n")
1121 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001122 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001123 try:
1124 res = posix.read(b, 9).decode(encoding="utf-8")
1125 self.assertEqual("testline\n", res)
1126 finally:
1127 posix.close(a)
1128 posix.close(b)
1129
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1131 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001132 os.symlink(support.TESTFN, support.TESTFN + 'link')
1133 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1134 try:
1135 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001136 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001137 finally:
1138 support.unlink(support.TESTFN + 'link')
1139 posix.close(f)
1140
Larry Hastings9cf065c2012-06-22 16:30:09 -07001141 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1142 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001143 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001144 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001145 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1146 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001147 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001148 except:
1149 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1150 raise
1151 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001152 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001153 finally:
1154 posix.close(f)
1155
Larry Hastings9cf065c2012-06-22 16:30:09 -07001156 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1157 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001158 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1159 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001160 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001161 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1162 finally:
1163 posix.close(f)
1164 support.unlink(support.TESTFN + 'link')
1165
Larry Hastings9cf065c2012-06-22 16:30:09 -07001166 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1167 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001168 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001169 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001170 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001171 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001172 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001173 except:
1174 support.unlink(support.TESTFN + 'del')
1175 raise
1176 else:
1177 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1178 finally:
1179 posix.close(f)
1180
Larry Hastings9cf065c2012-06-22 16:30:09 -07001181 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1182 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001183 support.unlink(support.TESTFN)
1184 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1185 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001186 try:
1187 posix.mkfifo(support.TESTFN,
1188 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1189 except PermissionError as e:
1190 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001191 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1192 finally:
1193 posix.close(f)
1194
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001195 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1196 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001197 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001198 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001199
1200 @requires_sched_h
1201 def test_sched_yield(self):
1202 # This has no error conditions (at least on Linux).
1203 posix.sched_yield()
1204
1205 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001206 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1207 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001208 def test_sched_priority(self):
1209 # Round-robin usually has interesting priorities.
1210 pol = posix.SCHED_RR
1211 lo = posix.sched_get_priority_min(pol)
1212 hi = posix.sched_get_priority_max(pol)
1213 self.assertIsInstance(lo, int)
1214 self.assertIsInstance(hi, int)
1215 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001216 # OSX evidently just returns 15 without checking the argument.
1217 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001218 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1219 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001220
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001221 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001222 def test_get_and_set_scheduler_and_param(self):
1223 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1224 if name.startswith("SCHED_")]
1225 mine = posix.sched_getscheduler(0)
1226 self.assertIn(mine, possible_schedulers)
1227 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001228 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001229 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001230 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001231 raise
1232 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001233 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001234 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1235 self.assertRaises(OSError, posix.sched_getparam, -1)
1236 param = posix.sched_getparam(0)
1237 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001238
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001239 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1240 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1241 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1242 if not sys.platform.startswith(('freebsd', 'netbsd')):
1243 try:
1244 posix.sched_setscheduler(0, mine, param)
1245 posix.sched_setparam(0, param)
1246 except OSError as e:
1247 if e.errno != errno.EPERM:
1248 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001249 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1250
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001251 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1252 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1253 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1254 param = posix.sched_param(None)
1255 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1256 large = 214748364700
1257 param = posix.sched_param(large)
1258 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1259 param = posix.sched_param(sched_priority=-large)
1260 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1261
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001262 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001263 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001264 try:
1265 interval = posix.sched_rr_get_interval(0)
1266 except OSError as e:
1267 # This likely means that sched_rr_get_interval is only valid for
1268 # processes with the SCHED_RR scheduler in effect.
1269 if e.errno != errno.EINVAL:
1270 raise
1271 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001272 self.assertIsInstance(interval, float)
1273 # Reasonable constraints, I think.
1274 self.assertGreaterEqual(interval, 0.)
1275 self.assertLess(interval, 1.)
1276
Benjamin Peterson2740af82011-08-02 17:41:34 -05001277 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001278 def test_sched_getaffinity(self):
1279 mask = posix.sched_getaffinity(0)
1280 self.assertIsInstance(mask, set)
1281 self.assertGreaterEqual(len(mask), 1)
1282 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1283 for cpu in mask:
1284 self.assertIsInstance(cpu, int)
1285 self.assertGreaterEqual(cpu, 0)
1286 self.assertLess(cpu, 1 << 32)
1287
1288 @requires_sched_affinity
1289 def test_sched_setaffinity(self):
1290 mask = posix.sched_getaffinity(0)
1291 if len(mask) > 1:
1292 # Empty masks are forbidden
1293 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001294 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001295 self.assertEqual(posix.sched_getaffinity(0), mask)
1296 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1297 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1298 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001299 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1300
Victor Stinner8b905bd2011-10-25 13:34:04 +02001301 def test_rtld_constants(self):
1302 # check presence of major RTLD_* constants
1303 posix.RTLD_LAZY
1304 posix.RTLD_NOW
1305 posix.RTLD_GLOBAL
1306 posix.RTLD_LOCAL
1307
Jesus Cea60c13dd2012-06-23 02:58:14 +02001308 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1309 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001310 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001311 # Even if the filesystem doesn't report holes,
1312 # if the OS supports it the SEEK_* constants
1313 # will be defined and will have a consistent
1314 # behaviour:
1315 # os.SEEK_DATA = current position
1316 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001317 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001318 fp.write(b"hello")
1319 fp.flush()
1320 size = fp.tell()
1321 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001322 try :
1323 for i in range(size):
1324 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1325 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1326 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1327 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1328 except OSError :
1329 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1330 # but it is not true.
1331 # For instance:
1332 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1333 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001334
Larry Hastingsb0827312014-02-09 22:05:19 -08001335 def test_path_error2(self):
1336 """
1337 Test functions that call path_error2(), providing two filenames in their exceptions.
1338 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001339 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001340 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001341 if function is None:
1342 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001343
Victor Stinnerbed04a72014-10-05 17:37:59 +02001344 for dst in ("noodly2", support.TESTFN):
1345 try:
1346 function('doesnotexistfilename', dst)
1347 except OSError as e:
1348 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1349 break
1350 else:
1351 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001352
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001353 def test_path_with_null_character(self):
1354 fn = support.TESTFN
1355 fn_with_NUL = fn + '\0'
1356 self.addCleanup(support.unlink, fn)
1357 support.unlink(fn)
1358 fd = None
1359 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001360 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001361 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1362 finally:
1363 if fd is not None:
1364 os.close(fd)
1365 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001366 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001367 self.assertFalse(os.path.exists(fn))
1368 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001369 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001370
1371 def test_path_with_null_byte(self):
1372 fn = os.fsencode(support.TESTFN)
1373 fn_with_NUL = fn + b'\0'
1374 self.addCleanup(support.unlink, fn)
1375 support.unlink(fn)
1376 fd = None
1377 try:
1378 with self.assertRaises(ValueError):
1379 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1380 finally:
1381 if fd is not None:
1382 os.close(fd)
1383 self.assertFalse(os.path.exists(fn))
1384 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1385 self.assertFalse(os.path.exists(fn))
1386 open(fn, 'wb').close()
1387 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1388
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001389class PosixGroupsTester(unittest.TestCase):
1390
1391 def setUp(self):
1392 if posix.getuid() != 0:
1393 raise unittest.SkipTest("not enough privileges")
1394 if not hasattr(posix, 'getgroups'):
1395 raise unittest.SkipTest("need posix.getgroups")
1396 if sys.platform == 'darwin':
1397 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1398 self.saved_groups = posix.getgroups()
1399
1400 def tearDown(self):
1401 if hasattr(posix, 'setgroups'):
1402 posix.setgroups(self.saved_groups)
1403 elif hasattr(posix, 'initgroups'):
1404 name = pwd.getpwuid(posix.getuid()).pw_name
1405 posix.initgroups(name, self.saved_groups[0])
1406
1407 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1408 "test needs posix.initgroups()")
1409 def test_initgroups(self):
1410 # find missing group
1411
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001412 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001413 name = pwd.getpwuid(posix.getuid()).pw_name
1414 posix.initgroups(name, g)
1415 self.assertIn(g, posix.getgroups())
1416
1417 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1418 "test needs posix.setgroups()")
1419 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001420 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001421 posix.setgroups(groups)
1422 self.assertListEqual(groups, posix.getgroups())
1423
Serhiy Storchakaef347532018-05-01 16:45:04 +03001424
1425@unittest.skipUnless(hasattr(os, 'posix_spawn'), "test needs os.posix_spawn")
1426class TestPosixSpawn(unittest.TestCase):
1427 def test_returns_pid(self):
1428 pidfile = support.TESTFN
1429 self.addCleanup(support.unlink, pidfile)
1430 script = f"""if 1:
1431 import os
1432 with open({pidfile!r}, "w") as pidfile:
1433 pidfile.write(str(os.getpid()))
1434 """
1435 pid = posix.posix_spawn(sys.executable,
1436 [sys.executable, '-c', script],
1437 os.environ)
1438 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1439 with open(pidfile) as f:
1440 self.assertEqual(f.read(), str(pid))
1441
1442 def test_no_such_executable(self):
1443 no_such_executable = 'no_such_executable'
1444 try:
1445 pid = posix.posix_spawn(no_such_executable,
1446 [no_such_executable],
1447 os.environ)
1448 except FileNotFoundError as exc:
1449 self.assertEqual(exc.filename, no_such_executable)
1450 else:
1451 pid2, status = os.waitpid(pid, 0)
1452 self.assertEqual(pid2, pid)
1453 self.assertNotEqual(status, 0)
1454
1455 def test_specify_environment(self):
1456 envfile = support.TESTFN
1457 self.addCleanup(support.unlink, envfile)
1458 script = f"""if 1:
1459 import os
1460 with open({envfile!r}, "w") as envfile:
1461 envfile.write(os.environ['foo'])
1462 """
1463 pid = posix.posix_spawn(sys.executable,
1464 [sys.executable, '-c', script],
Miro Hrončok7ec8f282018-05-11 07:40:43 +02001465 {**os.environ, 'foo': 'bar'})
Serhiy Storchakaef347532018-05-01 16:45:04 +03001466 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1467 with open(envfile) as f:
1468 self.assertEqual(f.read(), 'bar')
1469
1470 def test_empty_file_actions(self):
1471 pid = posix.posix_spawn(
1472 sys.executable,
1473 [sys.executable, '-c', 'pass'],
1474 os.environ,
1475 []
1476 )
1477 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1478
1479 def test_multiple_file_actions(self):
1480 file_actions = [
1481 (os.POSIX_SPAWN_OPEN, 3, os.path.realpath(__file__), os.O_RDONLY, 0),
1482 (os.POSIX_SPAWN_CLOSE, 0),
1483 (os.POSIX_SPAWN_DUP2, 1, 4),
1484 ]
1485 pid = posix.posix_spawn(sys.executable,
1486 [sys.executable, "-c", "pass"],
1487 os.environ, file_actions)
1488 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1489
1490 def test_bad_file_actions(self):
1491 with self.assertRaises(TypeError):
1492 posix.posix_spawn(sys.executable,
1493 [sys.executable, "-c", "pass"],
1494 os.environ, [None])
1495 with self.assertRaises(TypeError):
1496 posix.posix_spawn(sys.executable,
1497 [sys.executable, "-c", "pass"],
1498 os.environ, [()])
1499 with self.assertRaises(TypeError):
1500 posix.posix_spawn(sys.executable,
1501 [sys.executable, "-c", "pass"],
1502 os.environ, [(None,)])
1503 with self.assertRaises(TypeError):
1504 posix.posix_spawn(sys.executable,
1505 [sys.executable, "-c", "pass"],
1506 os.environ, [(12345,)])
1507 with self.assertRaises(TypeError):
1508 posix.posix_spawn(sys.executable,
1509 [sys.executable, "-c", "pass"],
1510 os.environ, [(os.POSIX_SPAWN_CLOSE,)])
1511 with self.assertRaises(TypeError):
1512 posix.posix_spawn(sys.executable,
1513 [sys.executable, "-c", "pass"],
1514 os.environ, [(os.POSIX_SPAWN_CLOSE, 1, 2)])
1515 with self.assertRaises(TypeError):
1516 posix.posix_spawn(sys.executable,
1517 [sys.executable, "-c", "pass"],
1518 os.environ, [(os.POSIX_SPAWN_CLOSE, None)])
1519 with self.assertRaises(ValueError):
1520 posix.posix_spawn(sys.executable,
1521 [sys.executable, "-c", "pass"],
1522 os.environ,
1523 [(os.POSIX_SPAWN_OPEN, 3, __file__ + '\0',
1524 os.O_RDONLY, 0)])
1525
1526 def test_open_file(self):
1527 outfile = support.TESTFN
1528 self.addCleanup(support.unlink, outfile)
1529 script = """if 1:
1530 import sys
1531 sys.stdout.write("hello")
1532 """
1533 file_actions = [
1534 (os.POSIX_SPAWN_OPEN, 1, outfile,
1535 os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
1536 stat.S_IRUSR | stat.S_IWUSR),
1537 ]
1538 pid = posix.posix_spawn(sys.executable,
1539 [sys.executable, '-c', script],
1540 os.environ, file_actions)
1541 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1542 with open(outfile) as f:
1543 self.assertEqual(f.read(), 'hello')
1544
1545 def test_close_file(self):
1546 closefile = support.TESTFN
1547 self.addCleanup(support.unlink, closefile)
1548 script = f"""if 1:
1549 import os
1550 try:
1551 os.fstat(0)
1552 except OSError as e:
1553 with open({closefile!r}, 'w') as closefile:
1554 closefile.write('is closed %d' % e.errno)
1555 """
1556 pid = posix.posix_spawn(sys.executable,
1557 [sys.executable, '-c', script],
1558 os.environ,
1559 [(os.POSIX_SPAWN_CLOSE, 0),])
1560 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1561 with open(closefile) as f:
1562 self.assertEqual(f.read(), 'is closed %d' % errno.EBADF)
1563
1564 def test_dup2(self):
1565 dupfile = support.TESTFN
1566 self.addCleanup(support.unlink, dupfile)
1567 script = """if 1:
1568 import sys
1569 sys.stdout.write("hello")
1570 """
1571 with open(dupfile, "wb") as childfile:
1572 file_actions = [
1573 (os.POSIX_SPAWN_DUP2, childfile.fileno(), 1),
1574 ]
1575 pid = posix.posix_spawn(sys.executable,
1576 [sys.executable, '-c', script],
1577 os.environ, file_actions)
1578 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
1579 with open(dupfile) as f:
1580 self.assertEqual(f.read(), 'hello')
1581
1582
Neal Norwitze241ce82003-02-17 18:17:05 +00001583def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001584 try:
Serhiy Storchakaef347532018-05-01 16:45:04 +03001585 support.run_unittest(PosixTester, PosixGroupsTester, TestPosixSpawn)
Antoine Pitrou68c95922011-03-20 17:33:57 +01001586 finally:
1587 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001588
1589if __name__ == '__main__':
1590 test_main()