blob: 148c0641a999d550a7823fde1fa8db9990bedccd [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
Xavier de Gaye3a4e9892016-12-13 10:00:01 +01005android_not_root = support.android_not_root
R. David Murrayeb3615d2009-04-22 02:24:39 +00006
7# Skip these tests if there is no posix module.
8posix = support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00009
Antoine Pitroub7572f02009-12-02 20:46:48 +000010import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +000011import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000012import time
13import os
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020014import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000015import pwd
Benjamin Peterson052a02b2010-08-17 01:27:09 +000016import stat
Ned Deilyba2eab22011-07-26 13:53:55 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000020
Ned Deilyba2eab22011-07-26 13:53:55 -070021_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
22 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000023
24class PosixTester(unittest.TestCase):
25
26 def setUp(self):
27 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000028 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000029 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070030 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000031 self._warnings_manager = support.check_warnings()
32 self._warnings_manager.__enter__()
33 warnings.filterwarnings('ignore', '.* potential security risk .*',
34 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000035
36 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070037 for teardown_file in self.teardown_files:
38 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000039 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000040
41 def testNoArgFunctions(self):
42 # test posix functions which take no arguments and have
43 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000044 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000045 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000046 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020047 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000048 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000049
Neal Norwitze241ce82003-02-17 18:17:05 +000050 for name in NO_ARG_FUNCTIONS:
51 posix_func = getattr(posix, name, None)
52 if posix_func is not None:
53 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000054 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
Serhiy Storchaka43767632013-11-03 21:31:38 +020056 @unittest.skipUnless(hasattr(posix, 'getresuid'),
57 'test needs posix.getresuid()')
58 def test_getresuid(self):
59 user_ids = posix.getresuid()
60 self.assertEqual(len(user_ids), 3)
61 for val in user_ids:
62 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000063
Serhiy Storchaka43767632013-11-03 21:31:38 +020064 @unittest.skipUnless(hasattr(posix, 'getresgid'),
65 'test needs posix.getresgid()')
66 def test_getresgid(self):
67 group_ids = posix.getresgid()
68 self.assertEqual(len(group_ids), 3)
69 for val in group_ids:
70 self.assertGreaterEqual(val, 0)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000071
Serhiy Storchaka43767632013-11-03 21:31:38 +020072 @unittest.skipUnless(hasattr(posix, 'setresuid'),
73 'test needs posix.setresuid()')
74 def test_setresuid(self):
75 current_user_ids = posix.getresuid()
76 self.assertIsNone(posix.setresuid(*current_user_ids))
77 # -1 means don't change that value.
78 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000079
Serhiy Storchaka43767632013-11-03 21:31:38 +020080 @unittest.skipUnless(hasattr(posix, 'setresuid'),
81 'test needs posix.setresuid()')
82 def test_setresuid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_user_ids = posix.getresuid()
85 if 0 not in current_user_ids:
86 new_user_ids = (current_user_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000088
Serhiy Storchaka43767632013-11-03 21:31:38 +020089 @unittest.skipUnless(hasattr(posix, 'setresgid'),
90 'test needs posix.setresgid()')
91 def test_setresgid(self):
92 current_group_ids = posix.getresgid()
93 self.assertIsNone(posix.setresgid(*current_group_ids))
94 # -1 means don't change that value.
95 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000096
Serhiy Storchaka43767632013-11-03 21:31:38 +020097 @unittest.skipUnless(hasattr(posix, 'setresgid'),
98 'test needs posix.setresgid()')
99 def test_setresgid_exception(self):
100 # Don't do this test if someone is silly enough to run us as root.
101 current_group_ids = posix.getresgid()
102 if 0 not in current_group_ids:
103 new_group_ids = (current_group_ids[0]+1, -1, -1)
104 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis7aed61a2009-11-27 14:09:49 +0000105
Antoine Pitroub7572f02009-12-02 20:46:48 +0000106 @unittest.skipUnless(hasattr(posix, 'initgroups'),
107 "test needs os.initgroups()")
108 def test_initgroups(self):
109 # It takes a string and an integer; check that it raises a TypeError
110 # for other argument lists.
111 self.assertRaises(TypeError, posix.initgroups)
112 self.assertRaises(TypeError, posix.initgroups, None)
113 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
115
116 # If a non-privileged user invokes it, it should fail with OSError
117 # EPERM.
118 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200119 try:
120 name = pwd.getpwuid(posix.getuid()).pw_name
121 except KeyError:
122 # the current UID may not have a pwd entry
123 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000124 try:
125 posix.initgroups(name, 13)
126 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000127 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000128 else:
129 self.fail("Expected OSError to be raised by initgroups")
130
Serhiy Storchaka43767632013-11-03 21:31:38 +0200131 @unittest.skipUnless(hasattr(posix, 'statvfs'),
132 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 def test_statvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200134 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000135
Serhiy Storchaka43767632013-11-03 21:31:38 +0200136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
137 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 def test_fstatvfs(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200139 fp = open(support.TESTFN)
140 try:
141 self.assertTrue(posix.fstatvfs(fp.fileno()))
142 self.assertTrue(posix.statvfs(fp.fileno()))
143 finally:
144 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000145
Serhiy Storchaka43767632013-11-03 21:31:38 +0200146 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
147 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000148 def test_ftruncate(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200149 fp = open(support.TESTFN, 'w+')
150 try:
151 # we need to have some data to truncate
152 fp.write('test')
153 fp.flush()
154 posix.ftruncate(fp.fileno(), 0)
155 finally:
156 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000157
Ross Lagerwall7807c352011-03-17 20:20:30 +0200158 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
159 def test_truncate(self):
160 with open(support.TESTFN, 'w') as fp:
161 fp.write('test')
162 fp.flush()
163 posix.truncate(support.TESTFN, 0)
164
Larry Hastings9cf065c2012-06-22 16:30:09 -0700165 @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 +0200166 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200167 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200168 def test_fexecve(self):
169 fp = os.open(sys.executable, os.O_RDONLY)
170 try:
171 pid = os.fork()
172 if pid == 0:
173 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700174 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200175 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200176 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200177 finally:
178 os.close(fp)
179
180 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
181 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
182 def test_waitid(self):
183 pid = os.fork()
184 if pid == 0:
185 os.chdir(os.path.split(sys.executable)[0])
186 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
187 else:
188 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
189 self.assertEqual(pid, res.si_pid)
190
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200191 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Gregory P. Smith163468a2017-05-29 10:03:41 -0700192 def test_register_at_fork(self):
193 with self.assertRaises(TypeError, msg="Positional args not allowed"):
194 os.register_at_fork(lambda: None)
195 with self.assertRaises(TypeError, msg="Args must be callable"):
196 os.register_at_fork(before=2)
197 with self.assertRaises(TypeError, msg="Args must be callable"):
198 os.register_at_fork(after_in_child="three")
199 with self.assertRaises(TypeError, msg="Args must be callable"):
200 os.register_at_fork(after_in_parent=b"Five")
201 with self.assertRaises(TypeError, msg="Args must not be None"):
202 os.register_at_fork(before=None)
203 with self.assertRaises(TypeError, msg="Args must not be None"):
204 os.register_at_fork(after_in_child=None)
205 with self.assertRaises(TypeError, msg="Args must not be None"):
206 os.register_at_fork(after_in_parent=None)
207 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
208 # Ensure a combination of valid and invalid is an error.
209 os.register_at_fork(before=None, after_in_parent=lambda: 3)
210 with self.assertRaises(TypeError, msg="Invalid arg was allowed"):
211 # Ensure a combination of valid and invalid is an error.
212 os.register_at_fork(before=lambda: None, after_in_child='')
213 # We test actual registrations in their own process so as not to
214 # pollute this one. There is no way to unregister for cleanup.
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200215 code = """if 1:
216 import os
217
218 r, w = os.pipe()
219 fin_r, fin_w = os.pipe()
220
Gregory P. Smith163468a2017-05-29 10:03:41 -0700221 os.register_at_fork(before=lambda: os.write(w, b'A'))
222 os.register_at_fork(after_in_parent=lambda: os.write(w, b'C'))
223 os.register_at_fork(after_in_child=lambda: os.write(w, b'E'))
224 os.register_at_fork(before=lambda: os.write(w, b'B'),
225 after_in_parent=lambda: os.write(w, b'D'),
226 after_in_child=lambda: os.write(w, b'F'))
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200227
228 pid = os.fork()
229 if pid == 0:
230 # At this point, after-forkers have already been executed
231 os.close(w)
232 # Wait for parent to tell us to exit
233 os.read(fin_r, 1)
234 os._exit(0)
235 else:
236 try:
237 os.close(w)
238 with open(r, "rb") as f:
239 data = f.read()
240 assert len(data) == 6, data
241 # Check before-fork callbacks
242 assert data[:2] == b'BA', data
243 # Check after-fork callbacks
244 assert sorted(data[2:]) == list(b'CDEF'), data
245 assert data.index(b'C') < data.index(b'D'), data
246 assert data.index(b'E') < data.index(b'F'), data
247 finally:
248 os.write(fin_w, b'!')
249 """
250 assert_python_ok('-c', code)
251
Ross Lagerwall7807c352011-03-17 20:20:30 +0200252 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
253 def test_lockf(self):
254 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
255 try:
256 os.write(fd, b'test')
257 os.lseek(fd, 0, os.SEEK_SET)
258 posix.lockf(fd, posix.F_LOCK, 4)
259 # section is locked
260 posix.lockf(fd, posix.F_ULOCK, 4)
261 finally:
262 os.close(fd)
263
264 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
265 def test_pread(self):
266 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
267 try:
268 os.write(fd, b'test')
269 os.lseek(fd, 0, os.SEEK_SET)
270 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100271 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200272 self.assertEqual(b'te', posix.read(fd, 2))
273 finally:
274 os.close(fd)
275
276 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
277 def test_pwrite(self):
278 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
279 try:
280 os.write(fd, b'test')
281 os.lseek(fd, 0, os.SEEK_SET)
282 posix.pwrite(fd, b'xx', 1)
283 self.assertEqual(b'txxt', posix.read(fd, 4))
284 finally:
285 os.close(fd)
286
287 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
288 "test needs posix.posix_fallocate()")
289 def test_posix_fallocate(self):
290 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
291 try:
292 posix.posix_fallocate(fd, 0, 10)
293 except OSError as inst:
294 # issue10812, ZFS doesn't appear to support posix_fallocate,
295 # so skip Solaris-based since they are likely to have ZFS.
296 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
297 raise
298 finally:
299 os.close(fd)
300
301 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
302 "test needs posix.posix_fadvise()")
303 def test_posix_fadvise(self):
304 fd = os.open(support.TESTFN, os.O_RDONLY)
305 try:
306 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
307 finally:
308 os.close(fd)
309
Larry Hastings9cf065c2012-06-22 16:30:09 -0700310 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
311 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200312 now = time.time()
313 fd = os.open(support.TESTFN, os.O_RDONLY)
314 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700315 posix.utime(fd)
316 posix.utime(fd, None)
317 self.assertRaises(TypeError, posix.utime, fd, (None, None))
318 self.assertRaises(TypeError, posix.utime, fd, (now, None))
319 self.assertRaises(TypeError, posix.utime, fd, (None, now))
320 posix.utime(fd, (int(now), int(now)))
321 posix.utime(fd, (now, now))
322 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
323 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
324 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
325 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
326 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
327
Ross Lagerwall7807c352011-03-17 20:20:30 +0200328 finally:
329 os.close(fd)
330
Larry Hastings9cf065c2012-06-22 16:30:09 -0700331 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
332 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200333 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700334 posix.utime(support.TESTFN, None, follow_symlinks=False)
335 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
336 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
337 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
338 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
339 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
340 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200341
342 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
343 def test_writev(self):
344 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
345 try:
Victor Stinner57ddf782014-01-08 15:21:28 +0100346 n = os.writev(fd, (b'test1', b'tt2', b't3'))
347 self.assertEqual(n, 10)
348
Ross Lagerwall7807c352011-03-17 20:20:30 +0200349 os.lseek(fd, 0, os.SEEK_SET)
350 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
Victor Stinner57ddf782014-01-08 15:21:28 +0100351
352 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100353 try:
354 size = posix.writev(fd, [])
355 except OSError:
356 # writev(fd, []) raises OSError(22, "Invalid argument")
357 # on OpenIndiana
358 pass
359 else:
360 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200361 finally:
362 os.close(fd)
363
364 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
365 def test_readv(self):
366 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
367 try:
368 os.write(fd, b'test1tt2t3')
369 os.lseek(fd, 0, os.SEEK_SET)
370 buf = [bytearray(i) for i in [5, 3, 2]]
371 self.assertEqual(posix.readv(fd, buf), 10)
372 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
Victor Stinner57ddf782014-01-08 15:21:28 +0100373
374 # Issue #20113: empty list of buffers should not crash
Victor Stinnercd5ca6a2014-01-08 16:01:31 +0100375 try:
376 size = posix.readv(fd, [])
377 except OSError:
378 # readv(fd, []) raises OSError(22, "Invalid argument")
379 # on OpenIndiana
380 pass
381 else:
382 self.assertEqual(size, 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200383 finally:
384 os.close(fd)
385
Serhiy Storchaka43767632013-11-03 21:31:38 +0200386 @unittest.skipUnless(hasattr(posix, 'dup'),
387 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000388 def test_dup(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200389 fp = open(support.TESTFN)
390 try:
391 fd = posix.dup(fp.fileno())
392 self.assertIsInstance(fd, int)
393 os.close(fd)
394 finally:
395 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000396
Serhiy Storchaka43767632013-11-03 21:31:38 +0200397 @unittest.skipUnless(hasattr(posix, 'confstr'),
398 'test needs posix.confstr()')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000399 def test_confstr(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200400 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
401 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000402
Serhiy Storchaka43767632013-11-03 21:31:38 +0200403 @unittest.skipUnless(hasattr(posix, 'dup2'),
404 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000405 def test_dup2(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200406 fp1 = open(support.TESTFN)
407 fp2 = open(support.TESTFN)
408 try:
409 posix.dup2(fp1.fileno(), fp2.fileno())
410 finally:
411 fp1.close()
412 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000413
Charles-François Natali1e045b12011-05-22 20:42:32 +0200414 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200415 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200416 def test_oscloexec(self):
417 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
418 self.addCleanup(os.close, fd)
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200419 self.assertFalse(os.get_inheritable(fd))
Charles-François Natali1e045b12011-05-22 20:42:32 +0200420
Serhiy Storchaka43767632013-11-03 21:31:38 +0200421 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
422 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000423 def test_osexlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200424 fd = os.open(support.TESTFN,
425 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
426 self.assertRaises(OSError, os.open, support.TESTFN,
427 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
428 os.close(fd)
429
430 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000431 fd = os.open(support.TESTFN,
Serhiy Storchaka43767632013-11-03 21:31:38 +0200432 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000433 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000434 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
435 os.close(fd)
436
Serhiy Storchaka43767632013-11-03 21:31:38 +0200437 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
438 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000439 def test_osshlock(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200440 fd1 = os.open(support.TESTFN,
441 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
442 fd2 = os.open(support.TESTFN,
443 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
444 os.close(fd2)
445 os.close(fd1)
446
447 if hasattr(posix, "O_EXLOCK"):
448 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000449 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka43767632013-11-03 21:31:38 +0200450 self.assertRaises(OSError, os.open, support.TESTFN,
451 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
452 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000453
Serhiy Storchaka43767632013-11-03 21:31:38 +0200454 @unittest.skipUnless(hasattr(posix, 'fstat'),
455 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000456 def test_fstat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200457 fp = open(support.TESTFN)
458 try:
459 self.assertTrue(posix.fstat(fp.fileno()))
460 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200461
Serhiy Storchaka43767632013-11-03 21:31:38 +0200462 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700463 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200464 posix.stat, float(fp.fileno()))
465 finally:
466 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000467
Serhiy Storchaka43767632013-11-03 21:31:38 +0200468 @unittest.skipUnless(hasattr(posix, 'stat'),
469 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000470 def test_stat(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200471 self.assertTrue(posix.stat(support.TESTFN))
472 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200473
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300474 self.assertWarnsRegex(DeprecationWarning,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700475 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300476 posix.stat, bytearray(os.fsencode(support.TESTFN)))
Serhiy Storchaka43767632013-11-03 21:31:38 +0200477 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700478 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200479 posix.stat, None)
480 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, list(support.TESTFN))
483 self.assertRaisesRegex(TypeError,
Brett Cannon3f9183b2016-08-26 14:44:48 -0700484 'should be string, bytes, os.PathLike or integer, not',
Serhiy Storchaka43767632013-11-03 21:31:38 +0200485 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000486
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000487 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
Xavier de Gaye3a4e9892016-12-13 10:00:01 +0100488 @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000489 def test_mkfifo(self):
490 support.unlink(support.TESTFN)
491 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
492 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
493
494 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
495 "don't have mknod()/S_IFIFO")
Xavier de Gaye3a4e9892016-12-13 10:00:01 +0100496 @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000497 def test_mknod(self):
498 # Test using mknod() to create a FIFO (the only use specified
499 # by POSIX).
500 support.unlink(support.TESTFN)
501 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
502 try:
503 posix.mknod(support.TESTFN, mode, 0)
504 except OSError as e:
505 # Some old systems don't allow unprivileged users to use
506 # mknod(), or only support creating device nodes.
507 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
508 else:
509 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
510
Martin Panterbf19d162015-09-09 01:01:13 +0000511 # Keyword arguments are also supported
512 support.unlink(support.TESTFN)
513 try:
514 posix.mknod(path=support.TESTFN, mode=mode, device=0,
515 dir_fd=None)
516 except OSError as e:
517 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
518
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300519 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
520 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
521 def test_makedev(self):
522 st = posix.stat(support.TESTFN)
523 dev = st.st_dev
524 self.assertIsInstance(dev, int)
525 self.assertGreaterEqual(dev, 0)
526
527 major = posix.major(dev)
528 self.assertIsInstance(major, int)
529 self.assertGreaterEqual(major, 0)
530 self.assertEqual(posix.major(dev), major)
531 self.assertRaises(TypeError, posix.major, float(dev))
532 self.assertRaises(TypeError, posix.major)
533 self.assertRaises((ValueError, OverflowError), posix.major, -1)
534
535 minor = posix.minor(dev)
536 self.assertIsInstance(minor, int)
537 self.assertGreaterEqual(minor, 0)
538 self.assertEqual(posix.minor(dev), minor)
539 self.assertRaises(TypeError, posix.minor, float(dev))
540 self.assertRaises(TypeError, posix.minor)
541 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
542
Victor Stinner12953ff2017-07-27 16:55:54 +0200543 if sys.platform.startswith('freebsd') and dev >= 0x1_0000_0000:
544 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
545 "64-bit dev to 32-bit")
546
Serhiy Storchaka16b2e4f2015-04-20 09:22:13 +0300547 self.assertEqual(posix.makedev(major, minor), dev)
548 self.assertRaises(TypeError, posix.makedev, float(major), minor)
549 self.assertRaises(TypeError, posix.makedev, major, float(minor))
550 self.assertRaises(TypeError, posix.makedev, major)
551 self.assertRaises(TypeError, posix.makedev)
552
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200553 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000554 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200555 def check_stat(uid, gid):
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200556 if stat_func is not None:
557 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200558 self.assertEqual(stat.st_uid, uid)
559 self.assertEqual(stat.st_gid, gid)
560 uid = os.getuid()
561 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200562 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200563 chown_func(first_param, uid, gid)
564 check_stat(uid, gid)
565 chown_func(first_param, -1, gid)
566 check_stat(uid, gid)
567 chown_func(first_param, uid, -1)
568 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200569
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200570 if uid == 0:
571 # Try an amusingly large uid/gid to make sure we handle
572 # large unsigned values. (chown lets you use any
573 # uid/gid you like, even if they aren't defined.)
574 #
575 # This problem keeps coming up:
576 # http://bugs.python.org/issue1747858
577 # http://bugs.python.org/issue4591
578 # http://bugs.python.org/issue15301
579 # Hopefully the fix in 4591 fixes it for good!
580 #
581 # This part of the test only runs when run as root.
582 # Only scary people run their tests as root.
583
584 big_value = 2**31
585 chown_func(first_param, big_value, big_value)
586 check_stat(big_value, big_value)
587 chown_func(first_param, -1, -1)
588 check_stat(big_value, big_value)
589 chown_func(first_param, uid, gid)
590 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200591 elif platform.system() in ('HP-UX', 'SunOS'):
592 # HP-UX and Solaris can allow a non-root user to chown() to root
593 # (issue #5113)
594 raise unittest.SkipTest("Skipping because of non-standard chown() "
595 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000596 else:
597 # non-root cannot chown to root, raises OSError
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200598 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200599 check_stat(uid, gid)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200600 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200601 check_stat(uid, gid)
Serhiy Storchakaa2964b32013-02-21 14:34:36 +0200602 if 0 not in os.getgroups():
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200603 self.assertRaises(OSError, chown_func, first_param, -1, 0)
604 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200605 # test illegal types
606 for t in str, float:
607 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
608 check_stat(uid, gid)
609 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
610 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000611
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000612 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
613 def test_chown(self):
614 # raise an OSError if the file does not exist
615 os.unlink(support.TESTFN)
616 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000617
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000618 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200619 support.create_empty_file(support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200620 self._test_all_chown_common(posix.chown, support.TESTFN,
621 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000622
623 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
624 def test_fchown(self):
625 os.unlink(support.TESTFN)
626
627 # re-create the file
628 test_file = open(support.TESTFN, 'w')
629 try:
630 fd = test_file.fileno()
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200631 self._test_all_chown_common(posix.fchown, fd,
632 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000633 finally:
634 test_file.close()
635
636 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
637 def test_lchown(self):
638 os.unlink(support.TESTFN)
639 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700640 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 self._test_all_chown_common(posix.lchown, support.TESTFN,
642 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000643
Serhiy Storchaka43767632013-11-03 21:31:38 +0200644 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000645 def test_chdir(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200646 posix.chdir(os.curdir)
647 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000648
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000649 def test_listdir(self):
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300650 self.assertIn(support.TESTFN, posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000651
652 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700653 # When listdir is called without argument,
654 # it's the same as listdir(os.curdir).
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300655 self.assertIn(support.TESTFN, posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000656
Larry Hastingsfdaea062012-06-25 04:42:23 -0700657 def test_listdir_bytes(self):
658 # When listdir is called with a bytes object,
659 # the returned strings are of type bytes.
Serhiy Storchaka1180e5a2017-07-11 06:36:46 +0300660 self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
661
662 def test_listdir_bytes_like(self):
663 for cls in bytearray, memoryview:
664 with self.assertWarns(DeprecationWarning):
665 names = posix.listdir(cls(b'.'))
666 self.assertIn(os.fsencode(support.TESTFN), names)
667 for name in names:
668 self.assertIs(type(name), bytes)
Larry Hastingsfdaea062012-06-25 04:42:23 -0700669
670 @unittest.skipUnless(posix.listdir in os.supports_fd,
671 "test needs fd support for posix.listdir()")
672 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000673 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100674 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000675 self.assertEqual(
676 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700677 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000678 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100679 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100680 self.assertEqual(
681 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100683 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000684
Serhiy Storchaka43767632013-11-03 21:31:38 +0200685 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000686 def test_access(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200687 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000688
Serhiy Storchaka43767632013-11-03 21:31:38 +0200689 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000690 def test_umask(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200691 old_mask = posix.umask(0)
692 self.assertIsInstance(old_mask, int)
693 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000694
Serhiy Storchaka43767632013-11-03 21:31:38 +0200695 @unittest.skipUnless(hasattr(posix, 'strerror'),
696 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000697 def test_strerror(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200698 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000699
Serhiy Storchaka43767632013-11-03 21:31:38 +0200700 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000701 def test_pipe(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200702 reader, writer = posix.pipe()
703 os.close(reader)
704 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000705
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200706 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200707 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200708 def test_pipe2(self):
709 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
710 self.assertRaises(TypeError, os.pipe2, 0, 0)
711
Charles-François Natali368f34b2011-06-06 19:49:47 +0200712 # try calling with flags = 0, like os.pipe()
713 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200714 os.close(r)
715 os.close(w)
716
717 # test flags
718 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
719 self.addCleanup(os.close, r)
720 self.addCleanup(os.close, w)
Victor Stinnerbff989e2013-08-28 12:25:40 +0200721 self.assertFalse(os.get_inheritable(r))
722 self.assertFalse(os.get_inheritable(w))
Victor Stinner1db9e7b2014-07-29 22:32:47 +0200723 self.assertFalse(os.get_blocking(r))
724 self.assertFalse(os.get_blocking(w))
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200725 # try reading from an empty pipe: this should fail, not block
726 self.assertRaises(OSError, os.read, r, 1)
727 # try a write big enough to fill-up the pipe: this should either
728 # fail or perform a partial write, not block
729 try:
730 os.write(w, b'x' * support.PIPE_MAX_SIZE)
731 except OSError:
732 pass
733
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200734 @support.cpython_only
735 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
736 @support.requires_linux_version(2, 6, 27)
737 def test_pipe2_c_limits(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200738 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200739 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200740 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1)
741 self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
742
Serhiy Storchaka43767632013-11-03 21:31:38 +0200743 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000744 def test_utime(self):
Serhiy Storchaka43767632013-11-03 21:31:38 +0200745 now = time.time()
746 posix.utime(support.TESTFN, None)
747 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
748 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
749 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
750 posix.utime(support.TESTFN, (int(now), int(now)))
751 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000752
Larry Hastings9cf065c2012-06-22 16:30:09 -0700753 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700754 st = os.stat(target_file)
755 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000756
757 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
758 flags = st.st_flags | stat.UF_IMMUTABLE
759 try:
760 chflags_func(target_file, flags, **kwargs)
761 except OSError as err:
762 if err.errno != errno.EOPNOTSUPP:
763 raise
764 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
765 self.skipTest(msg)
766
Ned Deily3eb67d52011-06-28 00:00:28 -0700767 try:
768 new_st = os.stat(target_file)
769 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
770 try:
771 fd = open(target_file, 'w+')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200772 except OSError as e:
Ned Deily3eb67d52011-06-28 00:00:28 -0700773 self.assertEqual(e.errno, errno.EPERM)
774 finally:
775 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000776
Ned Deily3eb67d52011-06-28 00:00:28 -0700777 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
778 def test_chflags(self):
779 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
780
781 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
782 def test_lchflags_regular_file(self):
783 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700784 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700785
786 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
787 def test_lchflags_symlink(self):
788 testfn_st = os.stat(support.TESTFN)
789
790 self.assertTrue(hasattr(testfn_st, 'st_flags'))
791
792 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
793 self.teardown_files.append(_DUMMY_SYMLINK)
794 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
795
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 def chflags_nofollow(path, flags):
797 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700798
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000800 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
801 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
802 try:
803 fn(_DUMMY_SYMLINK, flags)
804 except OSError as err:
805 if err.errno != errno.EOPNOTSUPP:
806 raise
807 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
808 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700809 try:
810 new_testfn_st = os.stat(support.TESTFN)
811 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
812
813 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
814 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
815 new_dummy_symlink_st.st_flags)
816 finally:
817 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000818
Guido van Rossum98297ee2007-11-06 21:34:58 +0000819 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000820 if os.name == "nt":
821 item_type = str
822 else:
823 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000824 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000825 self.assertEqual(type(k), item_type)
826 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000827
Serhiy Storchaka77703942017-06-25 07:33:01 +0300828 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
829 def test_putenv(self):
830 with self.assertRaises(ValueError):
831 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
832 with self.assertRaises(ValueError):
833 os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
834 with self.assertRaises(ValueError):
835 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
836 with self.assertRaises(ValueError):
837 os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
838 with self.assertRaises(ValueError):
839 os.putenv('FRUIT=ORANGE', 'lemon')
840 with self.assertRaises(ValueError):
841 os.putenv(b'FRUIT=ORANGE', b'lemon')
842
Serhiy Storchaka43767632013-11-03 21:31:38 +0200843 @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000844 def test_getcwd_long_pathnames(self):
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500845 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
846 curdir = os.getcwd()
847 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000848
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500849 try:
850 os.mkdir(base_path)
851 os.chdir(base_path)
852 except:
853 # Just returning nothing instead of the SkipTest exception, because
854 # the test results in Error in that case. Is that ok?
855 # raise unittest.SkipTest("cannot create directory for testing")
856 return
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000857
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500858 def _create_and_do_getcwd(dirname, current_path_length = 0):
859 try:
860 os.mkdir(dirname)
861 except:
862 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000863
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500864 os.chdir(dirname)
865 try:
866 os.getcwd()
867 if current_path_length < 1027:
868 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
869 finally:
870 os.chdir('..')
871 os.rmdir(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000872
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500873 _create_and_do_getcwd(dirname)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000874
Benjamin Peterson3a7dffa2013-08-23 21:01:48 -0500875 finally:
876 os.chdir(curdir)
877 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000878
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200879 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
880 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
881 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
882 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +0000883 user = pwd.getpwuid(os.getuid())[0]
884 group = pwd.getpwuid(os.getuid())[3]
885 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200886
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200887
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000888 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000889 def test_getgroups(self):
Jesus Cea61f32cb2014-06-28 18:39:35 +0200890 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000891 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200892 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000893
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200894 try:
895 idg_groups = set(int(g) for g in groups.split())
896 except ValueError:
897 idg_groups = set()
898 if ret is not None or not idg_groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000899 raise unittest.SkipTest("need working 'id -G'")
900
Ned Deily028915e2013-02-02 15:08:52 -0800901 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
902 if sys.platform == 'darwin':
903 import sysconfig
904 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily04cdfa12014-06-25 13:36:14 -0700905 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deily028915e2013-02-02 15:08:52 -0800906 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
907
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000908 # 'id -G' and 'os.getgroups()' should return the same
Xavier de Gaye24c3b492016-10-19 11:00:26 +0200909 # groups, ignoring order, duplicates, and the effective gid.
910 # #10822/#26944 - It is implementation defined whether
911 # posix.getgroups() includes the effective gid.
912 symdiff = idg_groups.symmetric_difference(posix.getgroups())
913 self.assertTrue(not symdiff or symdiff == {posix.getegid()})
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000914
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000915 # tests for the posix *at functions follow
916
Larry Hastings9cf065c2012-06-22 16:30:09 -0700917 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
918 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000919 f = posix.open(posix.getcwd(), posix.O_RDONLY)
920 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700921 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000922 finally:
923 posix.close(f)
924
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
926 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000927 os.chmod(support.TESTFN, stat.S_IRUSR)
928
929 f = posix.open(posix.getcwd(), posix.O_RDONLY)
930 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000932
933 s = posix.stat(support.TESTFN)
934 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
935 finally:
936 posix.close(f)
937
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
939 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000940 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200941 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000942
943 f = posix.open(posix.getcwd(), posix.O_RDONLY)
944 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700945 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000946 finally:
947 posix.close(f)
948
Larry Hastings9cf065c2012-06-22 16:30:09 -0700949 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
950 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000951 support.unlink(support.TESTFN)
952 with open(support.TESTFN, 'w') as outfile:
953 outfile.write("testline\n")
954
955 f = posix.open(posix.getcwd(), posix.O_RDONLY)
956 try:
957 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700958 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000959 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200960 s2 = posix.stat(support.TESTFN, dir_fd=None)
961 self.assertEqual(s1, s2)
Serhiy Storchaka7155b882016-04-08 08:48:20 +0300962 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200963 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
Serhiy Storchaka7155b882016-04-08 08:48:20 +0300964 self.assertRaisesRegex(TypeError, 'should be integer or None, not',
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200965 posix.stat, support.TESTFN, dir_fd=float(f))
966 self.assertRaises(OverflowError,
967 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000968 finally:
969 posix.close(f)
970
Larry Hastings9cf065c2012-06-22 16:30:09 -0700971 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
972 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000973 f = posix.open(posix.getcwd(), posix.O_RDONLY)
974 try:
975 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700976 posix.utime(support.TESTFN, None, dir_fd=f)
977 posix.utime(support.TESTFN, dir_fd=f)
978 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
979 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
980 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
981 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
982 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
983 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
984 posix.utime(support.TESTFN, (now, now), dir_fd=f)
985 posix.utime(support.TESTFN,
986 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
987 posix.utime(support.TESTFN, dir_fd=f,
988 times=(int(now), int((now - int(now)) * 1e9)))
989
Larry Hastings90867a52012-06-22 17:01:41 -0700990 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -0700991 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -0700992 try:
993 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +0200994 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -0700995 # whoops! using both together not supported on this platform.
996 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -0700997
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000998 finally:
999 posix.close(f)
1000
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
Xavier de Gaye3a4e9892016-12-13 10:00:01 +01001002 @unittest.skipIf(android_not_root, "hard link not allowed, non root user")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001003 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001004 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1005 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001006 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001007 # should have same inodes
1008 self.assertEqual(posix.stat(support.TESTFN)[1],
1009 posix.stat(support.TESTFN + 'link')[1])
1010 finally:
1011 posix.close(f)
1012 support.unlink(support.TESTFN + 'link')
1013
Larry Hastings9cf065c2012-06-22 16:30:09 -07001014 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
1015 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001016 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1017 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001018 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001019 posix.stat(support.TESTFN + 'dir') # should not raise exception
1020 finally:
1021 posix.close(f)
1022 support.rmtree(support.TESTFN + 'dir')
1023
Larry Hastings9cf065c2012-06-22 16:30:09 -07001024 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
1025 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
Xavier de Gaye3a4e9892016-12-13 10:00:01 +01001026 @unittest.skipIf(android_not_root, "mknod not allowed, non root user")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001028 # Test using mknodat() to create a FIFO (the only use specified
1029 # by POSIX).
1030 support.unlink(support.TESTFN)
1031 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
1032 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1033 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001034 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001035 except OSError as e:
1036 # Some old systems don't allow unprivileged users to use
1037 # mknod(), or only support creating device nodes.
1038 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
1039 else:
1040 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1041 finally:
1042 posix.close(f)
1043
Larry Hastings9cf065c2012-06-22 16:30:09 -07001044 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
1045 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001046 support.unlink(support.TESTFN)
1047 with open(support.TESTFN, 'w') as outfile:
1048 outfile.write("testline\n")
1049 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001050 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001051 try:
1052 res = posix.read(b, 9).decode(encoding="utf-8")
1053 self.assertEqual("testline\n", res)
1054 finally:
1055 posix.close(a)
1056 posix.close(b)
1057
Larry Hastings9cf065c2012-06-22 16:30:09 -07001058 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
1059 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001060 os.symlink(support.TESTFN, support.TESTFN + 'link')
1061 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1062 try:
1063 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001065 finally:
1066 support.unlink(support.TESTFN + 'link')
1067 posix.close(f)
1068
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
1070 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001071 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +02001072 support.create_empty_file(support.TESTFN + 'ren')
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.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001076 except:
1077 posix.rename(support.TESTFN + 'ren', support.TESTFN)
1078 raise
1079 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +02001080 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001081 finally:
1082 posix.close(f)
1083
Larry Hastings9cf065c2012-06-22 16:30:09 -07001084 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
1085 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001086 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1087 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001088 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001089 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
1090 finally:
1091 posix.close(f)
1092 support.unlink(support.TESTFN + 'link')
1093
Larry Hastings9cf065c2012-06-22 16:30:09 -07001094 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
1095 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001096 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +02001097 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +02001098 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001099 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001100 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001101 except:
1102 support.unlink(support.TESTFN + 'del')
1103 raise
1104 else:
1105 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
1106 finally:
1107 posix.close(f)
1108
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
Xavier de Gaye3a4e9892016-12-13 10:00:01 +01001110 @unittest.skipIf(android_not_root, "mkfifo not allowed, non root user")
Larry Hastings9cf065c2012-06-22 16:30:09 -07001111 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001112 support.unlink(support.TESTFN)
1113 f = posix.open(posix.getcwd(), posix.O_RDONLY)
1114 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -07001115 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00001116 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
1117 finally:
1118 posix.close(f)
1119
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001120 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
1121 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +02001122 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -05001123 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001124
1125 @requires_sched_h
1126 def test_sched_yield(self):
1127 # This has no error conditions (at least on Linux).
1128 posix.sched_yield()
1129
1130 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02001131 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
1132 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001133 def test_sched_priority(self):
1134 # Round-robin usually has interesting priorities.
1135 pol = posix.SCHED_RR
1136 lo = posix.sched_get_priority_min(pol)
1137 hi = posix.sched_get_priority_max(pol)
1138 self.assertIsInstance(lo, int)
1139 self.assertIsInstance(hi, int)
1140 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -05001141 # OSX evidently just returns 15 without checking the argument.
1142 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -05001143 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
1144 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001145
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001146 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001147 def test_get_and_set_scheduler_and_param(self):
1148 possible_schedulers = [sched for name, sched in posix.__dict__.items()
1149 if name.startswith("SCHED_")]
1150 mine = posix.sched_getscheduler(0)
1151 self.assertIn(mine, possible_schedulers)
1152 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001153 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001154 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001155 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001156 raise
1157 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +02001158 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001159 self.assertRaises(OSError, posix.sched_getscheduler, -1)
1160 self.assertRaises(OSError, posix.sched_getparam, -1)
1161 param = posix.sched_getparam(0)
1162 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001163
Charles-François Natalib402a5c2013-01-13 14:13:25 +01001164 # POSIX states that calling sched_setparam() or sched_setscheduler() on
1165 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
1166 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
1167 if not sys.platform.startswith(('freebsd', 'netbsd')):
1168 try:
1169 posix.sched_setscheduler(0, mine, param)
1170 posix.sched_setparam(0, param)
1171 except OSError as e:
1172 if e.errno != errno.EPERM:
1173 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +02001174 self.assertRaises(OSError, posix.sched_setparam, -1, param)
1175
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001176 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
1177 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
1178 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
1179 param = posix.sched_param(None)
1180 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
1181 large = 214748364700
1182 param = posix.sched_param(large)
1183 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1184 param = posix.sched_param(sched_priority=-large)
1185 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
1186
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05001187 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001188 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -05001189 try:
1190 interval = posix.sched_rr_get_interval(0)
1191 except OSError as e:
1192 # This likely means that sched_rr_get_interval is only valid for
1193 # processes with the SCHED_RR scheduler in effect.
1194 if e.errno != errno.EINVAL:
1195 raise
1196 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001197 self.assertIsInstance(interval, float)
1198 # Reasonable constraints, I think.
1199 self.assertGreaterEqual(interval, 0.)
1200 self.assertLess(interval, 1.)
1201
Benjamin Peterson2740af82011-08-02 17:41:34 -05001202 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +02001203 def test_sched_getaffinity(self):
1204 mask = posix.sched_getaffinity(0)
1205 self.assertIsInstance(mask, set)
1206 self.assertGreaterEqual(len(mask), 1)
1207 self.assertRaises(OSError, posix.sched_getaffinity, -1)
1208 for cpu in mask:
1209 self.assertIsInstance(cpu, int)
1210 self.assertGreaterEqual(cpu, 0)
1211 self.assertLess(cpu, 1 << 32)
1212
1213 @requires_sched_affinity
1214 def test_sched_setaffinity(self):
1215 mask = posix.sched_getaffinity(0)
1216 if len(mask) > 1:
1217 # Empty masks are forbidden
1218 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001219 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +02001220 self.assertEqual(posix.sched_getaffinity(0), mask)
1221 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
1222 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
1223 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001224 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
1225
Victor Stinner8b905bd2011-10-25 13:34:04 +02001226 def test_rtld_constants(self):
1227 # check presence of major RTLD_* constants
1228 posix.RTLD_LAZY
1229 posix.RTLD_NOW
1230 posix.RTLD_GLOBAL
1231 posix.RTLD_LOCAL
1232
Jesus Cea60c13dd2012-06-23 02:58:14 +02001233 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1234 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001235 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001236 # Even if the filesystem doesn't report holes,
1237 # if the OS supports it the SEEK_* constants
1238 # will be defined and will have a consistent
1239 # behaviour:
1240 # os.SEEK_DATA = current position
1241 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001242 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001243 fp.write(b"hello")
1244 fp.flush()
1245 size = fp.tell()
1246 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001247 try :
1248 for i in range(size):
1249 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1250 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1251 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1252 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1253 except OSError :
1254 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1255 # but it is not true.
1256 # For instance:
1257 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1258 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001259
Larry Hastingsb0827312014-02-09 22:05:19 -08001260 def test_path_error2(self):
1261 """
1262 Test functions that call path_error2(), providing two filenames in their exceptions.
1263 """
Victor Stinner047b7ae2014-10-05 17:37:41 +02001264 for name in ("rename", "replace", "link"):
Larry Hastingsb0827312014-02-09 22:05:19 -08001265 function = getattr(os, name, None)
Victor Stinnerbed04a72014-10-05 17:37:59 +02001266 if function is None:
1267 continue
Larry Hastingsb0827312014-02-09 22:05:19 -08001268
Victor Stinnerbed04a72014-10-05 17:37:59 +02001269 for dst in ("noodly2", support.TESTFN):
1270 try:
1271 function('doesnotexistfilename', dst)
1272 except OSError as e:
1273 self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e))
1274 break
1275 else:
1276 self.fail("No valid path_error2() test for os." + name)
Larry Hastingsb0827312014-02-09 22:05:19 -08001277
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001278 def test_path_with_null_character(self):
1279 fn = support.TESTFN
1280 fn_with_NUL = fn + '\0'
1281 self.addCleanup(support.unlink, fn)
1282 support.unlink(fn)
1283 fd = None
1284 try:
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001285 with self.assertRaises(ValueError):
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001286 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1287 finally:
1288 if fd is not None:
1289 os.close(fd)
1290 self.assertFalse(os.path.exists(fn))
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001291 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001292 self.assertFalse(os.path.exists(fn))
1293 open(fn, 'wb').close()
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +03001294 self.assertRaises(ValueError, os.stat, fn_with_NUL)
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +03001295
1296 def test_path_with_null_byte(self):
1297 fn = os.fsencode(support.TESTFN)
1298 fn_with_NUL = fn + b'\0'
1299 self.addCleanup(support.unlink, fn)
1300 support.unlink(fn)
1301 fd = None
1302 try:
1303 with self.assertRaises(ValueError):
1304 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
1305 finally:
1306 if fd is not None:
1307 os.close(fd)
1308 self.assertFalse(os.path.exists(fn))
1309 self.assertRaises(ValueError, os.mkdir, fn_with_NUL)
1310 self.assertFalse(os.path.exists(fn))
1311 open(fn, 'wb').close()
1312 self.assertRaises(ValueError, os.stat, fn_with_NUL)
1313
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001314class PosixGroupsTester(unittest.TestCase):
1315
1316 def setUp(self):
1317 if posix.getuid() != 0:
1318 raise unittest.SkipTest("not enough privileges")
1319 if not hasattr(posix, 'getgroups'):
1320 raise unittest.SkipTest("need posix.getgroups")
1321 if sys.platform == 'darwin':
1322 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1323 self.saved_groups = posix.getgroups()
1324
1325 def tearDown(self):
1326 if hasattr(posix, 'setgroups'):
1327 posix.setgroups(self.saved_groups)
1328 elif hasattr(posix, 'initgroups'):
1329 name = pwd.getpwuid(posix.getuid()).pw_name
1330 posix.initgroups(name, self.saved_groups[0])
1331
1332 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1333 "test needs posix.initgroups()")
1334 def test_initgroups(self):
1335 # find missing group
1336
Benjamin Peterson659a6f52014-03-01 19:14:12 -05001337 g = max(self.saved_groups or [0]) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001338 name = pwd.getpwuid(posix.getuid()).pw_name
1339 posix.initgroups(name, g)
1340 self.assertIn(g, posix.getgroups())
1341
1342 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1343 "test needs posix.setgroups()")
1344 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001345 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001346 posix.setgroups(groups)
1347 self.assertListEqual(groups, posix.getgroups())
1348
Neal Norwitze241ce82003-02-17 18:17:05 +00001349def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001350 try:
1351 support.run_unittest(PosixTester, PosixGroupsTester)
1352 finally:
1353 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001354
1355if __name__ == '__main__':
1356 test_main()