blob: 6c504063179906c817922556fc9c1232c0461892 [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
275 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
276 def test_pwrite(self):
277 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
278 try:
279 os.write(fd, b'test')
280 os.lseek(fd, 0, os.SEEK_SET)
281 posix.pwrite(fd, b'xx', 1)
282 self.assertEqual(b'txxt', posix.read(fd, 4))
283 finally:
284 os.close(fd)
285
286 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
287 "test needs posix.posix_fallocate()")
288 def test_posix_fallocate(self):
289 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
290 try:
291 posix.posix_fallocate(fd, 0, 10)
292 except OSError as inst:
293 # issue10812, ZFS doesn't appear to support posix_fallocate,
294 # so skip Solaris-based since they are likely to have ZFS.
295 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
296 raise
297 finally:
298 os.close(fd)
299
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500300 # issue31106 - posix_fallocate() does not set error in errno.
301 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
302 "test needs posix.posix_fallocate()")
303 def test_posix_fallocate_errno(self):
304 try:
305 posix.posix_fallocate(-42, 0, 10)
306 except OSError as inst:
307 if inst.errno != errno.EBADF:
308 raise
309
Ross Lagerwall7807c352011-03-17 20:20:30 +0200310 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
311 "test needs posix.posix_fadvise()")
312 def test_posix_fadvise(self):
313 fd = os.open(support.TESTFN, os.O_RDONLY)
314 try:
315 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
316 finally:
317 os.close(fd)
318
Коренберг Маркd4b93e22017-08-14 18:55:16 +0500319 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
320 "test needs posix.posix_fadvise()")
321 def test_posix_fadvise_errno(self):
322 try:
323 posix.posix_fadvise(-42, 0, 0, posix.POSIX_FADV_WILLNEED)
324 except OSError as inst:
325 if inst.errno != errno.EBADF:
326 raise
327
Larry Hastings9cf065c2012-06-22 16:30:09 -0700328 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
329 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200330 now = time.time()
331 fd = os.open(support.TESTFN, os.O_RDONLY)
332 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700333 posix.utime(fd)
334 posix.utime(fd, None)
335 self.assertRaises(TypeError, posix.utime, fd, (None, None))
336 self.assertRaises(TypeError, posix.utime, fd, (now, None))
337 self.assertRaises(TypeError, posix.utime, fd, (None, now))
338 posix.utime(fd, (int(now), int(now)))
339 posix.utime(fd, (now, now))
340 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
341 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
342 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
343 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
344 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
345
Ross Lagerwall7807c352011-03-17 20:20:30 +0200346 finally:
347 os.close(fd)
348
Larry Hastings9cf065c2012-06-22 16:30:09 -0700349 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
350 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200351 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700352 posix.utime(support.TESTFN, None, follow_symlinks=False)
353 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
354 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
355 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
356 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
357 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
358 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200359
360 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
361 def test_writev(self):
362 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
363 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100364 n = os.writev(fd, (b'test1', b'tt2', b't3'))
365 self.assertEqual(n, 10)
366
Ross Lagerwall7807c352011-03-17 20:20:30 +0200367 os.lseek(fd, 0, os.SEEK_SET)
368 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100369
370 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100371 try:
372 size = posix.writev(fd, [])
373 except OSError:
374 # writev(fd, []) raises OSError(22, "Invalid argument")
375 # on OpenIndiana
376 pass
377 else:
378 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200379 finally:
380 os.close(fd)
381
382 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
383 def test_readv(self):
384 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
385 try:
386 os.write(fd, b'test1tt2t3')
387 os.lseek(fd, 0, os.SEEK_SET)
388 buf = [bytearray(i) for i in [5, 3, 2]]
389 self.assertEqual(posix.readv(fd, buf), 10)
390 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100391
392 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100393 try:
394 size = posix.readv(fd, [])
395 except OSError:
396 # readv(fd, []) raises OSError(22, "Invalid argument")
397 # on OpenIndiana
398 pass
399 else:
400 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200401 finally:
402 os.close(fd)
403
Serhiy Storchaka43767632013-11-03 21:31:38 +0200404 @unittest.skipUnless(hasattr(posix, 'dup'),
405 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000406 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200407 fp = open(support.TESTFN)
408 try:
409 fd = posix.dup(fp.fileno())
410 self.assertIsInstance(fd, int)
411 os.close(fd)
412 finally:
413 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000414
Serhiy Storchaka43767632013-11-03 21:31:38 +0200415 @unittest.skipUnless(hasattr(posix, 'confstr'),
416 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000417 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200418 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
419 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420
Serhiy Storchaka43767632013-11-03 21:31:38 +0200421 @unittest.skipUnless(hasattr(posix, 'dup2'),
422 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000423 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200424 fp1 = open(support.TESTFN)
425 fp2 = open(support.TESTFN)
426 try:
427 posix.dup2(fp1.fileno(), fp2.fileno())
428 finally:
429 fp1.close()
430 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000431
Charles-François Natali1e045b12011-05-22 20:42:32 +0200432 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200433 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200434 def test_oscloexec(self):
435 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
436 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200437 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200438
Serhiy Storchaka43767632013-11-03 21:31:38 +0200439 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
440 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000441 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200442 fd = os.open(support.TESTFN,
443 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
444 self.assertRaises(OSError, os.open, support.TESTFN,
445 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
446 os.close(fd)
447
448 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000449 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200450 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000451 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000452 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
453 os.close(fd)
454
Serhiy Storchaka43767632013-11-03 21:31:38 +0200455 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
456 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000457 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200458 fd1 = os.open(support.TESTFN,
459 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
460 fd2 = os.open(support.TESTFN,
461 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
462 os.close(fd2)
463 os.close(fd1)
464
465 if hasattr(posix, "O_EXLOCK"):
466 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000467 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200468 self.assertRaises(OSError, os.open, support.TESTFN,
469 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
470 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000471
Serhiy Storchaka43767632013-11-03 21:31:38 +0200472 @unittest.skipUnless(hasattr(posix, 'fstat'),
473 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000474 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200475 fp = open(support.TESTFN)
476 try:
477 self.assertTrue(posix.fstat(fp.fileno()))
478 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200479
Serhiy Storchaka43767632013-11-03 21:31:38 +0200480 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700481 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200482 posix.stat, float(fp.fileno()))
483 finally:
484 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000485
Serhiy Storchaka43767632013-11-03 21:31:38 +0200486 @unittest.skipUnless(hasattr(posix, 'stat'),
487 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000488 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200489 self.assertTrue(posix.stat(support.TESTFN))
490 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200491
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300492 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700493 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300494 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200495 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700496 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200497 posix.stat, None)
498 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700499 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200500 posix.stat, list(support.TESTFN))
501 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700502 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200503 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000504
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000505 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
506 def test_mkfifo(self):
507 support.unlink(support.TESTFN)
xdegaye92c2ca72017-11-12 17:31:07 +0100508 try:
509 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
510 except PermissionError as e:
511 self.skipTest('posix.mkfifo(): %s' % e)
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000512 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
513
514 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
515 "don't have mknod()/S_IFIFO")
516 def test_mknod(self):
517 # Test using mknod() to create a FIFO (the only use specified
518 # by POSIX).
519 support.unlink(support.TESTFN)
520 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
521 try:
522 posix.mknod(support.TESTFN, mode, 0)
523 except OSError as e:
524 # Some old systems don't allow unprivileged users to use
525 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +0100526 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000527 else:
528 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
529
Martin Panterbf19d162015-09-09 01:01:13 +0000530 # Keyword arguments are also supported
531 support.unlink(support.TESTFN)
532 try:
533 posix.mknod(path=support.TESTFN, mode=mode, device=0,
534 dir_fd=None)
535 except OSError as e:
xdegaye92c2ca72017-11-12 17:31:07 +0100536 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Martin Panterbf19d162015-09-09 01:01:13 +0000537
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300538 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
539 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
540 def test_makedev(self):
541 st = posix.stat(support.TESTFN)
542 dev = st.st_dev
543 self.assertIsInstance(dev, int)
544 self.assertGreaterEqual(dev, 0)
545
546 major = posix.major(dev)
547 self.assertIsInstance(major, int)
548 self.assertGreaterEqual(major, 0)
549 self.assertEqual(posix.major(dev), major)
550 self.assertRaises(TypeError, posix.major, float(dev))
551 self.assertRaises(TypeError, posix.major)
552 self.assertRaises((ValueError, OverflowError), posix.major, -1)
553
554 minor = posix.minor(dev)
555 self.assertIsInstance(minor, int)
556 self.assertGreaterEqual(minor, 0)
557 self.assertEqual(posix.minor(dev), minor)
558 self.assertRaises(TypeError, posix.minor, float(dev))
559 self.assertRaises(TypeError, posix.minor)
560 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
561
Victor Stinner13ff2452018-01-22 18:32:50 +0100562 # FIXME: reenable these tests on FreeBSD with the kernel fix
Victor Stinner12953ff2017-07-27 16:55:54 +0200563 if sys.platform.startswith('freebsd') and dev >= 0x1_0000_0000:
564 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
565 "64-bit dev to 32-bit")
566
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300567 self.assertEqual(posix.makedev(major, minor), dev)
568 self.assertRaises(TypeError, posix.makedev, float(major), minor)
569 self.assertRaises(TypeError, posix.makedev, major, float(minor))
570 self.assertRaises(TypeError, posix.makedev, major)
571 self.assertRaises(TypeError, posix.makedev)
572
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200573 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000574 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200575 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 if stat_func is not None:
577 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200578 self.assertEqual(stat.st_uid, uid)
579 self.assertEqual(stat.st_gid, gid)
580 uid = os.getuid()
581 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200582 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200583 chown_func(first_param, uid, gid)
584 check_stat(uid, gid)
585 chown_func(first_param, -1, gid)
586 check_stat(uid, gid)
587 chown_func(first_param, uid, -1)
588 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200589
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200590 if uid == 0:
591 # Try an amusingly large uid/gid to make sure we handle
592 # large unsigned values. (chown lets you use any
593 # uid/gid you like, even if they aren't defined.)
594 #
595 # This problem keeps coming up:
596 # http://bugs.python.org/issue1747858
597 # http://bugs.python.org/issue4591
598 # http://bugs.python.org/issue15301
599 # Hopefully the fix in 4591 fixes it for good!
600 #
601 # This part of the test only runs when run as root.
602 # Only scary people run their tests as root.
603
604 big_value = 2**31
605 chown_func(first_param, big_value, big_value)
606 check_stat(big_value, big_value)
607 chown_func(first_param, -1, -1)
608 check_stat(big_value, big_value)
609 chown_func(first_param, uid, gid)
610 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200611 elif platform.system() in ('HP-UX', 'SunOS'):
612 # HP-UX and Solaris can allow a non-root user to chown() to root
613 # (issue #5113)
614 raise unittest.SkipTest("Skipping because of non-standard chown() "
615 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000616 else:
617 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200619 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200621 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200622 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200623 self.assertRaises(OSError, chown_func, first_param, -1, 0)
624 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200625 # test illegal types
626 for t in str, float:
627 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
628 check_stat(uid, gid)
629 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
630 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000631
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000632 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
633 def test_chown(self):
634 # raise an OSError if the file does not exist
635 os.unlink(support.TESTFN)
636 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000637
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000638 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200639 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200640 self._test_all_chown_common(posix.chown, support.TESTFN,
641 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000642
643 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
644 def test_fchown(self):
645 os.unlink(support.TESTFN)
646
647 # re-create the file
648 test_file = open(support.TESTFN, 'w')
649 try:
650 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200651 self._test_all_chown_common(posix.fchown, fd,
652 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000653 finally:
654 test_file.close()
655
656 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
657 def test_lchown(self):
658 os.unlink(support.TESTFN)
659 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700660 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200661 self._test_all_chown_common(posix.lchown, support.TESTFN,
662 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000663
Serhiy Storchaka43767632013-11-03 21:31:38 +0200664 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000665 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200666 posix.chdir(os.curdir)
667 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000668
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000669 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300670 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000671
672 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700673 # When listdir is called without argument,
674 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300675 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000676
Larry Hastingsfdaea062012-06-25 04:42:23 -0700677 def test_listdir_bytes(self):
678 # When listdir is called with a bytes object,
679 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300680 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
681
682 def test_listdir_bytes_like(self):
683 for cls in bytearray, memoryview:
684 with self.assertWarns(DeprecationWarning):
685 names = posix.listdir(cls(b'.'))
686 self.assertIn(os.fsencode(support.TESTFN), names)
687 for name in names:
688 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700689
690 @unittest.skipUnless(posix.listdir in os.supports_fd,
691 "test needs fd support for posix.listdir()")
692 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000693 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100694 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000695 self.assertEqual(
696 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000698 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100699 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100700 self.assertEqual(
701 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700702 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100703 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000704
Serhiy Storchaka43767632013-11-03 21:31:38 +0200705 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000706 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200707 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000708
Serhiy Storchaka43767632013-11-03 21:31:38 +0200709 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000710 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200711 old_mask = posix.umask(0)
712 self.assertIsInstance(old_mask, int)
713 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000714
Serhiy Storchaka43767632013-11-03 21:31:38 +0200715 @unittest.skipUnless(hasattr(posix, 'strerror'),
716 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000717 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200718 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000719
Serhiy Storchaka43767632013-11-03 21:31:38 +0200720 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000721 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200722 reader, writer = posix.pipe()
723 os.close(reader)
724 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000725
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200726 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200727 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200728 def test_pipe2(self):
729 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
730 self.assertRaises(TypeError, os.pipe2, 0, 0)
731
Charles-François Natali368f34b2011-06-06 19:49:47 +0200732 # try calling with flags = 0, like os.pipe()
733 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200734 os.close(r)
735 os.close(w)
736
737 # test flags
738 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
739 self.addCleanup(os.close, r)
740 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200741 self.assertFalse(os.get_inheritable(r))
742 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200743 self.assertFalse(os.get_blocking(r))
744 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200745 # try reading from an empty pipe: this should fail, not block
746 self.assertRaises(OSError, os.read, r, 1)
747 # try a write big enough to fill-up the pipe: this should either
748 # fail or perform a partial write, not block
749 try:
750 os.write(w, b'x' * support.PIPE_MAX_SIZE)
751 except OSError:
752 pass
753
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200754 @support.cpython_only
755 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
756 @support.requires_linux_version(2, 6, 27)
757 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200758 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200759 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200760 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
761 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
762
Serhiy Storchaka43767632013-11-03 21:31:38 +0200763 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000764 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200765 now = time.time()
766 posix.utime(support.TESTFN, None)
767 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
768 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
769 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
770 posix.utime(support.TESTFN, (int(now), int(now)))
771 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000772
Larry Hastings9cf065c2012-06-22 16:30:09 -0700773 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700774 st = os.stat(target_file)
775 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000776
777 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
778 flags = st.st_flags | stat.UF_IMMUTABLE
779 try:
780 chflags_func(target_file, flags, **kwargs)
781 except OSError as err:
782 if err.errno != errno.EOPNOTSUPP:
783 raise
784 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
785 self.skipTest(msg)
786
Ned Deily3eb67d52011-06-28 00:00:28 -0700787 try:
788 new_st = os.stat(target_file)
789 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
790 try:
791 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200792 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700793 self.assertEqual(e.errno, errno.EPERM)
794 finally:
795 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000796
Ned Deily3eb67d52011-06-28 00:00:28 -0700797 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
798 def test_chflags(self):
799 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
800
801 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
802 def test_lchflags_regular_file(self):
803 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700804 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700805
806 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
807 def test_lchflags_symlink(self):
808 testfn_st = os.stat(support.TESTFN)
809
810 self.assertTrue(hasattr(testfn_st, 'st_flags'))
811
812 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
813 self.teardown_files.append(_DUMMY_SYMLINK)
814 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
815
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 def chflags_nofollow(path, flags):
817 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700818
Larry Hastings9cf065c2012-06-22 16:30:09 -0700819 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000820 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
821 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
822 try:
823 fn(_DUMMY_SYMLINK, flags)
824 except OSError as err:
825 if err.errno != errno.EOPNOTSUPP:
826 raise
827 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
828 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 try:
830 new_testfn_st = os.stat(support.TESTFN)
831 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
832
833 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
834 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
835 new_dummy_symlink_st.st_flags)
836 finally:
837 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000838
Guido van Rossum98297ee2007-11-06 21:34:58 +0000839 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000840 if os.name == "nt":
841 item_type = str
842 else:
843 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000844 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000845 self.assertEqual(type(k), item_type)
846 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000847
Serhiy Storchaka77703942017-06-25 07:33:01 +0300848 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
849 def test_putenv(self):
850 with self.assertRaises(ValueError):
851 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
852 with self.assertRaises(ValueError):
853 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
854 with self.assertRaises(ValueError):
855 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
856 with self.assertRaises(ValueError):
857 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
858 with self.assertRaises(ValueError):
859 os.putenv('FRUIT=ORANGE', 'lemon')
860 with self.assertRaises(ValueError):
861 os.putenv(b'FRUIT=ORANGE', b'lemon')
862
Serhiy Storchaka43767632013-11-03 21:31:38 +0200863 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000864 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500865 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
866 curdir = os.getcwd()
867 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000868
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500869 try:
870 os.mkdir(base_path)
871 os.chdir(base_path)
872 except:
873 # Just returning nothing instead of the SkipTest exception, because
874 # the test results in Error in that case. Is that ok?
875 # raise unittest.SkipTest("cannot create directory for testing")
876 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000877
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500878 def _create_and_do_getcwd(dirname, current_path_length = 0):
879 try:
880 os.mkdir(dirname)
881 except:
882 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000883
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500884 os.chdir(dirname)
885 try:
886 os.getcwd()
887 if current_path_length < 1027:
888 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
889 finally:
890 os.chdir('..')
891 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000892
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500893 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000894
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500895 finally:
896 os.chdir(curdir)
897 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000898
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200899 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
900 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
901 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
902 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +0000903 user = pwd.getpwuid(os.getuid())[0]
904 group = pwd.getpwuid(os.getuid())[3]
905 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200906
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200907
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000908 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000909 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +0200910 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000911 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200912 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000913
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200914 try:
915 idg_groups = set(int(g) for g in groups.split())
916 except ValueError:
917 idg_groups = set()
918 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000919 raise unittest.SkipTest("need working 'id -G'")
920
Ned Deily028915e2013-02-02 15:08:52 -0800921 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
922 if sys.platform == 'darwin':
923 import sysconfig
924 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -0700925 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -0800926 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
927
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000928 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200929 # groups, ignoring order, duplicates, and the effective gid.
930 # #10822/#26944 - It is implementation defined whether
931 # posix.getgroups() includes the effective gid.
932 symdiff = idg_groups.symmetric_difference(posix.getgroups())
933 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000934
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000935 # tests for the posix *at functions follow
936
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
938 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000939 f = posix.open(posix.getcwd(), posix.O_RDONLY)
940 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700941 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000942 finally:
943 posix.close(f)
944
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
946 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000947 os.chmod(support.TESTFN, stat.S_IRUSR)
948
949 f = posix.open(posix.getcwd(), posix.O_RDONLY)
950 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700951 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000952
953 s = posix.stat(support.TESTFN)
954 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
955 finally:
956 posix.close(f)
957
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
959 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000960 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200961 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000962
963 f = posix.open(posix.getcwd(), posix.O_RDONLY)
964 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700965 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000966 finally:
967 posix.close(f)
968
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
970 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000971 support.unlink(support.TESTFN)
972 with open(support.TESTFN, 'w') as outfile:
973 outfile.write("testline\n")
974
975 f = posix.open(posix.getcwd(), posix.O_RDONLY)
976 try:
977 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000979 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200980 s2 = posix.stat(support.TESTFN, dir_fd=None)
981 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +0300982 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200983 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +0300984 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200985 posix.stat, support.TESTFN, dir_fd=float(f))
986 self.assertRaises(OverflowError,
987 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000988 finally:
989 posix.close(f)
990
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
992 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000993 f = posix.open(posix.getcwd(), posix.O_RDONLY)
994 try:
995 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700996 posix.utime(support.TESTFN, None, dir_fd=f)
997 posix.utime(support.TESTFN, dir_fd=f)
998 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
999 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
1000 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
1001 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
1002 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
1003 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
1004 posix.utime(support.TESTFN, (now, now), dir_fd=f)
1005 posix.utime(support.TESTFN,
1006 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
1007 posix.utime(support.TESTFN, dir_fd=f,
1008 times=(int(now), int((now - int(now)) * 1e9)))
1009
Larry Hastings90867a52012-06-22 17:01:41 -07001010 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -07001011 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -07001012 try:
1013 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +02001014 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -07001015 # whoops! using both together not supported on this platform.
1016 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -07001017
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001018 finally:
1019 posix.close(f)
1020
Larry Hastings9cf065c2012-06-22 16:30:09 -07001021 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
1022 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001023 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1024 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
xdegaye92c2ca72017-11-12 17:31:07 +01001026 except PermissionError as e:
1027 self.skipTest('posix.link(): %s' % e)
1028 else:
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001029 # should have same inodes
1030 self.assertEqual(posix.stat(support.TESTFN)[1],
1031 posix.stat(support.TESTFN + 'link')[1])
1032 finally:
1033 posix.close(f)
1034 support.unlink(support.TESTFN + 'link')
1035
Larry Hastings9cf065c2012-06-22 16:30:09 -07001036 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1037 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001038 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1039 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001040 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001041 posix.stat(support.TESTFN + 'dir') # should not raise exception
1042 finally:
1043 posix.close(f)
1044 support.rmtree(support.TESTFN + 'dir')
1045
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1047 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
1048 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001049 # Test using mknodat() to create a FIFO (the only use specified
1050 # by POSIX).
1051 support.unlink(support.TESTFN)
1052 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1053 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1054 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001056 except OSError as e:
1057 # Some old systems don't allow unprivileged users to use
1058 # mknod(), or only support creating device nodes.
xdegaye92c2ca72017-11-12 17:31:07 +01001059 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001060 else:
1061 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1062 finally:
1063 posix.close(f)
1064
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1066 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001067 support.unlink(support.TESTFN)
1068 with open(support.TESTFN, 'w') as outfile:
1069 outfile.write("testline\n")
1070 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001072 try:
1073 res = posix.read(b, 9).decode(encoding="utf-8")
1074 self.assertEqual("testline\n", res)
1075 finally:
1076 posix.close(a)
1077 posix.close(b)
1078
Larry Hastings9cf065c2012-06-22 16:30:09 -07001079 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1080 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001081 os.symlink(support.TESTFN, support.TESTFN + 'link')
1082 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1083 try:
1084 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001085 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001086 finally:
1087 support.unlink(support.TESTFN + 'link')
1088 posix.close(f)
1089
Larry Hastings9cf065c2012-06-22 16:30:09 -07001090 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1091 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001092 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001093 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001094 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1095 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001097 except:
1098 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1099 raise
1100 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001101 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001102 finally:
1103 posix.close(f)
1104
Larry Hastings9cf065c2012-06-22 16:30:09 -07001105 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1106 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001107 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1108 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001110 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1111 finally:
1112 posix.close(f)
1113 support.unlink(support.TESTFN + 'link')
1114
Larry Hastings9cf065c2012-06-22 16:30:09 -07001115 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1116 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001117 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001118 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001119 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001120 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001121 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001122 except:
1123 support.unlink(support.TESTFN + 'del')
1124 raise
1125 else:
1126 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1127 finally:
1128 posix.close(f)
1129
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
1131 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001132 support.unlink(support.TESTFN)
1133 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1134 try:
xdegaye92c2ca72017-11-12 17:31:07 +01001135 try:
1136 posix.mkfifo(support.TESTFN,
1137 stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
1138 except PermissionError as e:
1139 self.skipTest('posix.mkfifo(): %s' % e)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001140 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1141 finally:
1142 posix.close(f)
1143
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001144 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1145 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001146 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001147 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001148
1149 @requires_sched_h
1150 def test_sched_yield(self):
1151 # This has no error conditions (at least on Linux).
1152 posix.sched_yield()
1153
1154 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001155 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1156 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001157 def test_sched_priority(self):
1158 # Round-robin usually has interesting priorities.
1159 pol = posix.SCHED_RR
1160 lo = posix.sched_get_priority_min(pol)
1161 hi = posix.sched_get_priority_max(pol)
1162 self.assertIsInstance(lo, int)
1163 self.assertIsInstance(hi, int)
1164 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001165 # OSX evidently just returns 15 without checking the argument.
1166 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001167 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1168 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001169
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001170 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001171 def test_get_and_set_scheduler_and_param(self):
1172 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1173 if name.startswith("SCHED_")]
1174 mine = posix.sched_getscheduler(0)
1175 self.assertIn(mine, possible_schedulers)
1176 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001177 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001178 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001179 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001180 raise
1181 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001182 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001183 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1184 self.assertRaises(OSError, posix.sched_getparam, -1)
1185 param = posix.sched_getparam(0)
1186 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001187
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001188 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1189 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1190 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1191 if not sys.platform.startswith(('freebsd', 'netbsd')):
1192 try:
1193 posix.sched_setscheduler(0, mine, param)
1194 posix.sched_setparam(0, param)
1195 except OSError as e:
1196 if e.errno != errno.EPERM:
1197 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001198 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1199
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001200 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1201 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1202 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1203 param = posix.sched_param(None)
1204 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1205 large = 214748364700
1206 param = posix.sched_param(large)
1207 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1208 param = posix.sched_param(sched_priority=-large)
1209 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1210
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001211 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001212 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001213 try:
1214 interval = posix.sched_rr_get_interval(0)
1215 except OSError as e:
1216 # This likely means that sched_rr_get_interval is only valid for
1217 # processes with the SCHED_RR scheduler in effect.
1218 if e.errno != errno.EINVAL:
1219 raise
1220 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001221 self.assertIsInstance(interval, float)
1222 # Reasonable constraints, I think.
1223 self.assertGreaterEqual(interval, 0.)
1224 self.assertLess(interval, 1.)
1225
Benjamin Peterson2740af82011-08-02 17:41:34 -05001226 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001227 def test_sched_getaffinity(self):
1228 mask = posix.sched_getaffinity(0)
1229 self.assertIsInstance(mask, set)
1230 self.assertGreaterEqual(len(mask), 1)
1231 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1232 for cpu in mask:
1233 self.assertIsInstance(cpu, int)
1234 self.assertGreaterEqual(cpu, 0)
1235 self.assertLess(cpu, 1 << 32)
1236
1237 @requires_sched_affinity
1238 def test_sched_setaffinity(self):
1239 mask = posix.sched_getaffinity(0)
1240 if len(mask) > 1:
1241 # Empty masks are forbidden
1242 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001243 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001244 self.assertEqual(posix.sched_getaffinity(0), mask)
1245 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1246 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1247 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001248 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1249
Victor Stinner8b905bd2011-10-25 13:34:04 +02001250 def test_rtld_constants(self):
1251 # check presence of major RTLD_* constants
1252 posix.RTLD_LAZY
1253 posix.RTLD_NOW
1254 posix.RTLD_GLOBAL
1255 posix.RTLD_LOCAL
1256
Jesus Cea60c13dd2012-06-23 02:58:14 +02001257 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1258 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001259 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001260 # Even if the filesystem doesn't report holes,
1261 # if the OS supports it the SEEK_* constants
1262 # will be defined and will have a consistent
1263 # behaviour:
1264 # os.SEEK_DATA = current position
1265 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001266 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001267 fp.write(b"hello")
1268 fp.flush()
1269 size = fp.tell()
1270 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001271 try :
1272 for i in range(size):
1273 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1274 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1275 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1276 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1277 except OSError :
1278 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1279 # but it is not true.
1280 # For instance:
1281 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1282 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001283
Larry Hastingsb0827312014-02-09 22:05:19 -08001284 def test_path_error2(self):
1285 """
1286 Test functions that call path_error2(), providing two filenames in their exceptions.
1287 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001288 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001289 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001290 if function is None:
1291 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001292
Victor Stinnerbed04a72014-10-05 17:37:59 +02001293 for dst in ("noodly2", support.TESTFN):
1294 try:
1295 function('doesnotexistfilename', dst)
1296 except OSError as e:
1297 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1298 break
1299 else:
1300 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001301
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001302 def test_path_with_null_character(self):
1303 fn = support.TESTFN
1304 fn_with_NUL = fn + '\0'
1305 self.addCleanup(support.unlink, fn)
1306 support.unlink(fn)
1307 fd = None
1308 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001309 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001310 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1311 finally:
1312 if fd is not None:
1313 os.close(fd)
1314 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001315 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001316 self.assertFalse(os.path.exists(fn))
1317 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001318 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001319
1320 def test_path_with_null_byte(self):
1321 fn = os.fsencode(support.TESTFN)
1322 fn_with_NUL = fn + b'\0'
1323 self.addCleanup(support.unlink, fn)
1324 support.unlink(fn)
1325 fd = None
1326 try:
1327 with self.assertRaises(ValueError):
1328 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1329 finally:
1330 if fd is not None:
1331 os.close(fd)
1332 self.assertFalse(os.path.exists(fn))
1333 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1334 self.assertFalse(os.path.exists(fn))
1335 open(fn, 'wb').close()
1336 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1337
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001338class PosixGroupsTester(unittest.TestCase):
1339
1340 def setUp(self):
1341 if posix.getuid() != 0:
1342 raise unittest.SkipTest("not enough privileges")
1343 if not hasattr(posix, 'getgroups'):
1344 raise unittest.SkipTest("need posix.getgroups")
1345 if sys.platform == 'darwin':
1346 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1347 self.saved_groups = posix.getgroups()
1348
1349 def tearDown(self):
1350 if hasattr(posix, 'setgroups'):
1351 posix.setgroups(self.saved_groups)
1352 elif hasattr(posix, 'initgroups'):
1353 name = pwd.getpwuid(posix.getuid()).pw_name
1354 posix.initgroups(name, self.saved_groups[0])
1355
1356 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1357 "test needs posix.initgroups()")
1358 def test_initgroups(self):
1359 # find missing group
1360
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001361 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001362 name = pwd.getpwuid(posix.getuid()).pw_name
1363 posix.initgroups(name, g)
1364 self.assertIn(g, posix.getgroups())
1365
1366 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1367 "test needs posix.setgroups()")
1368 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001369 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001370 posix.setgroups(groups)
1371 self.assertListEqual(groups, posix.getgroups())
1372
Neal Norwitze241ce82003-02-17 18:17:05 +00001373def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001374 try:
1375 support.run_unittest(PosixTester, PosixGroupsTester)
1376 finally:
1377 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001378
1379if __name__ == '__main__':
1380 test_main()