blob: 5843b030399ef33c01d254035386d022445ed6a4 [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
R. David Murrayeb3615d2009-04-22 02:24:39 +00004
5# Skip these tests if there is no posix module.
6posix = support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitroub7572f02009-12-02 20:46:48 +00008import errno
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Charles-François Natali1e045b12011-05-22 20:42:32 +020012import fcntl
Charles-François Nataliab2d58e2012-04-17 19:48:35 +020013import platform
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000014import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000015import shutil
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
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000056 if hasattr(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)
62
63 if hasattr(posix, 'getresgid'):
64 def test_getresgid(self):
65 group_ids = posix.getresgid()
66 self.assertEqual(len(group_ids), 3)
67 for val in group_ids:
68 self.assertGreaterEqual(val, 0)
69
70 if hasattr(posix, 'setresuid'):
71 def test_setresuid(self):
72 current_user_ids = posix.getresuid()
73 self.assertIsNone(posix.setresuid(*current_user_ids))
74 # -1 means don't change that value.
75 self.assertIsNone(posix.setresuid(-1, -1, -1))
76
77 def test_setresuid_exception(self):
78 # Don't do this test if someone is silly enough to run us as root.
79 current_user_ids = posix.getresuid()
80 if 0 not in current_user_ids:
81 new_user_ids = (current_user_ids[0]+1, -1, -1)
82 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
83
84 if hasattr(posix, 'setresgid'):
85 def test_setresgid(self):
86 current_group_ids = posix.getresgid()
87 self.assertIsNone(posix.setresgid(*current_group_ids))
88 # -1 means don't change that value.
89 self.assertIsNone(posix.setresgid(-1, -1, -1))
90
91 def test_setresgid_exception(self):
92 # Don't do this test if someone is silly enough to run us as root.
93 current_group_ids = posix.getresgid()
94 if 0 not in current_group_ids:
95 new_group_ids = (current_group_ids[0]+1, -1, -1)
96 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
97
Antoine Pitroub7572f02009-12-02 20:46:48 +000098 @unittest.skipUnless(hasattr(posix, 'initgroups'),
99 "test needs os.initgroups()")
100 def test_initgroups(self):
101 # It takes a string and an integer; check that it raises a TypeError
102 # for other argument lists.
103 self.assertRaises(TypeError, posix.initgroups)
104 self.assertRaises(TypeError, posix.initgroups, None)
105 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
106 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
107
108 # If a non-privileged user invokes it, it should fail with OSError
109 # EPERM.
110 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200111 try:
112 name = pwd.getpwuid(posix.getuid()).pw_name
113 except KeyError:
114 # the current UID may not have a pwd entry
115 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000116 try:
117 posix.initgroups(name, 13)
118 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000119 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000120 else:
121 self.fail("Expected OSError to be raised by initgroups")
122
Neal Norwitze241ce82003-02-17 18:17:05 +0000123 def test_statvfs(self):
124 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000125 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000126
127 def test_fstatvfs(self):
128 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000129 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000130 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000131 self.assertTrue(posix.fstatvfs(fp.fileno()))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700132 self.assertTrue(posix.statvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 finally:
134 fp.close()
135
136 def test_ftruncate(self):
137 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000138 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000139 try:
140 # we need to have some data to truncate
141 fp.write('test')
142 fp.flush()
143 posix.ftruncate(fp.fileno(), 0)
144 finally:
145 fp.close()
146
Ross Lagerwall7807c352011-03-17 20:20:30 +0200147 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
148 def test_truncate(self):
149 with open(support.TESTFN, 'w') as fp:
150 fp.write('test')
151 fp.flush()
152 posix.truncate(support.TESTFN, 0)
153
Larry Hastings9cf065c2012-06-22 16:30:09 -0700154 @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 +0200155 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200156 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200157 def test_fexecve(self):
158 fp = os.open(sys.executable, os.O_RDONLY)
159 try:
160 pid = os.fork()
161 if pid == 0:
162 os.chdir(os.path.split(sys.executable)[0])
Larry Hastings9cf065c2012-06-22 16:30:09 -0700163 posix.execve(fp, [sys.executable, '-c', 'pass'], os.environ)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200164 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200165 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200166 finally:
167 os.close(fp)
168
169 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
170 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
171 def test_waitid(self):
172 pid = os.fork()
173 if pid == 0:
174 os.chdir(os.path.split(sys.executable)[0])
175 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
176 else:
177 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
178 self.assertEqual(pid, res.si_pid)
179
180 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
181 def test_lockf(self):
182 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
183 try:
184 os.write(fd, b'test')
185 os.lseek(fd, 0, os.SEEK_SET)
186 posix.lockf(fd, posix.F_LOCK, 4)
187 # section is locked
188 posix.lockf(fd, posix.F_ULOCK, 4)
189 finally:
190 os.close(fd)
191
192 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
193 def test_pread(self):
194 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
195 try:
196 os.write(fd, b'test')
197 os.lseek(fd, 0, os.SEEK_SET)
198 self.assertEqual(b'es', posix.pread(fd, 2, 1))
Florent Xiclunae41f0de2011-11-11 19:39:25 +0100199 # the first pread() shouldn't disturb the file offset
Ross Lagerwall7807c352011-03-17 20:20:30 +0200200 self.assertEqual(b'te', posix.read(fd, 2))
201 finally:
202 os.close(fd)
203
204 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
205 def test_pwrite(self):
206 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
207 try:
208 os.write(fd, b'test')
209 os.lseek(fd, 0, os.SEEK_SET)
210 posix.pwrite(fd, b'xx', 1)
211 self.assertEqual(b'txxt', posix.read(fd, 4))
212 finally:
213 os.close(fd)
214
215 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
216 "test needs posix.posix_fallocate()")
217 def test_posix_fallocate(self):
218 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
219 try:
220 posix.posix_fallocate(fd, 0, 10)
221 except OSError as inst:
222 # issue10812, ZFS doesn't appear to support posix_fallocate,
223 # so skip Solaris-based since they are likely to have ZFS.
224 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
225 raise
226 finally:
227 os.close(fd)
228
229 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
230 "test needs posix.posix_fadvise()")
231 def test_posix_fadvise(self):
232 fd = os.open(support.TESTFN, os.O_RDONLY)
233 try:
234 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
235 finally:
236 os.close(fd)
237
Larry Hastings9cf065c2012-06-22 16:30:09 -0700238 @unittest.skipUnless(os.utime in os.supports_fd, "test needs fd support in os.utime")
239 def test_utime_with_fd(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200240 now = time.time()
241 fd = os.open(support.TESTFN, os.O_RDONLY)
242 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700243 posix.utime(fd)
244 posix.utime(fd, None)
245 self.assertRaises(TypeError, posix.utime, fd, (None, None))
246 self.assertRaises(TypeError, posix.utime, fd, (now, None))
247 self.assertRaises(TypeError, posix.utime, fd, (None, now))
248 posix.utime(fd, (int(now), int(now)))
249 posix.utime(fd, (now, now))
250 self.assertRaises(ValueError, posix.utime, fd, (now, now), ns=(now, now))
251 self.assertRaises(ValueError, posix.utime, fd, (now, 0), ns=(None, None))
252 self.assertRaises(ValueError, posix.utime, fd, (None, None), ns=(now, 0))
253 posix.utime(fd, (int(now), int((now - int(now)) * 1e9)))
254 posix.utime(fd, ns=(int(now), int((now - int(now)) * 1e9)))
255
Ross Lagerwall7807c352011-03-17 20:20:30 +0200256 finally:
257 os.close(fd)
258
Larry Hastings9cf065c2012-06-22 16:30:09 -0700259 @unittest.skipUnless(os.utime in os.supports_follow_symlinks, "test needs follow_symlinks support in os.utime")
260 def test_utime_nofollow_symlinks(self):
Ross Lagerwall7807c352011-03-17 20:20:30 +0200261 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700262 posix.utime(support.TESTFN, None, follow_symlinks=False)
263 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), follow_symlinks=False)
264 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), follow_symlinks=False)
265 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), follow_symlinks=False)
266 posix.utime(support.TESTFN, (int(now), int(now)), follow_symlinks=False)
267 posix.utime(support.TESTFN, (now, now), follow_symlinks=False)
268 posix.utime(support.TESTFN, follow_symlinks=False)
Ross Lagerwall7807c352011-03-17 20:20:30 +0200269
270 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
271 def test_writev(self):
272 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
273 try:
274 os.writev(fd, (b'test1', b'tt2', b't3'))
275 os.lseek(fd, 0, os.SEEK_SET)
276 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
277 finally:
278 os.close(fd)
279
280 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
281 def test_readv(self):
282 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
283 try:
284 os.write(fd, b'test1tt2t3')
285 os.lseek(fd, 0, os.SEEK_SET)
286 buf = [bytearray(i) for i in [5, 3, 2]]
287 self.assertEqual(posix.readv(fd, buf), 10)
288 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
289 finally:
290 os.close(fd)
291
Neal Norwitze241ce82003-02-17 18:17:05 +0000292 def test_dup(self):
293 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000294 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000295 try:
296 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000297 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000298 os.close(fd)
299 finally:
300 fp.close()
301
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000302 def test_confstr(self):
303 if hasattr(posix, 'confstr'):
304 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
305 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
306
Neal Norwitze241ce82003-02-17 18:17:05 +0000307 def test_dup2(self):
308 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000309 fp1 = open(support.TESTFN)
310 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000311 try:
312 posix.dup2(fp1.fileno(), fp2.fileno())
313 finally:
314 fp1.close()
315 fp2.close()
316
Charles-François Natali1e045b12011-05-22 20:42:32 +0200317 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200318 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200319 def test_oscloexec(self):
320 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
321 self.addCleanup(os.close, fd)
Victor Stinnere36f3752011-05-24 00:29:43 +0200322 self.assertTrue(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200323
Skip Montanaro98470002005-06-17 01:14:49 +0000324 def test_osexlock(self):
325 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000326 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000327 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000328 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000329 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
330 os.close(fd)
331
332 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000333 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000334 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000335 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000336 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
337 os.close(fd)
338
339 def test_osshlock(self):
340 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000341 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000342 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000343 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000344 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
345 os.close(fd2)
346 os.close(fd1)
347
348 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000349 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000350 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000351 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000352 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
353 os.close(fd)
354
Neal Norwitze241ce82003-02-17 18:17:05 +0000355 def test_fstat(self):
356 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000357 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000358 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000359 self.assertTrue(posix.fstat(fp.fileno()))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700360 self.assertTrue(posix.stat(fp.fileno()))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200361
362 self.assertRaisesRegex(TypeError,
363 'should be string, bytes or integer, not',
364 posix.stat, float(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000365 finally:
366 fp.close()
367
368 def test_stat(self):
369 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000370 self.assertTrue(posix.stat(support.TESTFN))
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200371 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
372 self.assertTrue(posix.stat(bytearray(os.fsencode(support.TESTFN))))
373
374 self.assertRaisesRegex(TypeError,
375 'can\'t specify None for path argument',
376 posix.stat, None)
377 self.assertRaisesRegex(TypeError,
378 'should be string, bytes or integer, not',
379 posix.stat, list(support.TESTFN))
380 self.assertRaisesRegex(TypeError,
381 'should be string, bytes or integer, not',
382 posix.stat, list(os.fsencode(support.TESTFN)))
Neal Norwitze241ce82003-02-17 18:17:05 +0000383
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000384 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
385 def test_mkfifo(self):
386 support.unlink(support.TESTFN)
387 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
388 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
389
390 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
391 "don't have mknod()/S_IFIFO")
392 def test_mknod(self):
393 # Test using mknod() to create a FIFO (the only use specified
394 # by POSIX).
395 support.unlink(support.TESTFN)
396 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
397 try:
398 posix.mknod(support.TESTFN, mode, 0)
399 except OSError as e:
400 # Some old systems don't allow unprivileged users to use
401 # mknod(), or only support creating device nodes.
402 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
403 else:
404 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
405
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000406 def _test_all_chown_common(self, chown_func, first_param):
407 """Common code for chown, fchown and lchown tests."""
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200408 # test a successful chown call
409 chown_func(first_param, os.getuid(), os.getgid())
410
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000411 if os.getuid() == 0:
412 try:
413 # Many linux distros have a nfsnobody user as MAX_UID-2
414 # that makes a good test case for signedness issues.
415 # http://bugs.python.org/issue1747858
416 # This part of the test only runs when run as root.
417 # Only scary people run their tests as root.
418 ent = pwd.getpwnam('nfsnobody')
419 chown_func(first_param, ent.pw_uid, ent.pw_gid)
420 except KeyError:
421 pass
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200422 elif platform.system() in ('HP-UX', 'SunOS'):
423 # HP-UX and Solaris can allow a non-root user to chown() to root
424 # (issue #5113)
425 raise unittest.SkipTest("Skipping because of non-standard chown() "
426 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000427 else:
428 # non-root cannot chown to root, raises OSError
429 self.assertRaises(OSError, chown_func,
430 first_param, 0, 0)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000431
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000432 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
433 def test_chown(self):
434 # raise an OSError if the file does not exist
435 os.unlink(support.TESTFN)
436 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000437
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000438 # re-create the file
Victor Stinnerbf816222011-06-30 23:25:47 +0200439 support.create_empty_file(support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000440 self._test_all_chown_common(posix.chown, support.TESTFN)
441
442 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
443 def test_fchown(self):
444 os.unlink(support.TESTFN)
445
446 # re-create the file
447 test_file = open(support.TESTFN, 'w')
448 try:
449 fd = test_file.fileno()
450 self._test_all_chown_common(posix.fchown, fd)
451 finally:
452 test_file.close()
453
454 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
455 def test_lchown(self):
456 os.unlink(support.TESTFN)
457 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700458 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000459 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000460
Neal Norwitze241ce82003-02-17 18:17:05 +0000461 def test_chdir(self):
462 if hasattr(posix, 'chdir'):
463 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000464 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000465
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000466 def test_listdir(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700467 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000468
469 def test_listdir_default(self):
Larry Hastingsfdaea062012-06-25 04:42:23 -0700470 # When listdir is called without argument,
471 # it's the same as listdir(os.curdir).
472 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000473
Larry Hastingsfdaea062012-06-25 04:42:23 -0700474 def test_listdir_bytes(self):
475 # When listdir is called with a bytes object,
476 # the returned strings are of type bytes.
477 self.assertTrue(os.fsencode(support.TESTFN) in posix.listdir(b'.'))
478
479 @unittest.skipUnless(posix.listdir in os.supports_fd,
480 "test needs fd support for posix.listdir()")
481 def test_listdir_fd(self):
Antoine Pitrou8250e232011-02-25 23:41:16 +0000482 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100483 self.addCleanup(posix.close, f)
Antoine Pitrou8250e232011-02-25 23:41:16 +0000484 self.assertEqual(
485 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700486 sorted(posix.listdir(f))
Antoine Pitrou8250e232011-02-25 23:41:16 +0000487 )
Charles-François Natali7546ad32012-01-08 18:34:06 +0100488 # Check that the fd offset was reset (issue #13739)
Charles-François Natali7546ad32012-01-08 18:34:06 +0100489 self.assertEqual(
490 sorted(posix.listdir('.')),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700491 sorted(posix.listdir(f))
Charles-François Natali7546ad32012-01-08 18:34:06 +0100492 )
Antoine Pitrou8250e232011-02-25 23:41:16 +0000493
Neal Norwitze241ce82003-02-17 18:17:05 +0000494 def test_access(self):
495 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000496 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000497
498 def test_umask(self):
499 if hasattr(posix, 'umask'):
500 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000501 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000502 posix.umask(old_mask)
503
504 def test_strerror(self):
505 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000506 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000507
508 def test_pipe(self):
509 if hasattr(posix, 'pipe'):
510 reader, writer = posix.pipe()
511 os.close(reader)
512 os.close(writer)
513
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200514 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200515 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200516 def test_pipe2(self):
517 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
518 self.assertRaises(TypeError, os.pipe2, 0, 0)
519
Charles-François Natali368f34b2011-06-06 19:49:47 +0200520 # try calling with flags = 0, like os.pipe()
521 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200522 os.close(r)
523 os.close(w)
524
525 # test flags
526 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
527 self.addCleanup(os.close, r)
528 self.addCleanup(os.close, w)
529 self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
530 self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
531 # try reading from an empty pipe: this should fail, not block
532 self.assertRaises(OSError, os.read, r, 1)
533 # try a write big enough to fill-up the pipe: this should either
534 # fail or perform a partial write, not block
535 try:
536 os.write(w, b'x' * support.PIPE_MAX_SIZE)
537 except OSError:
538 pass
539
Neal Norwitze241ce82003-02-17 18:17:05 +0000540 def test_utime(self):
541 if hasattr(posix, 'utime'):
542 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000543 posix.utime(support.TESTFN, None)
544 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
545 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
546 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
547 posix.utime(support.TESTFN, (int(now), int(now)))
548 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000549
Larry Hastings9cf065c2012-06-22 16:30:09 -0700550 def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
Ned Deily3eb67d52011-06-28 00:00:28 -0700551 st = os.stat(target_file)
552 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelson75959cf2012-08-21 23:59:31 +0000553
554 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
555 flags = st.st_flags | stat.UF_IMMUTABLE
556 try:
557 chflags_func(target_file, flags, **kwargs)
558 except OSError as err:
559 if err.errno != errno.EOPNOTSUPP:
560 raise
561 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
562 self.skipTest(msg)
563
Ned Deily3eb67d52011-06-28 00:00:28 -0700564 try:
565 new_st = os.stat(target_file)
566 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
567 try:
568 fd = open(target_file, 'w+')
569 except IOError as e:
570 self.assertEqual(e.errno, errno.EPERM)
571 finally:
572 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000573
Ned Deily3eb67d52011-06-28 00:00:28 -0700574 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
575 def test_chflags(self):
576 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
577
578 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
579 def test_lchflags_regular_file(self):
580 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700581 self._test_chflags_regular_file(posix.chflags, support.TESTFN, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700582
583 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
584 def test_lchflags_symlink(self):
585 testfn_st = os.stat(support.TESTFN)
586
587 self.assertTrue(hasattr(testfn_st, 'st_flags'))
588
589 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
590 self.teardown_files.append(_DUMMY_SYMLINK)
591 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
592
Larry Hastings9cf065c2012-06-22 16:30:09 -0700593 def chflags_nofollow(path, flags):
594 return posix.chflags(path, flags, follow_symlinks=False)
Ned Deily3eb67d52011-06-28 00:00:28 -0700595
Larry Hastings9cf065c2012-06-22 16:30:09 -0700596 for fn in (posix.lchflags, chflags_nofollow):
Trent Nelson75959cf2012-08-21 23:59:31 +0000597 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
598 flags = dummy_symlink_st.st_flags | stat.UF_IMMUTABLE
599 try:
600 fn(_DUMMY_SYMLINK, flags)
601 except OSError as err:
602 if err.errno != errno.EOPNOTSUPP:
603 raise
604 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
605 self.skipTest(msg)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700606 try:
607 new_testfn_st = os.stat(support.TESTFN)
608 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
609
610 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
611 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
612 new_dummy_symlink_st.st_flags)
613 finally:
614 fn(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000615
Guido van Rossum98297ee2007-11-06 21:34:58 +0000616 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000617 if os.name == "nt":
618 item_type = str
619 else:
620 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000621 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000622 self.assertEqual(type(k), item_type)
623 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000624
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000625 def test_getcwd_long_pathnames(self):
626 if hasattr(posix, 'getcwd'):
627 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
628 curdir = os.getcwd()
629 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
630
631 try:
632 os.mkdir(base_path)
633 os.chdir(base_path)
634 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000635# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000636# because the test results in Error in that case.
637# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000638# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000639 return
640
641 def _create_and_do_getcwd(dirname, current_path_length = 0):
642 try:
643 os.mkdir(dirname)
644 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000645 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000646
647 os.chdir(dirname)
648 try:
649 os.getcwd()
650 if current_path_length < 1027:
651 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
652 finally:
653 os.chdir('..')
654 os.rmdir(dirname)
655
656 _create_and_do_getcwd(dirname)
657
658 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000659 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000660 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000661
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200662 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
663 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
664 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
665 def test_getgrouplist(self):
Ross Lagerwalla0b315f2012-12-13 15:20:26 +0000666 user = pwd.getpwuid(os.getuid())[0]
667 group = pwd.getpwuid(os.getuid())[3]
668 self.assertIn(group, posix.getgrouplist(user, group))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200669
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200670
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000671 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000672 def test_getgroups(self):
673 with os.popen('id -G') as idg:
674 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200675 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000676
Benjamin Petersonb29614e2012-10-09 11:16:03 -0400677 if ret is not None or not groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000678 raise unittest.SkipTest("need working 'id -G'")
679
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000680 # 'id -G' and 'os.getgroups()' should return the same
681 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000682 # #10822 - it is implementation defined whether posix.getgroups()
683 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000684 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000685 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000686 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000687
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000688 # tests for the posix *at functions follow
689
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()")
691 def test_access_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000692 f = posix.open(posix.getcwd(), posix.O_RDONLY)
693 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700694 self.assertTrue(posix.access(support.TESTFN, os.R_OK, dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000695 finally:
696 posix.close(f)
697
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()")
699 def test_chmod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000700 os.chmod(support.TESTFN, stat.S_IRUSR)
701
702 f = posix.open(posix.getcwd(), posix.O_RDONLY)
703 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700704 posix.chmod(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000705
706 s = posix.stat(support.TESTFN)
707 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
708 finally:
709 posix.close(f)
710
Larry Hastings9cf065c2012-06-22 16:30:09 -0700711 @unittest.skipUnless(os.chown in os.supports_dir_fd, "test needs dir_fd support in os.chown()")
712 def test_chown_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000713 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200714 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000715
716 f = posix.open(posix.getcwd(), posix.O_RDONLY)
717 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700718 posix.chown(support.TESTFN, os.getuid(), os.getgid(), dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000719 finally:
720 posix.close(f)
721
Larry Hastings9cf065c2012-06-22 16:30:09 -0700722 @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()")
723 def test_stat_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000724 support.unlink(support.TESTFN)
725 with open(support.TESTFN, 'w') as outfile:
726 outfile.write("testline\n")
727
728 f = posix.open(posix.getcwd(), posix.O_RDONLY)
729 try:
730 s1 = posix.stat(support.TESTFN)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700731 s2 = posix.stat(support.TESTFN, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000732 self.assertEqual(s1, s2)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200733 s2 = posix.stat(support.TESTFN, dir_fd=None)
734 self.assertEqual(s1, s2)
735 self.assertRaisesRegex(TypeError, 'should be integer, not',
736 posix.stat, support.TESTFN, dir_fd=posix.getcwd())
737 self.assertRaisesRegex(TypeError, 'should be integer, not',
738 posix.stat, support.TESTFN, dir_fd=float(f))
739 self.assertRaises(OverflowError,
740 posix.stat, support.TESTFN, dir_fd=10**20)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000741 finally:
742 posix.close(f)
743
Larry Hastings9cf065c2012-06-22 16:30:09 -0700744 @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
745 def test_utime_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000746 f = posix.open(posix.getcwd(), posix.O_RDONLY)
747 try:
748 now = time.time()
Larry Hastings9cf065c2012-06-22 16:30:09 -0700749 posix.utime(support.TESTFN, None, dir_fd=f)
750 posix.utime(support.TESTFN, dir_fd=f)
751 self.assertRaises(TypeError, posix.utime, support.TESTFN, now, dir_fd=f)
752 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None), dir_fd=f)
753 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None), dir_fd=f)
754 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now), dir_fd=f)
755 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, "x"), dir_fd=f)
756 posix.utime(support.TESTFN, (int(now), int(now)), dir_fd=f)
757 posix.utime(support.TESTFN, (now, now), dir_fd=f)
758 posix.utime(support.TESTFN,
759 (int(now), int((now - int(now)) * 1e9)), dir_fd=f)
760 posix.utime(support.TESTFN, dir_fd=f,
761 times=(int(now), int((now - int(now)) * 1e9)))
762
Larry Hastings90867a52012-06-22 17:01:41 -0700763 # try dir_fd and follow_symlinks together
Larry Hastings9cf065c2012-06-22 16:30:09 -0700764 if os.utime in os.supports_follow_symlinks:
Larry Hastings90867a52012-06-22 17:01:41 -0700765 try:
766 posix.utime(support.TESTFN, follow_symlinks=False, dir_fd=f)
Georg Brandl969288e2012-06-26 09:25:44 +0200767 except ValueError:
Larry Hastings90867a52012-06-22 17:01:41 -0700768 # whoops! using both together not supported on this platform.
769 pass
Larry Hastings9cf065c2012-06-22 16:30:09 -0700770
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000771 finally:
772 posix.close(f)
773
Larry Hastings9cf065c2012-06-22 16:30:09 -0700774 @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()")
775 def test_link_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000776 f = posix.open(posix.getcwd(), posix.O_RDONLY)
777 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700778 posix.link(support.TESTFN, support.TESTFN + 'link', src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000779 # should have same inodes
780 self.assertEqual(posix.stat(support.TESTFN)[1],
781 posix.stat(support.TESTFN + 'link')[1])
782 finally:
783 posix.close(f)
784 support.unlink(support.TESTFN + 'link')
785
Larry Hastings9cf065c2012-06-22 16:30:09 -0700786 @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()")
787 def test_mkdir_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000788 f = posix.open(posix.getcwd(), posix.O_RDONLY)
789 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700790 posix.mkdir(support.TESTFN + 'dir', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000791 posix.stat(support.TESTFN + 'dir') # should not raise exception
792 finally:
793 posix.close(f)
794 support.rmtree(support.TESTFN + 'dir')
795
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'),
797 "test requires both stat.S_IFIFO and dir_fd support for os.mknod()")
798 def test_mknod_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000799 # Test using mknodat() to create a FIFO (the only use specified
800 # by POSIX).
801 support.unlink(support.TESTFN)
802 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
803 f = posix.open(posix.getcwd(), posix.O_RDONLY)
804 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700805 posix.mknod(support.TESTFN, mode, 0, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000806 except OSError as e:
807 # Some old systems don't allow unprivileged users to use
808 # mknod(), or only support creating device nodes.
809 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
810 else:
811 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
812 finally:
813 posix.close(f)
814
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815 @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()")
816 def test_open_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000817 support.unlink(support.TESTFN)
818 with open(support.TESTFN, 'w') as outfile:
819 outfile.write("testline\n")
820 a = posix.open(posix.getcwd(), posix.O_RDONLY)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700821 b = posix.open(support.TESTFN, posix.O_RDONLY, dir_fd=a)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000822 try:
823 res = posix.read(b, 9).decode(encoding="utf-8")
824 self.assertEqual("testline\n", res)
825 finally:
826 posix.close(a)
827 posix.close(b)
828
Larry Hastings9cf065c2012-06-22 16:30:09 -0700829 @unittest.skipUnless(os.readlink in os.supports_dir_fd, "test needs dir_fd support in os.readlink()")
830 def test_readlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000831 os.symlink(support.TESTFN, support.TESTFN + 'link')
832 f = posix.open(posix.getcwd(), posix.O_RDONLY)
833 try:
834 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
Larry Hastings9cf065c2012-06-22 16:30:09 -0700835 posix.readlink(support.TESTFN + 'link', dir_fd=f))
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000836 finally:
837 support.unlink(support.TESTFN + 'link')
838 posix.close(f)
839
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840 @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()")
841 def test_rename_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000842 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200843 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000844 f = posix.open(posix.getcwd(), posix.O_RDONLY)
845 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700846 posix.rename(support.TESTFN + 'ren', support.TESTFN, src_dir_fd=f, dst_dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000847 except:
848 posix.rename(support.TESTFN + 'ren', support.TESTFN)
849 raise
850 else:
Andrew Svetlov5b898402012-12-18 21:26:36 +0200851 posix.stat(support.TESTFN) # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000852 finally:
853 posix.close(f)
854
Larry Hastings9cf065c2012-06-22 16:30:09 -0700855 @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()")
856 def test_symlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000857 f = posix.open(posix.getcwd(), posix.O_RDONLY)
858 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859 posix.symlink(support.TESTFN, support.TESTFN + 'link', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000860 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
861 finally:
862 posix.close(f)
863 support.unlink(support.TESTFN + 'link')
864
Larry Hastings9cf065c2012-06-22 16:30:09 -0700865 @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()")
866 def test_unlink_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000867 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +0200868 support.create_empty_file(support.TESTFN + 'del')
Andrew Svetlov5b898402012-12-18 21:26:36 +0200869 posix.stat(support.TESTFN + 'del') # should not raise exception
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000870 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 posix.unlink(support.TESTFN + 'del', dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000872 except:
873 support.unlink(support.TESTFN + 'del')
874 raise
875 else:
876 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
877 finally:
878 posix.close(f)
879
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()")
881 def test_mkfifo_dir_fd(self):
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000882 support.unlink(support.TESTFN)
883 f = posix.open(posix.getcwd(), posix.O_RDONLY)
884 try:
Larry Hastings9cf065c2012-06-22 16:30:09 -0700885 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000886 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
887 finally:
888 posix.close(f)
889
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500890 requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'),
891 "don't have scheduling support")
Antoine Pitrou84869872012-08-04 16:16:35 +0200892 requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'),
Benjamin Peterson50ba2712011-08-02 22:15:40 -0500893 "don't have sched affinity support")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500894
895 @requires_sched_h
896 def test_sched_yield(self):
897 # This has no error conditions (at least on Linux).
898 posix.sched_yield()
899
900 @requires_sched_h
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +0200901 @unittest.skipUnless(hasattr(posix, 'sched_get_priority_max'),
902 "requires sched_get_priority_max()")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500903 def test_sched_priority(self):
904 # Round-robin usually has interesting priorities.
905 pol = posix.SCHED_RR
906 lo = posix.sched_get_priority_min(pol)
907 hi = posix.sched_get_priority_max(pol)
908 self.assertIsInstance(lo, int)
909 self.assertIsInstance(hi, int)
910 self.assertGreaterEqual(hi, lo)
Benjamin Peterson539b6c42011-08-02 22:09:37 -0500911 # OSX evidently just returns 15 without checking the argument.
912 if sys.platform != "darwin":
Benjamin Petersonc1581582011-08-02 22:10:55 -0500913 self.assertRaises(OSError, posix.sched_get_priority_min, -23)
914 self.assertRaises(OSError, posix.sched_get_priority_max, -23)
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500915
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -0500916 @unittest.skipUnless(hasattr(posix, 'sched_setscheduler'), "can't change scheduler")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500917 def test_get_and_set_scheduler_and_param(self):
918 possible_schedulers = [sched for name, sched in posix.__dict__.items()
919 if name.startswith("SCHED_")]
920 mine = posix.sched_getscheduler(0)
921 self.assertIn(mine, possible_schedulers)
922 try:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200923 parent = posix.sched_getscheduler(os.getppid())
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500924 except OSError as e:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200925 if e.errno != errno.EPERM:
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500926 raise
927 else:
Jesus Ceaceb5d162011-09-10 01:16:55 +0200928 self.assertIn(parent, possible_schedulers)
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500929 self.assertRaises(OSError, posix.sched_getscheduler, -1)
930 self.assertRaises(OSError, posix.sched_getparam, -1)
931 param = posix.sched_getparam(0)
932 self.assertIsInstance(param.sched_priority, int)
Charles-François Natali7b911cb2011-08-21 12:41:43 +0200933
Charles-François Natalic78de462013-01-13 14:10:37 +0100934 # POSIX states that calling sched_setparam() or sched_setscheduler() on
935 # a process with a scheduling policy other than SCHED_FIFO or SCHED_RR
936 # is implementation-defined: NetBSD and FreeBSD can return EINVAL.
937 if not sys.platform.startswith(('freebsd', 'netbsd')):
938 try:
939 posix.sched_setscheduler(0, mine, param)
940 posix.sched_setparam(0, param)
941 except OSError as e:
942 if e.errno != errno.EPERM:
943 raise
Charles-François Natali7b911cb2011-08-21 12:41:43 +0200944 self.assertRaises(OSError, posix.sched_setparam, -1, param)
945
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500946 self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
947 self.assertRaises(TypeError, posix.sched_setscheduler, 0, mine, None)
948 self.assertRaises(TypeError, posix.sched_setparam, 0, 43)
949 param = posix.sched_param(None)
950 self.assertRaises(TypeError, posix.sched_setparam, 0, param)
951 large = 214748364700
952 param = posix.sched_param(large)
953 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
954 param = posix.sched_param(sched_priority=-large)
955 self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
956
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -0500957 @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500958 def test_sched_rr_get_interval(self):
Benjamin Peterson43234ab2011-08-02 22:19:14 -0500959 try:
960 interval = posix.sched_rr_get_interval(0)
961 except OSError as e:
962 # This likely means that sched_rr_get_interval is only valid for
963 # processes with the SCHED_RR scheduler in effect.
964 if e.errno != errno.EINVAL:
965 raise
966 self.skipTest("only works on SCHED_RR processes")
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500967 self.assertIsInstance(interval, float)
968 # Reasonable constraints, I think.
969 self.assertGreaterEqual(interval, 0.)
970 self.assertLess(interval, 1.)
971
Benjamin Peterson2740af82011-08-02 17:41:34 -0500972 @requires_sched_affinity
Antoine Pitrou84869872012-08-04 16:16:35 +0200973 def test_sched_getaffinity(self):
974 mask = posix.sched_getaffinity(0)
975 self.assertIsInstance(mask, set)
976 self.assertGreaterEqual(len(mask), 1)
977 self.assertRaises(OSError, posix.sched_getaffinity, -1)
978 for cpu in mask:
979 self.assertIsInstance(cpu, int)
980 self.assertGreaterEqual(cpu, 0)
981 self.assertLess(cpu, 1 << 32)
982
983 @requires_sched_affinity
984 def test_sched_setaffinity(self):
985 mask = posix.sched_getaffinity(0)
986 if len(mask) > 1:
987 # Empty masks are forbidden
988 mask.pop()
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500989 posix.sched_setaffinity(0, mask)
Antoine Pitrou84869872012-08-04 16:16:35 +0200990 self.assertEqual(posix.sched_getaffinity(0), mask)
991 self.assertRaises(OSError, posix.sched_setaffinity, 0, [])
992 self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10])
993 self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128])
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500994 self.assertRaises(OSError, posix.sched_setaffinity, -1, mask)
995
Victor Stinner8b905bd2011-10-25 13:34:04 +0200996 def test_rtld_constants(self):
997 # check presence of major RTLD_* constants
998 posix.RTLD_LAZY
999 posix.RTLD_NOW
1000 posix.RTLD_GLOBAL
1001 posix.RTLD_LOCAL
1002
Jesus Cea60c13dd2012-06-23 02:58:14 +02001003 @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'),
1004 "test needs an OS that reports file holes")
Hynek Schlawackf841e422012-06-24 09:51:46 +02001005 def test_fs_holes(self):
Jesus Cea94363612012-06-22 18:32:07 +02001006 # Even if the filesystem doesn't report holes,
1007 # if the OS supports it the SEEK_* constants
1008 # will be defined and will have a consistent
1009 # behaviour:
1010 # os.SEEK_DATA = current position
1011 # os.SEEK_HOLE = end of file position
Hynek Schlawackf841e422012-06-24 09:51:46 +02001012 with open(support.TESTFN, 'r+b') as fp:
Jesus Cea94363612012-06-22 18:32:07 +02001013 fp.write(b"hello")
1014 fp.flush()
1015 size = fp.tell()
1016 fno = fp.fileno()
Jesus Cead46f7d22012-07-07 14:56:04 +02001017 try :
1018 for i in range(size):
1019 self.assertEqual(i, os.lseek(fno, i, os.SEEK_DATA))
1020 self.assertLessEqual(size, os.lseek(fno, i, os.SEEK_HOLE))
1021 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_DATA)
1022 self.assertRaises(OSError, os.lseek, fno, size, os.SEEK_HOLE)
1023 except OSError :
1024 # Some OSs claim to support SEEK_HOLE/SEEK_DATA
1025 # but it is not true.
1026 # For instance:
1027 # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html
1028 raise unittest.SkipTest("OSError raised!")
Jesus Cea94363612012-06-22 18:32:07 +02001029
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001030class PosixGroupsTester(unittest.TestCase):
1031
1032 def setUp(self):
1033 if posix.getuid() != 0:
1034 raise unittest.SkipTest("not enough privileges")
1035 if not hasattr(posix, 'getgroups'):
1036 raise unittest.SkipTest("need posix.getgroups")
1037 if sys.platform == 'darwin':
1038 raise unittest.SkipTest("getgroups(2) is broken on OSX")
1039 self.saved_groups = posix.getgroups()
1040
1041 def tearDown(self):
1042 if hasattr(posix, 'setgroups'):
1043 posix.setgroups(self.saved_groups)
1044 elif hasattr(posix, 'initgroups'):
1045 name = pwd.getpwuid(posix.getuid()).pw_name
1046 posix.initgroups(name, self.saved_groups[0])
1047
1048 @unittest.skipUnless(hasattr(posix, 'initgroups'),
1049 "test needs posix.initgroups()")
1050 def test_initgroups(self):
1051 # find missing group
1052
Antoine Pitroue5a91012010-09-04 17:32:06 +00001053 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001054 name = pwd.getpwuid(posix.getuid()).pw_name
1055 posix.initgroups(name, g)
1056 self.assertIn(g, posix.getgroups())
1057
1058 @unittest.skipUnless(hasattr(posix, 'setgroups'),
1059 "test needs posix.setgroups()")
1060 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +00001061 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00001062 posix.setgroups(groups)
1063 self.assertListEqual(groups, posix.getgroups())
1064
Neal Norwitze241ce82003-02-17 18:17:05 +00001065def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +01001066 try:
1067 support.run_unittest(PosixTester, PosixGroupsTester)
1068 finally:
1069 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +00001070
1071if __name__ == '__main__':
1072 test_main()