blob: 79e2d367b968ecf14fcc34d688ea6862373439f3 [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
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000013import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000014import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000015import stat
Neal Norwitze241ce82003-02-17 18:17:05 +000016import unittest
17import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000018
Neal Norwitze241ce82003-02-17 18:17:05 +000019
20class PosixTester(unittest.TestCase):
21
22 def setUp(self):
23 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000024 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000025 fp.close()
Brett Cannonc8d502e2010-03-20 21:53:28 +000026 self._warnings_manager = support.check_warnings()
27 self._warnings_manager.__enter__()
28 warnings.filterwarnings('ignore', '.* potential security risk .*',
29 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000030
31 def tearDown(self):
Neal Norwitzc34177c2008-08-25 01:04:16 +000032 support.unlink(support.TESTFN)
Brett Cannonc8d502e2010-03-20 21:53:28 +000033 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def testNoArgFunctions(self):
36 # test posix functions which take no arguments and have
37 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000038 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000039 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000040 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020041 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000042 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000043
Neal Norwitze241ce82003-02-17 18:17:05 +000044 for name in NO_ARG_FUNCTIONS:
45 posix_func = getattr(posix, name, None)
46 if posix_func is not None:
47 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000048 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000049
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000050 if hasattr(posix, 'getresuid'):
51 def test_getresuid(self):
52 user_ids = posix.getresuid()
53 self.assertEqual(len(user_ids), 3)
54 for val in user_ids:
55 self.assertGreaterEqual(val, 0)
56
57 if hasattr(posix, 'getresgid'):
58 def test_getresgid(self):
59 group_ids = posix.getresgid()
60 self.assertEqual(len(group_ids), 3)
61 for val in group_ids:
62 self.assertGreaterEqual(val, 0)
63
64 if hasattr(posix, 'setresuid'):
65 def test_setresuid(self):
66 current_user_ids = posix.getresuid()
67 self.assertIsNone(posix.setresuid(*current_user_ids))
68 # -1 means don't change that value.
69 self.assertIsNone(posix.setresuid(-1, -1, -1))
70
71 def test_setresuid_exception(self):
72 # Don't do this test if someone is silly enough to run us as root.
73 current_user_ids = posix.getresuid()
74 if 0 not in current_user_ids:
75 new_user_ids = (current_user_ids[0]+1, -1, -1)
76 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
77
78 if hasattr(posix, 'setresgid'):
79 def test_setresgid(self):
80 current_group_ids = posix.getresgid()
81 self.assertIsNone(posix.setresgid(*current_group_ids))
82 # -1 means don't change that value.
83 self.assertIsNone(posix.setresgid(-1, -1, -1))
84
85 def test_setresgid_exception(self):
86 # Don't do this test if someone is silly enough to run us as root.
87 current_group_ids = posix.getresgid()
88 if 0 not in current_group_ids:
89 new_group_ids = (current_group_ids[0]+1, -1, -1)
90 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
91
Antoine Pitroub7572f02009-12-02 20:46:48 +000092 @unittest.skipUnless(hasattr(posix, 'initgroups'),
93 "test needs os.initgroups()")
94 def test_initgroups(self):
95 # It takes a string and an integer; check that it raises a TypeError
96 # for other argument lists.
97 self.assertRaises(TypeError, posix.initgroups)
98 self.assertRaises(TypeError, posix.initgroups, None)
99 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
100 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
101
102 # If a non-privileged user invokes it, it should fail with OSError
103 # EPERM.
104 if os.getuid() != 0:
105 name = pwd.getpwuid(posix.getuid()).pw_name
106 try:
107 posix.initgroups(name, 13)
108 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000109 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000110 else:
111 self.fail("Expected OSError to be raised by initgroups")
112
Neal Norwitze241ce82003-02-17 18:17:05 +0000113 def test_statvfs(self):
114 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000115 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000116
117 def test_fstatvfs(self):
118 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000119 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000120 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000122 finally:
123 fp.close()
124
125 def test_ftruncate(self):
126 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000127 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000128 try:
129 # we need to have some data to truncate
130 fp.write('test')
131 fp.flush()
132 posix.ftruncate(fp.fileno(), 0)
133 finally:
134 fp.close()
135
Ross Lagerwall7807c352011-03-17 20:20:30 +0200136 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
137 def test_truncate(self):
138 with open(support.TESTFN, 'w') as fp:
139 fp.write('test')
140 fp.flush()
141 posix.truncate(support.TESTFN, 0)
142
143 @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
144 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200145 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200146 def test_fexecve(self):
147 fp = os.open(sys.executable, os.O_RDONLY)
148 try:
149 pid = os.fork()
150 if pid == 0:
151 os.chdir(os.path.split(sys.executable)[0])
152 posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
153 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200154 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200155 finally:
156 os.close(fp)
157
158 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
159 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
160 def test_waitid(self):
161 pid = os.fork()
162 if pid == 0:
163 os.chdir(os.path.split(sys.executable)[0])
164 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
165 else:
166 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
167 self.assertEqual(pid, res.si_pid)
168
169 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
170 def test_lockf(self):
171 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
172 try:
173 os.write(fd, b'test')
174 os.lseek(fd, 0, os.SEEK_SET)
175 posix.lockf(fd, posix.F_LOCK, 4)
176 # section is locked
177 posix.lockf(fd, posix.F_ULOCK, 4)
178 finally:
179 os.close(fd)
180
181 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
182 def test_pread(self):
183 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
184 try:
185 os.write(fd, b'test')
186 os.lseek(fd, 0, os.SEEK_SET)
187 self.assertEqual(b'es', posix.pread(fd, 2, 1))
188 # the first pread() shoudn't disturb the file offset
189 self.assertEqual(b'te', posix.read(fd, 2))
190 finally:
191 os.close(fd)
192
193 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
194 def test_pwrite(self):
195 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
196 try:
197 os.write(fd, b'test')
198 os.lseek(fd, 0, os.SEEK_SET)
199 posix.pwrite(fd, b'xx', 1)
200 self.assertEqual(b'txxt', posix.read(fd, 4))
201 finally:
202 os.close(fd)
203
204 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
205 "test needs posix.posix_fallocate()")
206 def test_posix_fallocate(self):
207 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
208 try:
209 posix.posix_fallocate(fd, 0, 10)
210 except OSError as inst:
211 # issue10812, ZFS doesn't appear to support posix_fallocate,
212 # so skip Solaris-based since they are likely to have ZFS.
213 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
214 raise
215 finally:
216 os.close(fd)
217
218 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
219 "test needs posix.posix_fadvise()")
220 def test_posix_fadvise(self):
221 fd = os.open(support.TESTFN, os.O_RDONLY)
222 try:
223 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
224 finally:
225 os.close(fd)
226
227 @unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
228 def test_futimes(self):
229 now = time.time()
230 fd = os.open(support.TESTFN, os.O_RDONLY)
231 try:
232 posix.futimes(fd, None)
233 self.assertRaises(TypeError, posix.futimes, fd, (None, None))
234 self.assertRaises(TypeError, posix.futimes, fd, (now, None))
235 self.assertRaises(TypeError, posix.futimes, fd, (None, now))
236 posix.futimes(fd, (int(now), int(now)))
237 posix.futimes(fd, (now, now))
238 finally:
239 os.close(fd)
240
241 @unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
242 def test_lutimes(self):
243 now = time.time()
244 posix.lutimes(support.TESTFN, None)
245 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
246 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
247 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
248 posix.lutimes(support.TESTFN, (int(now), int(now)))
249 posix.lutimes(support.TESTFN, (now, now))
250
251 @unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
252 def test_futimens(self):
253 now = time.time()
254 fd = os.open(support.TESTFN, os.O_RDONLY)
255 try:
256 self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
257 self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
258 self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
259 posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
260 (int(now), int((now - int(now)) * 1e9)))
261 finally:
262 os.close(fd)
263
264 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
265 def test_writev(self):
266 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
267 try:
268 os.writev(fd, (b'test1', b'tt2', b't3'))
269 os.lseek(fd, 0, os.SEEK_SET)
270 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
271 finally:
272 os.close(fd)
273
274 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
275 def test_readv(self):
276 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
277 try:
278 os.write(fd, b'test1tt2t3')
279 os.lseek(fd, 0, os.SEEK_SET)
280 buf = [bytearray(i) for i in [5, 3, 2]]
281 self.assertEqual(posix.readv(fd, buf), 10)
282 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
283 finally:
284 os.close(fd)
285
Neal Norwitze241ce82003-02-17 18:17:05 +0000286 def test_dup(self):
287 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000288 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000289 try:
290 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000291 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000292 os.close(fd)
293 finally:
294 fp.close()
295
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000296 def test_confstr(self):
297 if hasattr(posix, 'confstr'):
298 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
299 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
300
Neal Norwitze241ce82003-02-17 18:17:05 +0000301 def test_dup2(self):
302 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000303 fp1 = open(support.TESTFN)
304 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000305 try:
306 posix.dup2(fp1.fileno(), fp2.fileno())
307 finally:
308 fp1.close()
309 fp2.close()
310
Charles-François Natali1e045b12011-05-22 20:42:32 +0200311 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
312 def test_oscloexec(self):
Victor Stinnere36f3752011-05-24 00:29:43 +0200313 version = support.linux_version()
314 if sys.platform == 'linux2' and version < (2, 6, 23):
315 self.skipTest("Linux kernel 2.6.23 or higher required, "
316 "not %s.%s.%s" % version)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200317 fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC)
318 self.addCleanup(os.close, fd)
Victor Stinnere36f3752011-05-24 00:29:43 +0200319 self.assertTrue(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200320
Skip Montanaro98470002005-06-17 01:14:49 +0000321 def test_osexlock(self):
322 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000323 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000324 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000325 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000326 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
327 os.close(fd)
328
329 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000330 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000331 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000332 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000333 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
334 os.close(fd)
335
336 def test_osshlock(self):
337 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000338 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000339 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000340 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000341 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
342 os.close(fd2)
343 os.close(fd1)
344
345 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000346 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000347 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000348 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000349 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
350 os.close(fd)
351
Neal Norwitze241ce82003-02-17 18:17:05 +0000352 def test_fstat(self):
353 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000354 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000355 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000356 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000357 finally:
358 fp.close()
359
360 def test_stat(self):
361 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000362 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000363
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000364 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
365 def test_mkfifo(self):
366 support.unlink(support.TESTFN)
367 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
368 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
369
370 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
371 "don't have mknod()/S_IFIFO")
372 def test_mknod(self):
373 # Test using mknod() to create a FIFO (the only use specified
374 # by POSIX).
375 support.unlink(support.TESTFN)
376 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
377 try:
378 posix.mknod(support.TESTFN, mode, 0)
379 except OSError as e:
380 # Some old systems don't allow unprivileged users to use
381 # mknod(), or only support creating device nodes.
382 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
383 else:
384 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
385
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000386 def _test_all_chown_common(self, chown_func, first_param):
387 """Common code for chown, fchown and lchown tests."""
388 if os.getuid() == 0:
389 try:
390 # Many linux distros have a nfsnobody user as MAX_UID-2
391 # that makes a good test case for signedness issues.
392 # http://bugs.python.org/issue1747858
393 # This part of the test only runs when run as root.
394 # Only scary people run their tests as root.
395 ent = pwd.getpwnam('nfsnobody')
396 chown_func(first_param, ent.pw_uid, ent.pw_gid)
397 except KeyError:
398 pass
399 else:
400 # non-root cannot chown to root, raises OSError
401 self.assertRaises(OSError, chown_func,
402 first_param, 0, 0)
403 # test a successful chown call
404 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000405
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000406 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
407 def test_chown(self):
408 # raise an OSError if the file does not exist
409 os.unlink(support.TESTFN)
410 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000411
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000412 # re-create the file
413 open(support.TESTFN, 'w').close()
414 self._test_all_chown_common(posix.chown, support.TESTFN)
415
416 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
417 def test_fchown(self):
418 os.unlink(support.TESTFN)
419
420 # re-create the file
421 test_file = open(support.TESTFN, 'w')
422 try:
423 fd = test_file.fileno()
424 self._test_all_chown_common(posix.fchown, fd)
425 finally:
426 test_file.close()
427
428 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
429 def test_lchown(self):
430 os.unlink(support.TESTFN)
431 # create a symlink
432 os.symlink('/tmp/dummy-symlink-target', support.TESTFN)
433 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000434
Neal Norwitze241ce82003-02-17 18:17:05 +0000435 def test_chdir(self):
436 if hasattr(posix, 'chdir'):
437 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000438 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000439
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000440 def test_listdir(self):
441 if hasattr(posix, 'listdir'):
442 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
443
444 def test_listdir_default(self):
445 # When listdir is called without argument, it's the same as listdir(os.curdir)
446 if hasattr(posix, 'listdir'):
447 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000448
Antoine Pitrou8250e232011-02-25 23:41:16 +0000449 @unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
450 def test_fdlistdir(self):
451 f = posix.open(posix.getcwd(), posix.O_RDONLY)
452 self.assertEqual(
453 sorted(posix.listdir('.')),
454 sorted(posix.fdlistdir(f))
455 )
456 # Check the fd was closed by fdlistdir
457 with self.assertRaises(OSError) as ctx:
458 posix.close(f)
459 self.assertEqual(ctx.exception.errno, errno.EBADF)
460
Neal Norwitze241ce82003-02-17 18:17:05 +0000461 def test_access(self):
462 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000463 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000464
465 def test_umask(self):
466 if hasattr(posix, 'umask'):
467 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000468 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000469 posix.umask(old_mask)
470
471 def test_strerror(self):
472 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000473 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000474
475 def test_pipe(self):
476 if hasattr(posix, 'pipe'):
477 reader, writer = posix.pipe()
478 os.close(reader)
479 os.close(writer)
480
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200481 @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()")
482 def test_pipe2(self):
Charles-François Natalid92ccb12011-05-29 20:46:27 +0200483 version = support.linux_version()
484 if sys.platform == 'linux2' and version < (2, 6, 27):
485 self.skipTest("Linux kernel 2.6.27 or higher required, "
486 "not %s.%s.%s" % version)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200487 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
488 self.assertRaises(TypeError, os.pipe2, 0, 0)
489
490 # try calling without flag, like os.pipe()
491 r, w = os.pipe2()
492 os.close(r)
493 os.close(w)
494
495 # test flags
496 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
497 self.addCleanup(os.close, r)
498 self.addCleanup(os.close, w)
499 self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
500 self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
501 # try reading from an empty pipe: this should fail, not block
502 self.assertRaises(OSError, os.read, r, 1)
503 # try a write big enough to fill-up the pipe: this should either
504 # fail or perform a partial write, not block
505 try:
506 os.write(w, b'x' * support.PIPE_MAX_SIZE)
507 except OSError:
508 pass
509
Neal Norwitze241ce82003-02-17 18:17:05 +0000510 def test_utime(self):
511 if hasattr(posix, 'utime'):
512 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000513 posix.utime(support.TESTFN, None)
514 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
515 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
516 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
517 posix.utime(support.TESTFN, (int(now), int(now)))
518 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000519
Thomas Wouterscf297e42007-02-23 15:07:44 +0000520 def test_chflags(self):
521 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000522 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000523 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000524 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000525
526 def test_lchflags(self):
527 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000528 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000529 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000530 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000531
Guido van Rossum98297ee2007-11-06 21:34:58 +0000532 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000533 if os.name == "nt":
534 item_type = str
535 else:
536 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000537 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000538 self.assertEqual(type(k), item_type)
539 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000540
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000541 def test_getcwd_long_pathnames(self):
542 if hasattr(posix, 'getcwd'):
543 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
544 curdir = os.getcwd()
545 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
546
547 try:
548 os.mkdir(base_path)
549 os.chdir(base_path)
550 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000551# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000552# because the test results in Error in that case.
553# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000554# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000555 return
556
557 def _create_and_do_getcwd(dirname, current_path_length = 0):
558 try:
559 os.mkdir(dirname)
560 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000561 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000562
563 os.chdir(dirname)
564 try:
565 os.getcwd()
566 if current_path_length < 1027:
567 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
568 finally:
569 os.chdir('..')
570 os.rmdir(dirname)
571
572 _create_and_do_getcwd(dirname)
573
574 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000575 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000576 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000577
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000578 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000579 def test_getgroups(self):
580 with os.popen('id -G') as idg:
581 groups = idg.read().strip()
582
583 if not groups:
584 raise unittest.SkipTest("need working 'id -G'")
585
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000586 # 'id -G' and 'os.getgroups()' should return the same
587 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000588 # #10822 - it is implementation defined whether posix.getgroups()
589 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000590 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000591 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000592 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000593
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000594 # tests for the posix *at functions follow
595
596 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
597 def test_faccessat(self):
598 f = posix.open(posix.getcwd(), posix.O_RDONLY)
599 try:
600 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
601 finally:
602 posix.close(f)
603
604 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
605 def test_fchmodat(self):
606 os.chmod(support.TESTFN, stat.S_IRUSR)
607
608 f = posix.open(posix.getcwd(), posix.O_RDONLY)
609 try:
610 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
611
612 s = posix.stat(support.TESTFN)
613 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
614 finally:
615 posix.close(f)
616
617 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
618 def test_fchownat(self):
619 support.unlink(support.TESTFN)
620 open(support.TESTFN, 'w').close()
621
622 f = posix.open(posix.getcwd(), posix.O_RDONLY)
623 try:
624 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
625 finally:
626 posix.close(f)
627
628 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
629 def test_fstatat(self):
630 support.unlink(support.TESTFN)
631 with open(support.TESTFN, 'w') as outfile:
632 outfile.write("testline\n")
633
634 f = posix.open(posix.getcwd(), posix.O_RDONLY)
635 try:
636 s1 = posix.stat(support.TESTFN)
637 s2 = posix.fstatat(f, support.TESTFN)
638 self.assertEqual(s1, s2)
639 finally:
640 posix.close(f)
641
642 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
643 def test_futimesat(self):
644 f = posix.open(posix.getcwd(), posix.O_RDONLY)
645 try:
646 now = time.time()
647 posix.futimesat(f, support.TESTFN, None)
648 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
649 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
650 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
651 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
652 posix.futimesat(f, support.TESTFN, (now, now))
653 finally:
654 posix.close(f)
655
656 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
657 def test_linkat(self):
658 f = posix.open(posix.getcwd(), posix.O_RDONLY)
659 try:
660 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
661 # should have same inodes
662 self.assertEqual(posix.stat(support.TESTFN)[1],
663 posix.stat(support.TESTFN + 'link')[1])
664 finally:
665 posix.close(f)
666 support.unlink(support.TESTFN + 'link')
667
668 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
669 def test_mkdirat(self):
670 f = posix.open(posix.getcwd(), posix.O_RDONLY)
671 try:
672 posix.mkdirat(f, support.TESTFN + 'dir')
673 posix.stat(support.TESTFN + 'dir') # should not raise exception
674 finally:
675 posix.close(f)
676 support.rmtree(support.TESTFN + 'dir')
677
678 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
679 "don't have mknodat()/S_IFIFO")
680 def test_mknodat(self):
681 # Test using mknodat() to create a FIFO (the only use specified
682 # by POSIX).
683 support.unlink(support.TESTFN)
684 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
685 f = posix.open(posix.getcwd(), posix.O_RDONLY)
686 try:
687 posix.mknodat(f, support.TESTFN, mode, 0)
688 except OSError as e:
689 # Some old systems don't allow unprivileged users to use
690 # mknod(), or only support creating device nodes.
691 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
692 else:
693 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
694 finally:
695 posix.close(f)
696
697 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
698 def test_openat(self):
699 support.unlink(support.TESTFN)
700 with open(support.TESTFN, 'w') as outfile:
701 outfile.write("testline\n")
702 a = posix.open(posix.getcwd(), posix.O_RDONLY)
703 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
704 try:
705 res = posix.read(b, 9).decode(encoding="utf-8")
706 self.assertEqual("testline\n", res)
707 finally:
708 posix.close(a)
709 posix.close(b)
710
711 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
712 def test_readlinkat(self):
713 os.symlink(support.TESTFN, support.TESTFN + 'link')
714 f = posix.open(posix.getcwd(), posix.O_RDONLY)
715 try:
716 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
717 posix.readlinkat(f, support.TESTFN + 'link'))
718 finally:
719 support.unlink(support.TESTFN + 'link')
720 posix.close(f)
721
722 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
723 def test_renameat(self):
724 support.unlink(support.TESTFN)
725 open(support.TESTFN + 'ren', 'w').close()
726 f = posix.open(posix.getcwd(), posix.O_RDONLY)
727 try:
728 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
729 except:
730 posix.rename(support.TESTFN + 'ren', support.TESTFN)
731 raise
732 else:
733 posix.stat(support.TESTFN) # should not throw exception
734 finally:
735 posix.close(f)
736
737 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
738 def test_symlinkat(self):
739 f = posix.open(posix.getcwd(), posix.O_RDONLY)
740 try:
741 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
742 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
743 finally:
744 posix.close(f)
745 support.unlink(support.TESTFN + 'link')
746
747 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
748 def test_unlinkat(self):
749 f = posix.open(posix.getcwd(), posix.O_RDONLY)
750 open(support.TESTFN + 'del', 'w').close()
751 posix.stat(support.TESTFN + 'del') # should not throw exception
752 try:
753 posix.unlinkat(f, support.TESTFN + 'del')
754 except:
755 support.unlink(support.TESTFN + 'del')
756 raise
757 else:
758 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
759 finally:
760 posix.close(f)
761
762 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
763 def test_utimensat(self):
764 f = posix.open(posix.getcwd(), posix.O_RDONLY)
765 try:
766 now = time.time()
767 posix.utimensat(f, support.TESTFN, None, None)
768 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
769 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
770 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
771 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
772 (int(now), int((now - int(now)) * 1e9)))
773 finally:
774 posix.close(f)
775
776 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
777 def test_mkfifoat(self):
778 support.unlink(support.TESTFN)
779 f = posix.open(posix.getcwd(), posix.O_RDONLY)
780 try:
781 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
782 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
783 finally:
784 posix.close(f)
785
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000786class PosixGroupsTester(unittest.TestCase):
787
788 def setUp(self):
789 if posix.getuid() != 0:
790 raise unittest.SkipTest("not enough privileges")
791 if not hasattr(posix, 'getgroups'):
792 raise unittest.SkipTest("need posix.getgroups")
793 if sys.platform == 'darwin':
794 raise unittest.SkipTest("getgroups(2) is broken on OSX")
795 self.saved_groups = posix.getgroups()
796
797 def tearDown(self):
798 if hasattr(posix, 'setgroups'):
799 posix.setgroups(self.saved_groups)
800 elif hasattr(posix, 'initgroups'):
801 name = pwd.getpwuid(posix.getuid()).pw_name
802 posix.initgroups(name, self.saved_groups[0])
803
804 @unittest.skipUnless(hasattr(posix, 'initgroups'),
805 "test needs posix.initgroups()")
806 def test_initgroups(self):
807 # find missing group
808
Antoine Pitroue5a91012010-09-04 17:32:06 +0000809 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000810 name = pwd.getpwuid(posix.getuid()).pw_name
811 posix.initgroups(name, g)
812 self.assertIn(g, posix.getgroups())
813
814 @unittest.skipUnless(hasattr(posix, 'setgroups'),
815 "test needs posix.setgroups()")
816 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000817 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000818 posix.setgroups(groups)
819 self.assertListEqual(groups, posix.getgroups())
820
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000821
Neal Norwitze241ce82003-02-17 18:17:05 +0000822def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +0100823 try:
824 support.run_unittest(PosixTester, PosixGroupsTester)
825 finally:
826 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +0000827
828if __name__ == '__main__':
829 test_main()