blob: a7f3d34f66db9faee69775b9cd3b639ec31dc0e0 [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
179 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
180 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
181 def test_waitid(self):
182 pid = os.fork()
183 if pid == 0:
184 os.chdir(os.path.split(sys.executable)[0])
185 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
186 else:
187 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
188 self.assertEqual(pid, res.si_pid)
189
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200190 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700191 def test_register_at_fork(self):
192 with self.assertRaises(TypeError, msg="Positional args not allowed"):
193 os.register_at_fork(lambda: None)
194 with self.assertRaises(TypeError, msg="Args must be callable"):
195 os.register_at_fork(before=2)
196 with self.assertRaises(TypeError, msg="Args must be callable"):
197 os.register_at_fork(after_in_child="three")
198 with self.assertRaises(TypeError, msg="Args must be callable"):
199 os.register_at_fork(after_in_parent=b"Five")
200 with self.assertRaises(TypeError, msg="Args must not be None"):
201 os.register_at_fork(before=None)
202 with self.assertRaises(TypeError, msg="Args must not be None"):
203 os.register_at_fork(after_in_child=None)
204 with self.assertRaises(TypeError, msg="Args must not be None"):
205 os.register_at_fork(after_in_parent=None)
206 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
207 # Ensure a combination of valid and invalid is an error.
208 os.register_at_fork(before=None, after_in_parent=lambda: 3)
209 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
210 # Ensure a combination of valid and invalid is an error.
211 os.register_at_fork(before=lambda: None, after_in_child='')
212 # We test actual registrations in their own process so as not to
213 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200214 code = """if 1:
215 import os
216
217 r, w = os.pipe()
218 fin_r, fin_w = os.pipe()
219
Gregory P. Smith163468a2017-05-29 10:03:41 -0700220 os.register_at_fork(before=lambda: os.write(w, b'A'))
221 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
222 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
223 os.register_at_fork(before=lambda: os.write(w, b'B'),
224 after_in_parent=lambda: os.write(w, b'D'),
225 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200226
227 pid = os.fork()
228 if pid == 0:
229 # At this point, after-forkers have already been executed
230 os.close(w)
231 # Wait for parent to tell us to exit
232 os.read(fin_r, 1)
233 os._exit(0)
234 else:
235 try:
236 os.close(w)
237 with open(r, "rb") as f:
238 data = f.read()
239 assert len(data) == 6, data
240 # Check before-fork callbacks
241 assert data[:2] == b'BA', data
242 # Check after-fork callbacks
243 assert sorted(data[2:]) == list(b'CDEF'), data
244 assert data.index(b'C') < data.index(b'D'), data
245 assert data.index(b'E') < data.index(b'F'), data
246 finally:
247 os.write(fin_w, b'!')
248 """
249 assert_python_ok('-c', code)
250
Ross Lagerwall7807c352011-03-17 20:20:30 +0200251 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
252 def test_lockf(self):
253 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
254 try:
255 os.write(fd, b'test')
256 os.lseek(fd, 0, os.SEEK_SET)
257 posix.lockf(fd, posix.F_LOCK, 4)
258 # section is locked
259 posix.lockf(fd, posix.F_ULOCK, 4)
260 finally:
261 os.close(fd)
262
263 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
264 def test_pread(self):
265 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
266 try:
267 os.write(fd, b'test')
268 os.lseek(fd, 0, os.SEEK_SET)
269 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100270 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200271 self.assertEqual(b'te', posix.read(fd, 2))
272 finally:
273 os.close(fd)
274
Pablo Galindo4defba32018-01-27 16:16:37 +0000275 @unittest.skipUnless(hasattr(posix, 'preadv'), "test needs posix.preadv()")
276 def test_preadv(self):
277 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
278 try:
279 os.write(fd, b'test1tt2t3t5t6t6t8')
280 buf = [bytearray(i) for i in [5, 3, 2]]
281 self.assertEqual(posix.preadv(fd, buf, 3), 10)
282 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
283 finally:
284 os.close(fd)
285
286 @unittest.skipUnless(hasattr(posix, 'RWF_HIPRI'), "test needs posix.RWF_HIPRI")
287 def test_preadv_flags(self):
288 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
289 try:
290 os.write(fd, b'test1tt2t3t5t6t6t8')
291 buf = [bytearray(i) for i in [5, 3, 2]]
292 self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10)
293 self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf))
294 finally:
295 os.close(fd)
296
Ross Lagerwall7807c352011-03-17 20:20:30 +0200297 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
298 def test_pwrite(self):
299 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
300 try:
301 os.write(fd, b'test')
302 os.lseek(fd, 0, os.SEEK_SET)
303 posix.pwrite(fd, b'xx', 1)
304 self.assertEqual(b'txxt', posix.read(fd, 4))
305 finally:
306 os.close(fd)
307
Pablo Galindo4defba32018-01-27 16:16:37 +0000308 @unittest.skipUnless(hasattr(posix, 'pwritev'), "test needs posix.pwritev()")
309 def test_pwritev(self):
310 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
311 try:
312 os.write(fd, b"xx")
313 os.lseek(fd, 0, os.SEEK_SET)
314 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2)
315 self.assertEqual(n, 10)
316
317 os.lseek(fd, 0, os.SEEK_SET)
318 self.assertEqual(b'xxtest1tt2t3', posix.read(fd, 100))
319 finally:
320 os.close(fd)
321
322 @unittest.skipUnless(hasattr(posix, 'os.RWF_SYNC'), "test needs os.RWF_SYNC")
323 def test_pwritev_flags(self):
324 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
325 try:
326 os.write(fd,b"xx")
327 os.lseek(fd, 0, os.SEEK_SET)
328 n = os.pwritev(fd, [b'test1', b'tt2', b't3'], 2, os.RWF_SYNC)
329 self.assertEqual(n, 10)
330
331 os.lseek(fd, 0, os.SEEK_SET)
332 self.assertEqual(b'xxtest1tt2', posix.read(fd, 100))
333 finally:
334 os.close(fd)
335
Ross Lagerwall7807c352011-03-17 20:20:30 +0200336 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
337 "test needs posix.posix_fallocate()")
338 def test_posix_fallocate(self):
339 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
340 try:
341 posix.posix_fallocate(fd, 0, 10)
342 except OSError as inst:
343 # issue10812, ZFS doesn't appear to support posix_fallocate,
344 # so skip Solaris-based since they are likely to have ZFS.
345 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
346 raise
347 finally:
348 os.close(fd)
349
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500350 # issue31106 - posix_fallocate() does not set error in errno.
351 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
352 "test needs posix.posix_fallocate()")
353 def test_posix_fallocate_errno(self):
354 try:
355 posix.posix_fallocate(-42, 0, 10)
356 except OSError as inst:
357 if inst.errno != errno.EBADF:
358 raise
359
Ross Lagerwall7807c352011-03-17 20:20:30 +0200360 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
361 "test needs posix.posix_fadvise()")
362 def test_posix_fadvise(self):
363 fd = os.open(support.TESTFN, os.O_RDONLY)
364 try:
365 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
366 finally:
367 os.close(fd)
368
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500369 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
370 "test needs posix.posix_fadvise()")
371 def test_posix_fadvise_errno(self):
372 try:
373 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
374 except OSError as inst:
375 if inst.errno != errno.EBADF:
376 raise
377
Larry Hastings9cf065c2012-06-22 16:30:09 -0700378 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
379 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200380 now = time.time()
381 fd = os.open(support.TESTFN, os.O_RDONLY)
382 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700383 posix.utime(fd)
384 posix.utime(fd, None)
385 self.assertRaises(TypeError, posix.utime, fd, (None, None))
386 self.assertRaises(TypeError, posix.utime, fd, (now, None))
387 self.assertRaises(TypeError, posix.utime, fd, (None, now))
388 posix.utime(fd, (int(now), int(now)))
389 posix.utime(fd, (now, now))
390 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
391 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
392 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
393 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
394 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
395
Ross Lagerwall7807c352011-03-17 20:20:30 +0200396 finally:
397 os.close(fd)
398
Larry Hastings9cf065c2012-06-22 16:30:09 -0700399 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
400 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200401 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700402 posix.utime(support.TESTFN, None, follow_symlinks=False)
403 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
404 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
405 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
406 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
407 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
408 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200409
410 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
411 def test_writev(self):
412 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
413 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100414 n = os.writev(fd, (b'test1', b'tt2', b't3'))
415 self.assertEqual(n, 10)
416
Ross Lagerwall7807c352011-03-17 20:20:30 +0200417 os.lseek(fd, 0, os.SEEK_SET)
418 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100419
420 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100421 try:
422 size = posix.writev(fd, [])
423 except OSError:
424 # writev(fd, []) raises OSError(22, "Invalid argument")
425 # on OpenIndiana
426 pass
427 else:
428 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200429 finally:
430 os.close(fd)
431
432 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
433 def test_readv(self):
434 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
435 try:
436 os.write(fd, b'test1tt2t3')
437 os.lseek(fd, 0, os.SEEK_SET)
438 buf = [bytearray(i) for i in [5, 3, 2]]
439 self.assertEqual(posix.readv(fd, buf), 10)
440 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100441
442 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100443 try:
444 size = posix.readv(fd, [])
445 except OSError:
446 # readv(fd, []) raises OSError(22, "Invalid argument")
447 # on OpenIndiana
448 pass
449 else:
450 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200451 finally:
452 os.close(fd)
453
Serhiy Storchaka43767632013-11-03 21:31:38 +0200454 @unittest.skipUnless(hasattr(posix, 'dup'),
455 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000456 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200457 fp = open(support.TESTFN)
458 try:
459 fd = posix.dup(fp.fileno())
460 self.assertIsInstance(fd, int)
461 os.close(fd)
462 finally:
463 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000464
Serhiy Storchaka43767632013-11-03 21:31:38 +0200465 @unittest.skipUnless(hasattr(posix, 'confstr'),
466 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000467 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200468 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
469 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000470
Serhiy Storchaka43767632013-11-03 21:31:38 +0200471 @unittest.skipUnless(hasattr(posix, 'dup2'),
472 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000473 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200474 fp1 = open(support.TESTFN)
475 fp2 = open(support.TESTFN)
476 try:
477 posix.dup2(fp1.fileno(), fp2.fileno())
478 finally:
479 fp1.close()
480 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000481
Charles-François Natali1e045b12011-05-22 20:42:32 +0200482 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200483 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200484 def test_oscloexec(self):
485 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
486 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200487 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200488
Serhiy Storchaka43767632013-11-03 21:31:38 +0200489 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
490 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000491 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200492 fd = os.open(support.TESTFN,
493 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
494 self.assertRaises(OSError, os.open, support.TESTFN,
495 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
496 os.close(fd)
497
498 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000499 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200500 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000501 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000502 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
503 os.close(fd)
504
Serhiy Storchaka43767632013-11-03 21:31:38 +0200505 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
506 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000507 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200508 fd1 = os.open(support.TESTFN,
509 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
510 fd2 = os.open(support.TESTFN,
511 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
512 os.close(fd2)
513 os.close(fd1)
514
515 if hasattr(posix, "O_EXLOCK"):
516 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000517 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200518 self.assertRaises(OSError, os.open, support.TESTFN,
519 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
520 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000521
Serhiy Storchaka43767632013-11-03 21:31:38 +0200522 @unittest.skipUnless(hasattr(posix, 'fstat'),
523 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000524 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200525 fp = open(support.TESTFN)
526 try:
527 self.assertTrue(posix.fstat(fp.fileno()))
528 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200529
Serhiy Storchaka43767632013-11-03 21:31:38 +0200530 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700531 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200532 posix.stat, float(fp.fileno()))
533 finally:
534 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000535
Serhiy Storchaka43767632013-11-03 21:31:38 +0200536 @unittest.skipUnless(hasattr(posix, 'stat'),
537 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000538 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200539 self.assertTrue(posix.stat(support.TESTFN))
540 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200541
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300542 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700543 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300544 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200545 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700546 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200547 posix.stat, None)
548 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700549 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200550 posix.stat, list(support.TESTFN))
551 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, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000554
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000555 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
556 def test_mkfifo(self):
557 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100558 try:
559 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
560 except PermissionError as e:
561 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000562 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
563
564 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
565 "don't have mknod()/S_IFIFO")
566 def test_mknod(self):
567 # Test using mknod() to create a FIFO (the only use specified
568 # by POSIX).
569 support.unlink(support.TESTFN)
570 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
571 try:
572 posix.mknod(support.TESTFN, mode, 0)
573 except OSError as e:
574 # Some old systems don't allow unprivileged users to use
575 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100576 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000577 else:
578 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
579
Martin Panterbf19d162015-09-09 01:01:13 +0000580 # Keyword arguments are also supported
581 support.unlink(support.TESTFN)
582 try:
583 posix.mknod(path=support.TESTFN, mode=mode, device=0,
584 dir_fd=None)
585 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100586 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000587
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300588 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
589 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
590 def test_makedev(self):
591 st = posix.stat(support.TESTFN)
592 dev = st.st_dev
593 self.assertIsInstance(dev, int)
594 self.assertGreaterEqual(dev, 0)
595
596 major = posix.major(dev)
597 self.assertIsInstance(major, int)
598 self.assertGreaterEqual(major, 0)
599 self.assertEqual(posix.major(dev), major)
600 self.assertRaises(TypeError, posix.major, float(dev))
601 self.assertRaises(TypeError, posix.major)
602 self.assertRaises((ValueError, OverflowError), posix.major, -1)
603
604 minor = posix.minor(dev)
605 self.assertIsInstance(minor, int)
606 self.assertGreaterEqual(minor, 0)
607 self.assertEqual(posix.minor(dev), minor)
608 self.assertRaises(TypeError, posix.minor, float(dev))
609 self.assertRaises(TypeError, posix.minor)
610 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
611
Victor Stinner13ff2452018-01-22 18:32:50 +0100612 # FIXME: reenable these tests on FreeBSD with the kernel fix
Victor Stinner12953ff2017-07-27 16:55:54 +0200613 if sys.platform.startswith('freebsd') and dev >= 0x1_0000_0000:
614 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
615 "64-bit dev to 32-bit")
616
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300617 self.assertEqual(posix.makedev(major, minor), dev)
618 self.assertRaises(TypeError, posix.makedev, float(major), minor)
619 self.assertRaises(TypeError, posix.makedev, major, float(minor))
620 self.assertRaises(TypeError, posix.makedev, major)
621 self.assertRaises(TypeError, posix.makedev)
622
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200623 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000624 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200625 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 if stat_func is not None:
627 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200628 self.assertEqual(stat.st_uid, uid)
629 self.assertEqual(stat.st_gid, gid)
630 uid = os.getuid()
631 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200632 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200633 chown_func(first_param, uid, gid)
634 check_stat(uid, gid)
635 chown_func(first_param, -1, gid)
636 check_stat(uid, gid)
637 chown_func(first_param, uid, -1)
638 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200639
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200640 if uid == 0:
641 # Try an amusingly large uid/gid to make sure we handle
642 # large unsigned values. (chown lets you use any
643 # uid/gid you like, even if they aren't defined.)
644 #
645 # This problem keeps coming up:
646 # http://bugs.python.org/issue1747858
647 # http://bugs.python.org/issue4591
648 # http://bugs.python.org/issue15301
649 # Hopefully the fix in 4591 fixes it for good!
650 #
651 # This part of the test only runs when run as root.
652 # Only scary people run their tests as root.
653
654 big_value = 2**31
655 chown_func(first_param, big_value, big_value)
656 check_stat(big_value, big_value)
657 chown_func(first_param, -1, -1)
658 check_stat(big_value, big_value)
659 chown_func(first_param, uid, gid)
660 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200661 elif platform.system() in ('HP-UX', 'SunOS'):
662 # HP-UX and Solaris can allow a non-root user to chown() to root
663 # (issue #5113)
664 raise unittest.SkipTest("Skipping because of non-standard chown() "
665 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000666 else:
667 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200668 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200669 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200670 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200671 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200672 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200673 self.assertRaises(OSError, chown_func, first_param, -1, 0)
674 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200675 # test illegal types
676 for t in str, float:
677 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
678 check_stat(uid, gid)
679 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
680 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000681
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000682 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
683 def test_chown(self):
684 # raise an OSError if the file does not exist
685 os.unlink(support.TESTFN)
686 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000687
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000688 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200689 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200690 self._test_all_chown_common(posix.chown, support.TESTFN,
691 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000692
693 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
694 def test_fchown(self):
695 os.unlink(support.TESTFN)
696
697 # re-create the file
698 test_file = open(support.TESTFN, 'w')
699 try:
700 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200701 self._test_all_chown_common(posix.fchown, fd,
702 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000703 finally:
704 test_file.close()
705
706 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
707 def test_lchown(self):
708 os.unlink(support.TESTFN)
709 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700710 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200711 self._test_all_chown_common(posix.lchown, support.TESTFN,
712 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000713
Serhiy Storchaka43767632013-11-03 21:31:38 +0200714 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000715 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200716 posix.chdir(os.curdir)
717 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000718
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000719 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300720 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000721
722 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700723 # When listdir is called without argument,
724 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300725 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000726
Larry Hastingsfdaea062012-06-25 04:42:23 -0700727 def test_listdir_bytes(self):
728 # When listdir is called with a bytes object,
729 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300730 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
731
732 def test_listdir_bytes_like(self):
733 for cls in bytearray, memoryview:
734 with self.assertWarns(DeprecationWarning):
735 names = posix.listdir(cls(b'.'))
736 self.assertIn(os.fsencode(support.TESTFN), names)
737 for name in names:
738 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700739
740 @unittest.skipUnless(posix.listdir in os.supports_fd,
741 "test needs fd support for posix.listdir()")
742 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000743 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100744 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000745 self.assertEqual(
746 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000748 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100749 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100750 self.assertEqual(
751 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700752 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100753 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000754
Serhiy Storchaka43767632013-11-03 21:31:38 +0200755 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000756 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200757 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000758
Serhiy Storchaka43767632013-11-03 21:31:38 +0200759 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000760 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200761 old_mask = posix.umask(0)
762 self.assertIsInstance(old_mask, int)
763 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000764
Serhiy Storchaka43767632013-11-03 21:31:38 +0200765 @unittest.skipUnless(hasattr(posix, 'strerror'),
766 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000767 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200768 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000769
Serhiy Storchaka43767632013-11-03 21:31:38 +0200770 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000771 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200772 reader, writer = posix.pipe()
773 os.close(reader)
774 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000775
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200776 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200777 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200778 def test_pipe2(self):
779 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
780 self.assertRaises(TypeError, os.pipe2, 0, 0)
781
Charles-François Natali368f34b2011-06-06 19:49:47 +0200782 # try calling with flags = 0, like os.pipe()
783 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200784 os.close(r)
785 os.close(w)
786
787 # test flags
788 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
789 self.addCleanup(os.close, r)
790 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200791 self.assertFalse(os.get_inheritable(r))
792 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200793 self.assertFalse(os.get_blocking(r))
794 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200795 # try reading from an empty pipe: this should fail, not block
796 self.assertRaises(OSError, os.read, r, 1)
797 # try a write big enough to fill-up the pipe: this should either
798 # fail or perform a partial write, not block
799 try:
800 os.write(w, b'x' * support.PIPE_MAX_SIZE)
801 except OSError:
802 pass
803
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200804 @support.cpython_only
805 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
806 @support.requires_linux_version(2, 6, 27)
807 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200808 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200809 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200810 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
811 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
812
Serhiy Storchaka43767632013-11-03 21:31:38 +0200813 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000814 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200815 now = time.time()
816 posix.utime(support.TESTFN, None)
817 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
818 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
819 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
820 posix.utime(support.TESTFN, (int(now), int(now)))
821 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000822
Larry Hastings9cf065c2012-06-22 16:30:09 -0700823 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700824 st = os.stat(target_file)
825 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000826
827 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
828 flags = st.st_flags | stat.UF_IMMUTABLE
829 try:
830 chflags_func(target_file, flags, **kwargs)
831 except OSError as err:
832 if err.errno != errno.EOPNOTSUPP:
833 raise
834 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
835 self.skipTest(msg)
836
Ned Deily3eb67d52011-06-28 00:00:28 -0700837 try:
838 new_st = os.stat(target_file)
839 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
840 try:
841 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200842 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700843 self.assertEqual(e.errno, errno.EPERM)
844 finally:
845 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000846
Ned Deily3eb67d52011-06-28 00:00:28 -0700847 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
848 def test_chflags(self):
849 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
850
851 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
852 def test_lchflags_regular_file(self):
853 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700854 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700855
856 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
857 def test_lchflags_symlink(self):
858 testfn_st = os.stat(support.TESTFN)
859
860 self.assertTrue(hasattr(testfn_st, 'st_flags'))
861
862 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
863 self.teardown_files.append(_DUMMY_SYMLINK)
864 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
865
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 def chflags_nofollow(path, flags):
867 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700868
Larry Hastings9cf065c2012-06-22 16:30:09 -0700869 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000870 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
871 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
872 try:
873 fn(_DUMMY_SYMLINK, flags)
874 except OSError as err:
875 if err.errno != errno.EOPNOTSUPP:
876 raise
877 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
878 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700879 try:
880 new_testfn_st = os.stat(support.TESTFN)
881 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
882
883 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
884 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
885 new_dummy_symlink_st.st_flags)
886 finally:
887 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000888
Guido van Rossum98297ee2007-11-06 21:34:58 +0000889 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000890 if os.name == "nt":
891 item_type = str
892 else:
893 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000894 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000895 self.assertEqual(type(k), item_type)
896 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000897
Serhiy Storchaka77703942017-06-25 07:33:01 +0300898 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
899 def test_putenv(self):
900 with self.assertRaises(ValueError):
901 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
902 with self.assertRaises(ValueError):
903 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
904 with self.assertRaises(ValueError):
905 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
906 with self.assertRaises(ValueError):
907 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
908 with self.assertRaises(ValueError):
909 os.putenv('FRUIT=ORANGE', 'lemon')
910 with self.assertRaises(ValueError):
911 os.putenv(b'FRUIT=ORANGE', b'lemon')
912
Serhiy Storchaka43767632013-11-03 21:31:38 +0200913 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000914 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500915 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
916 curdir = os.getcwd()
917 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000918
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500919 try:
920 os.mkdir(base_path)
921 os.chdir(base_path)
922 except:
923 # Just returning nothing instead of the SkipTest exception, because
924 # the test results in Error in that case. Is that ok?
925 # raise unittest.SkipTest("cannot create directory for testing")
926 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000927
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500928 def _create_and_do_getcwd(dirname, current_path_length = 0):
929 try:
930 os.mkdir(dirname)
931 except:
932 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000933
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500934 os.chdir(dirname)
935 try:
936 os.getcwd()
937 if current_path_length < 1027:
938 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
939 finally:
940 os.chdir('..')
941 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000942
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500943 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000944
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500945 finally:
946 os.chdir(curdir)
947 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000948
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200949 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
950 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
951 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
952 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +0000953 user = pwd.getpwuid(os.getuid())[0]
954 group = pwd.getpwuid(os.getuid())[3]
955 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200956
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200957
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000958 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000959 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +0200960 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000961 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200962 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000963
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200964 try:
965 idg_groups = set(int(g) for g in groups.split())
966 except ValueError:
967 idg_groups = set()
968 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000969 raise unittest.SkipTest("need working 'id -G'")
970
Ned Deily028915e2013-02-02 15:08:52 -0800971 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
972 if sys.platform == 'darwin':
973 import sysconfig
974 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -0700975 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -0800976 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
977
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000978 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200979 # groups, ignoring order, duplicates, and the effective gid.
980 # #10822/#26944 - It is implementation defined whether
981 # posix.getgroups() includes the effective gid.
982 symdiff = idg_groups.symmetric_difference(posix.getgroups())
983 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000984
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000985 # tests for the posix *at functions follow
986
Larry Hastings9cf065c2012-06-22 16:30:09 -0700987 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
988 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000989 f = posix.open(posix.getcwd(), posix.O_RDONLY)
990 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000992 finally:
993 posix.close(f)
994
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
996 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000997 os.chmod(support.TESTFN, stat.S_IRUSR)
998
999 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1000 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001002
1003 s = posix.stat(support.TESTFN)
1004 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
1005 finally:
1006 posix.close(f)
1007
Larry Hastings9cf065c2012-06-22 16:30:09 -07001008 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
1009 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001010 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001011 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001012
1013 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1014 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001015 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001016 finally:
1017 posix.close(f)
1018
Larry Hastings9cf065c2012-06-22 16:30:09 -07001019 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
1020 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001021 support.unlink(support.TESTFN)
1022 with open(support.TESTFN, 'w') as outfile:
1023 outfile.write("testline\n")
1024
1025 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1026 try:
1027 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001028 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001029 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001030 s2 = posix.stat(support.TESTFN, dir_fd=None)
1031 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001032 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001033 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +03001034 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001035 posix.stat, support.TESTFN, dir_fd=float(f))
1036 self.assertRaises(OverflowError,
1037 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001038 finally:
1039 posix.close(f)
1040
Larry Hastings9cf065c2012-06-22 16:30:09 -07001041 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
1042 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001043 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1044 try:
1045 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046 posix.utime(support.TESTFN, None, dir_fd=f)
1047 posix.utime(support.TESTFN, dir_fd=f)
1048 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
1049 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1050 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1051 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1052 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1053 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1054 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1055 posix.utime(support.TESTFN,
1056 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1057 posix.utime(support.TESTFN, dir_fd=f,
1058 times=(int(now), int((now - int(now)) * 1e9)))
1059
Larry Hastings90867a52012-06-22 17:01:41 -07001060 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001062 try:
1063 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001064 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001065 # whoops! using both together not supported on this platform.
1066 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001067
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001068 finally:
1069 posix.close(f)
1070
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1072 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001073 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1074 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001075 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001076 except PermissionError as e:
1077 self.skipTest('posix.link(): %s' % e)
1078 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001079 # should have same inodes
1080 self.assertEqual(posix.stat(support.TESTFN)[1],
1081 posix.stat(support.TESTFN + 'link')[1])
1082 finally:
1083 posix.close(f)
1084 support.unlink(support.TESTFN + 'link')
1085
Larry Hastings9cf065c2012-06-22 16:30:09 -07001086 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1087 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001088 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1089 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001091 posix.stat(support.TESTFN + 'dir') # should not raise exception
1092 finally:
1093 posix.close(f)
1094 support.rmtree(support.TESTFN + 'dir')
1095
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1097 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1098 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001099 # Test using mknodat() to create a FIFO (the only use specified
1100 # by POSIX).
1101 support.unlink(support.TESTFN)
1102 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1103 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1104 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001106 except OSError as e:
1107 # Some old systems don't allow unprivileged users to use
1108 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001109 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001110 else:
1111 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1112 finally:
1113 posix.close(f)
1114
Larry Hastings9cf065c2012-06-22 16:30:09 -07001115 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1116 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001117 support.unlink(support.TESTFN)
1118 with open(support.TESTFN, 'w') as outfile:
1119 outfile.write("testline\n")
1120 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001121 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001122 try:
1123 res = posix.read(b, 9).decode(encoding="utf-8")
1124 self.assertEqual("testline\n", res)
1125 finally:
1126 posix.close(a)
1127 posix.close(b)
1128
Larry Hastings9cf065c2012-06-22 16:30:09 -07001129 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1130 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001131 os.symlink(support.TESTFN, support.TESTFN + 'link')
1132 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1133 try:
1134 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001135 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001136 finally:
1137 support.unlink(support.TESTFN + 'link')
1138 posix.close(f)
1139
Larry Hastings9cf065c2012-06-22 16:30:09 -07001140 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1141 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001142 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001143 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001144 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1145 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001146 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001147 except:
1148 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1149 raise
1150 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001151 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001152 finally:
1153 posix.close(f)
1154
Larry Hastings9cf065c2012-06-22 16:30:09 -07001155 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1156 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001157 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1158 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001159 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001160 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1161 finally:
1162 posix.close(f)
1163 support.unlink(support.TESTFN + 'link')
1164
Larry Hastings9cf065c2012-06-22 16:30:09 -07001165 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1166 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001167 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001168 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001169 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001170 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001171 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001172 except:
1173 support.unlink(support.TESTFN + 'del')
1174 raise
1175 else:
1176 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1177 finally:
1178 posix.close(f)
1179
Larry Hastings9cf065c2012-06-22 16:30:09 -07001180 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1181 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001182 support.unlink(support.TESTFN)
1183 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1184 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001185 try:
1186 posix.mkfifo(support.TESTFN,
1187 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1188 except PermissionError as e:
1189 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001190 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1191 finally:
1192 posix.close(f)
1193
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001194 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1195 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001196 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001197 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001198
1199 @requires_sched_h
1200 def test_sched_yield(self):
1201 # This has no error conditions (at least on Linux).
1202 posix.sched_yield()
1203
1204 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001205 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1206 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001207 def test_sched_priority(self):
1208 # Round-robin usually has interesting priorities.
1209 pol = posix.SCHED_RR
1210 lo = posix.sched_get_priority_min(pol)
1211 hi = posix.sched_get_priority_max(pol)
1212 self.assertIsInstance(lo, int)
1213 self.assertIsInstance(hi, int)
1214 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001215 # OSX evidently just returns 15 without checking the argument.
1216 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001217 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1218 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001219
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001220 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001221 def test_get_and_set_scheduler_and_param(self):
1222 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1223 if name.startswith("SCHED_")]
1224 mine = posix.sched_getscheduler(0)
1225 self.assertIn(mine, possible_schedulers)
1226 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001227 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001228 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001229 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001230 raise
1231 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001232 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001233 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1234 self.assertRaises(OSError, posix.sched_getparam, -1)
1235 param = posix.sched_getparam(0)
1236 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001237
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001238 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1239 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1240 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1241 if not sys.platform.startswith(('freebsd', 'netbsd')):
1242 try:
1243 posix.sched_setscheduler(0, mine, param)
1244 posix.sched_setparam(0, param)
1245 except OSError as e:
1246 if e.errno != errno.EPERM:
1247 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001248 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1249
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001250 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1251 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1252 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1253 param = posix.sched_param(None)
1254 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1255 large = 214748364700
1256 param = posix.sched_param(large)
1257 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1258 param = posix.sched_param(sched_priority=-large)
1259 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1260
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001261 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001262 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001263 try:
1264 interval = posix.sched_rr_get_interval(0)
1265 except OSError as e:
1266 # This likely means that sched_rr_get_interval is only valid for
1267 # processes with the SCHED_RR scheduler in effect.
1268 if e.errno != errno.EINVAL:
1269 raise
1270 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001271 self.assertIsInstance(interval, float)
1272 # Reasonable constraints, I think.
1273 self.assertGreaterEqual(interval, 0.)
1274 self.assertLess(interval, 1.)
1275
Benjamin Peterson2740af82011-08-02 17:41:34 -05001276 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001277 def test_sched_getaffinity(self):
1278 mask = posix.sched_getaffinity(0)
1279 self.assertIsInstance(mask, set)
1280 self.assertGreaterEqual(len(mask), 1)
1281 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1282 for cpu in mask:
1283 self.assertIsInstance(cpu, int)
1284 self.assertGreaterEqual(cpu, 0)
1285 self.assertLess(cpu, 1 << 32)
1286
1287 @requires_sched_affinity
1288 def test_sched_setaffinity(self):
1289 mask = posix.sched_getaffinity(0)
1290 if len(mask) > 1:
1291 # Empty masks are forbidden
1292 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001293 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001294 self.assertEqual(posix.sched_getaffinity(0), mask)
1295 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1296 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1297 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001298 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1299
Victor Stinner8b905bd2011-10-25 13:34:04 +02001300 def test_rtld_constants(self):
1301 # check presence of major RTLD_* constants
1302 posix.RTLD_LAZY
1303 posix.RTLD_NOW
1304 posix.RTLD_GLOBAL
1305 posix.RTLD_LOCAL
1306
Jesus Cea60c13dd2012-06-23 02:58:14 +02001307 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1308 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001309 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001310 # Even if the filesystem doesn't report holes,
1311 # if the OS supports it the SEEK_* constants
1312 # will be defined and will have a consistent
1313 # behaviour:
1314 # os.SEEK_DATA = current position
1315 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001316 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001317 fp.write(b"hello")
1318 fp.flush()
1319 size = fp.tell()
1320 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001321 try :
1322 for i in range(size):
1323 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1324 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1325 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1326 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1327 except OSError :
1328 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1329 # but it is not true.
1330 # For instance:
1331 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1332 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001333
Larry Hastingsb0827312014-02-09 22:05:19 -08001334 def test_path_error2(self):
1335 """
1336 Test functions that call path_error2(), providing two filenames in their exceptions.
1337 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001338 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001339 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001340 if function is None:
1341 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001342
Victor Stinnerbed04a72014-10-05 17:37:59 +02001343 for dst in ("noodly2", support.TESTFN):
1344 try:
1345 function('doesnotexistfilename', dst)
1346 except OSError as e:
1347 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1348 break
1349 else:
1350 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001351
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001352 def test_path_with_null_character(self):
1353 fn = support.TESTFN
1354 fn_with_NUL = fn + '\0'
1355 self.addCleanup(support.unlink, fn)
1356 support.unlink(fn)
1357 fd = None
1358 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001359 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001360 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1361 finally:
1362 if fd is not None:
1363 os.close(fd)
1364 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001365 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001366 self.assertFalse(os.path.exists(fn))
1367 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001368 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001369
1370 def test_path_with_null_byte(self):
1371 fn = os.fsencode(support.TESTFN)
1372 fn_with_NUL = fn + b'\0'
1373 self.addCleanup(support.unlink, fn)
1374 support.unlink(fn)
1375 fd = None
1376 try:
1377 with self.assertRaises(ValueError):
1378 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1379 finally:
1380 if fd is not None:
1381 os.close(fd)
1382 self.assertFalse(os.path.exists(fn))
1383 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1384 self.assertFalse(os.path.exists(fn))
1385 open(fn, 'wb').close()
1386 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1387
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001388class PosixGroupsTester(unittest.TestCase):
1389
1390 def setUp(self):
1391 if posix.getuid() != 0:
1392 raise unittest.SkipTest("not enough privileges")
1393 if not hasattr(posix, 'getgroups'):
1394 raise unittest.SkipTest("need posix.getgroups")
1395 if sys.platform == 'darwin':
1396 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1397 self.saved_groups = posix.getgroups()
1398
1399 def tearDown(self):
1400 if hasattr(posix, 'setgroups'):
1401 posix.setgroups(self.saved_groups)
1402 elif hasattr(posix, 'initgroups'):
1403 name = pwd.getpwuid(posix.getuid()).pw_name
1404 posix.initgroups(name, self.saved_groups[0])
1405
1406 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1407 "test needs posix.initgroups()")
1408 def test_initgroups(self):
1409 # find missing group
1410
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001411 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001412 name = pwd.getpwuid(posix.getuid()).pw_name
1413 posix.initgroups(name, g)
1414 self.assertIn(g, posix.getgroups())
1415
1416 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1417 "test needs posix.setgroups()")
1418 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001419 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001420 posix.setgroups(groups)
1421 self.assertListEqual(groups, posix.getgroups())
1422
Neal Norwitze241ce82003-02-17 18:17:05 +00001423def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001424 try:
1425 support.run_unittest(PosixTester, PosixGroupsTester)
1426 finally:
1427 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001428
1429if __name__ == '__main__':
1430 test_main()