blob: 0e9ac75172c402bd4221b81bb2b2b3e7a68a8bc2 [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
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000012import pwd
Benjamin Petersondcf97b92008-07-02 17:30:14 +000013import shutil
Benjamin Peterson052a02b2010-08-17 01:27:09 +000014import stat
Neal Norwitze241ce82003-02-17 18:17:05 +000015import unittest
16import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000017
Neal Norwitze241ce82003-02-17 18:17:05 +000018
19class PosixTester(unittest.TestCase):
20
21 def setUp(self):
22 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000023 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000024 fp.close()
Brett Cannonc8d502e2010-03-20 21:53:28 +000025 self._warnings_manager = support.check_warnings()
26 self._warnings_manager.__enter__()
27 warnings.filterwarnings('ignore', '.* potential security risk .*',
28 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000029
30 def tearDown(self):
Neal Norwitzc34177c2008-08-25 01:04:16 +000031 support.unlink(support.TESTFN)
Brett Cannonc8d502e2010-03-20 21:53:28 +000032 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000033
34 def testNoArgFunctions(self):
35 # test posix functions which take no arguments and have
36 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000037 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000038 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000039 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020040 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000041 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000042
Neal Norwitze241ce82003-02-17 18:17:05 +000043 for name in NO_ARG_FUNCTIONS:
44 posix_func = getattr(posix, name, None)
45 if posix_func is not None:
46 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000047 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000048
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000049 if hasattr(posix, 'getresuid'):
50 def test_getresuid(self):
51 user_ids = posix.getresuid()
52 self.assertEqual(len(user_ids), 3)
53 for val in user_ids:
54 self.assertGreaterEqual(val, 0)
55
56 if hasattr(posix, 'getresgid'):
57 def test_getresgid(self):
58 group_ids = posix.getresgid()
59 self.assertEqual(len(group_ids), 3)
60 for val in group_ids:
61 self.assertGreaterEqual(val, 0)
62
63 if hasattr(posix, 'setresuid'):
64 def test_setresuid(self):
65 current_user_ids = posix.getresuid()
66 self.assertIsNone(posix.setresuid(*current_user_ids))
67 # -1 means don't change that value.
68 self.assertIsNone(posix.setresuid(-1, -1, -1))
69
70 def test_setresuid_exception(self):
71 # Don't do this test if someone is silly enough to run us as root.
72 current_user_ids = posix.getresuid()
73 if 0 not in current_user_ids:
74 new_user_ids = (current_user_ids[0]+1, -1, -1)
75 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
76
77 if hasattr(posix, 'setresgid'):
78 def test_setresgid(self):
79 current_group_ids = posix.getresgid()
80 self.assertIsNone(posix.setresgid(*current_group_ids))
81 # -1 means don't change that value.
82 self.assertIsNone(posix.setresgid(-1, -1, -1))
83
84 def test_setresgid_exception(self):
85 # Don't do this test if someone is silly enough to run us as root.
86 current_group_ids = posix.getresgid()
87 if 0 not in current_group_ids:
88 new_group_ids = (current_group_ids[0]+1, -1, -1)
89 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
90
Antoine Pitroub7572f02009-12-02 20:46:48 +000091 @unittest.skipUnless(hasattr(posix, 'initgroups'),
92 "test needs os.initgroups()")
93 def test_initgroups(self):
94 # It takes a string and an integer; check that it raises a TypeError
95 # for other argument lists.
96 self.assertRaises(TypeError, posix.initgroups)
97 self.assertRaises(TypeError, posix.initgroups, None)
98 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
99 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
100
101 # If a non-privileged user invokes it, it should fail with OSError
102 # EPERM.
103 if os.getuid() != 0:
104 name = pwd.getpwuid(posix.getuid()).pw_name
105 try:
106 posix.initgroups(name, 13)
107 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000108 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000109 else:
110 self.fail("Expected OSError to be raised by initgroups")
111
Neal Norwitze241ce82003-02-17 18:17:05 +0000112 def test_statvfs(self):
113 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000114 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000115
116 def test_fstatvfs(self):
117 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000118 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000119 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000120 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000121 finally:
122 fp.close()
123
124 def test_ftruncate(self):
125 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000126 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000127 try:
128 # we need to have some data to truncate
129 fp.write('test')
130 fp.flush()
131 posix.ftruncate(fp.fileno(), 0)
132 finally:
133 fp.close()
134
Ross Lagerwall7807c352011-03-17 20:20:30 +0200135 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
136 def test_truncate(self):
137 with open(support.TESTFN, 'w') as fp:
138 fp.write('test')
139 fp.flush()
140 posix.truncate(support.TESTFN, 0)
141
142 @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
143 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200144 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200145 def test_fexecve(self):
146 fp = os.open(sys.executable, os.O_RDONLY)
147 try:
148 pid = os.fork()
149 if pid == 0:
150 os.chdir(os.path.split(sys.executable)[0])
151 posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
152 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200153 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200154 finally:
155 os.close(fp)
156
157 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
158 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
159 def test_waitid(self):
160 pid = os.fork()
161 if pid == 0:
162 os.chdir(os.path.split(sys.executable)[0])
163 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
164 else:
165 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
166 self.assertEqual(pid, res.si_pid)
167
168 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
169 def test_lockf(self):
170 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
171 try:
172 os.write(fd, b'test')
173 os.lseek(fd, 0, os.SEEK_SET)
174 posix.lockf(fd, posix.F_LOCK, 4)
175 # section is locked
176 posix.lockf(fd, posix.F_ULOCK, 4)
177 finally:
178 os.close(fd)
179
180 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
181 def test_pread(self):
182 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
183 try:
184 os.write(fd, b'test')
185 os.lseek(fd, 0, os.SEEK_SET)
186 self.assertEqual(b'es', posix.pread(fd, 2, 1))
187 # the first pread() shoudn't disturb the file offset
188 self.assertEqual(b'te', posix.read(fd, 2))
189 finally:
190 os.close(fd)
191
192 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
193 def test_pwrite(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 posix.pwrite(fd, b'xx', 1)
199 self.assertEqual(b'txxt', posix.read(fd, 4))
200 finally:
201 os.close(fd)
202
203 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
204 "test needs posix.posix_fallocate()")
205 def test_posix_fallocate(self):
206 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
207 try:
208 posix.posix_fallocate(fd, 0, 10)
209 except OSError as inst:
210 # issue10812, ZFS doesn't appear to support posix_fallocate,
211 # so skip Solaris-based since they are likely to have ZFS.
212 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
213 raise
214 finally:
215 os.close(fd)
216
217 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
218 "test needs posix.posix_fadvise()")
219 def test_posix_fadvise(self):
220 fd = os.open(support.TESTFN, os.O_RDONLY)
221 try:
222 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
223 finally:
224 os.close(fd)
225
226 @unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
227 def test_futimes(self):
228 now = time.time()
229 fd = os.open(support.TESTFN, os.O_RDONLY)
230 try:
231 posix.futimes(fd, None)
232 self.assertRaises(TypeError, posix.futimes, fd, (None, None))
233 self.assertRaises(TypeError, posix.futimes, fd, (now, None))
234 self.assertRaises(TypeError, posix.futimes, fd, (None, now))
235 posix.futimes(fd, (int(now), int(now)))
236 posix.futimes(fd, (now, now))
237 finally:
238 os.close(fd)
239
240 @unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
241 def test_lutimes(self):
242 now = time.time()
243 posix.lutimes(support.TESTFN, None)
244 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
245 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
246 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
247 posix.lutimes(support.TESTFN, (int(now), int(now)))
248 posix.lutimes(support.TESTFN, (now, now))
249
250 @unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
251 def test_futimens(self):
252 now = time.time()
253 fd = os.open(support.TESTFN, os.O_RDONLY)
254 try:
255 self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
256 self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
257 self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
258 posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
259 (int(now), int((now - int(now)) * 1e9)))
260 finally:
261 os.close(fd)
262
263 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
264 def test_writev(self):
265 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
266 try:
267 os.writev(fd, (b'test1', b'tt2', b't3'))
268 os.lseek(fd, 0, os.SEEK_SET)
269 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
270 finally:
271 os.close(fd)
272
273 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
274 def test_readv(self):
275 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
276 try:
277 os.write(fd, b'test1tt2t3')
278 os.lseek(fd, 0, os.SEEK_SET)
279 buf = [bytearray(i) for i in [5, 3, 2]]
280 self.assertEqual(posix.readv(fd, buf), 10)
281 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
282 finally:
283 os.close(fd)
284
Neal Norwitze241ce82003-02-17 18:17:05 +0000285 def test_dup(self):
286 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000287 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000288 try:
289 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000290 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000291 os.close(fd)
292 finally:
293 fp.close()
294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000295 def test_confstr(self):
296 if hasattr(posix, 'confstr'):
297 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
298 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
299
Neal Norwitze241ce82003-02-17 18:17:05 +0000300 def test_dup2(self):
301 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000302 fp1 = open(support.TESTFN)
303 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000304 try:
305 posix.dup2(fp1.fileno(), fp2.fileno())
306 finally:
307 fp1.close()
308 fp2.close()
309
Skip Montanaro98470002005-06-17 01:14:49 +0000310 def test_osexlock(self):
311 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000312 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000313 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000314 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000315 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
316 os.close(fd)
317
318 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000319 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000320 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000321 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000322 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
323 os.close(fd)
324
325 def test_osshlock(self):
326 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000327 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000328 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000329 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000330 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
331 os.close(fd2)
332 os.close(fd1)
333
334 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000335 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000336 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000337 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000338 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
339 os.close(fd)
340
Neal Norwitze241ce82003-02-17 18:17:05 +0000341 def test_fstat(self):
342 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000343 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000344 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000345 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000346 finally:
347 fp.close()
348
349 def test_stat(self):
350 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000351 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000352
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000353 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
354 def test_mkfifo(self):
355 support.unlink(support.TESTFN)
356 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
357 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
358
359 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
360 "don't have mknod()/S_IFIFO")
361 def test_mknod(self):
362 # Test using mknod() to create a FIFO (the only use specified
363 # by POSIX).
364 support.unlink(support.TESTFN)
365 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
366 try:
367 posix.mknod(support.TESTFN, mode, 0)
368 except OSError as e:
369 # Some old systems don't allow unprivileged users to use
370 # mknod(), or only support creating device nodes.
371 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
372 else:
373 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
374
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000375 def _test_all_chown_common(self, chown_func, first_param):
376 """Common code for chown, fchown and lchown tests."""
377 if os.getuid() == 0:
378 try:
379 # Many linux distros have a nfsnobody user as MAX_UID-2
380 # that makes a good test case for signedness issues.
381 # http://bugs.python.org/issue1747858
382 # This part of the test only runs when run as root.
383 # Only scary people run their tests as root.
384 ent = pwd.getpwnam('nfsnobody')
385 chown_func(first_param, ent.pw_uid, ent.pw_gid)
386 except KeyError:
387 pass
388 else:
389 # non-root cannot chown to root, raises OSError
390 self.assertRaises(OSError, chown_func,
391 first_param, 0, 0)
392 # test a successful chown call
393 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000394
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000395 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
396 def test_chown(self):
397 # raise an OSError if the file does not exist
398 os.unlink(support.TESTFN)
399 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000400
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000401 # re-create the file
402 open(support.TESTFN, 'w').close()
403 self._test_all_chown_common(posix.chown, support.TESTFN)
404
405 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
406 def test_fchown(self):
407 os.unlink(support.TESTFN)
408
409 # re-create the file
410 test_file = open(support.TESTFN, 'w')
411 try:
412 fd = test_file.fileno()
413 self._test_all_chown_common(posix.fchown, fd)
414 finally:
415 test_file.close()
416
417 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
418 def test_lchown(self):
419 os.unlink(support.TESTFN)
420 # create a symlink
421 os.symlink('/tmp/dummy-symlink-target', support.TESTFN)
422 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000423
Neal Norwitze241ce82003-02-17 18:17:05 +0000424 def test_chdir(self):
425 if hasattr(posix, 'chdir'):
426 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000427 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000428
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000429 def test_listdir(self):
430 if hasattr(posix, 'listdir'):
431 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
432
433 def test_listdir_default(self):
434 # When listdir is called without argument, it's the same as listdir(os.curdir)
435 if hasattr(posix, 'listdir'):
436 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000437
Antoine Pitrou8250e232011-02-25 23:41:16 +0000438 @unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
439 def test_fdlistdir(self):
440 f = posix.open(posix.getcwd(), posix.O_RDONLY)
441 self.assertEqual(
442 sorted(posix.listdir('.')),
443 sorted(posix.fdlistdir(f))
444 )
445 # Check the fd was closed by fdlistdir
446 with self.assertRaises(OSError) as ctx:
447 posix.close(f)
448 self.assertEqual(ctx.exception.errno, errno.EBADF)
449
Neal Norwitze241ce82003-02-17 18:17:05 +0000450 def test_access(self):
451 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000452 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000453
454 def test_umask(self):
455 if hasattr(posix, 'umask'):
456 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000457 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000458 posix.umask(old_mask)
459
460 def test_strerror(self):
461 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000462 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000463
464 def test_pipe(self):
465 if hasattr(posix, 'pipe'):
466 reader, writer = posix.pipe()
467 os.close(reader)
468 os.close(writer)
469
Neal Norwitze241ce82003-02-17 18:17:05 +0000470 def test_utime(self):
471 if hasattr(posix, 'utime'):
472 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000473 posix.utime(support.TESTFN, None)
474 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
475 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
476 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
477 posix.utime(support.TESTFN, (int(now), int(now)))
478 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000479
Thomas Wouterscf297e42007-02-23 15:07:44 +0000480 def test_chflags(self):
481 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000482 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000483 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000484 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000485
486 def test_lchflags(self):
487 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000488 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000489 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000490 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000491
Guido van Rossum98297ee2007-11-06 21:34:58 +0000492 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000493 if os.name == "nt":
494 item_type = str
495 else:
496 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000497 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000498 self.assertEqual(type(k), item_type)
499 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000500
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000501 def test_getcwd_long_pathnames(self):
502 if hasattr(posix, 'getcwd'):
503 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
504 curdir = os.getcwd()
505 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
506
507 try:
508 os.mkdir(base_path)
509 os.chdir(base_path)
510 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000511# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000512# because the test results in Error in that case.
513# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000514# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000515 return
516
517 def _create_and_do_getcwd(dirname, current_path_length = 0):
518 try:
519 os.mkdir(dirname)
520 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000521 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000522
523 os.chdir(dirname)
524 try:
525 os.getcwd()
526 if current_path_length < 1027:
527 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
528 finally:
529 os.chdir('..')
530 os.rmdir(dirname)
531
532 _create_and_do_getcwd(dirname)
533
534 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000535 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000536 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000537
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000538 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000539 def test_getgroups(self):
540 with os.popen('id -G') as idg:
541 groups = idg.read().strip()
542
543 if not groups:
544 raise unittest.SkipTest("need working 'id -G'")
545
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000546 # 'id -G' and 'os.getgroups()' should return the same
547 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000548 # #10822 - it is implementation defined whether posix.getgroups()
549 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000550 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000551 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000552 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000553
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000554 # tests for the posix *at functions follow
555
556 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
557 def test_faccessat(self):
558 f = posix.open(posix.getcwd(), posix.O_RDONLY)
559 try:
560 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
561 finally:
562 posix.close(f)
563
564 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
565 def test_fchmodat(self):
566 os.chmod(support.TESTFN, stat.S_IRUSR)
567
568 f = posix.open(posix.getcwd(), posix.O_RDONLY)
569 try:
570 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
571
572 s = posix.stat(support.TESTFN)
573 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
574 finally:
575 posix.close(f)
576
577 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
578 def test_fchownat(self):
579 support.unlink(support.TESTFN)
580 open(support.TESTFN, 'w').close()
581
582 f = posix.open(posix.getcwd(), posix.O_RDONLY)
583 try:
584 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
585 finally:
586 posix.close(f)
587
588 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
589 def test_fstatat(self):
590 support.unlink(support.TESTFN)
591 with open(support.TESTFN, 'w') as outfile:
592 outfile.write("testline\n")
593
594 f = posix.open(posix.getcwd(), posix.O_RDONLY)
595 try:
596 s1 = posix.stat(support.TESTFN)
597 s2 = posix.fstatat(f, support.TESTFN)
598 self.assertEqual(s1, s2)
599 finally:
600 posix.close(f)
601
602 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
603 def test_futimesat(self):
604 f = posix.open(posix.getcwd(), posix.O_RDONLY)
605 try:
606 now = time.time()
607 posix.futimesat(f, support.TESTFN, None)
608 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
609 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
610 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
611 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
612 posix.futimesat(f, support.TESTFN, (now, now))
613 finally:
614 posix.close(f)
615
616 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
617 def test_linkat(self):
618 f = posix.open(posix.getcwd(), posix.O_RDONLY)
619 try:
620 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
621 # should have same inodes
622 self.assertEqual(posix.stat(support.TESTFN)[1],
623 posix.stat(support.TESTFN + 'link')[1])
624 finally:
625 posix.close(f)
626 support.unlink(support.TESTFN + 'link')
627
628 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
629 def test_mkdirat(self):
630 f = posix.open(posix.getcwd(), posix.O_RDONLY)
631 try:
632 posix.mkdirat(f, support.TESTFN + 'dir')
633 posix.stat(support.TESTFN + 'dir') # should not raise exception
634 finally:
635 posix.close(f)
636 support.rmtree(support.TESTFN + 'dir')
637
638 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
639 "don't have mknodat()/S_IFIFO")
640 def test_mknodat(self):
641 # Test using mknodat() to create a FIFO (the only use specified
642 # by POSIX).
643 support.unlink(support.TESTFN)
644 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
645 f = posix.open(posix.getcwd(), posix.O_RDONLY)
646 try:
647 posix.mknodat(f, support.TESTFN, mode, 0)
648 except OSError as e:
649 # Some old systems don't allow unprivileged users to use
650 # mknod(), or only support creating device nodes.
651 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
652 else:
653 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
654 finally:
655 posix.close(f)
656
657 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
658 def test_openat(self):
659 support.unlink(support.TESTFN)
660 with open(support.TESTFN, 'w') as outfile:
661 outfile.write("testline\n")
662 a = posix.open(posix.getcwd(), posix.O_RDONLY)
663 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
664 try:
665 res = posix.read(b, 9).decode(encoding="utf-8")
666 self.assertEqual("testline\n", res)
667 finally:
668 posix.close(a)
669 posix.close(b)
670
671 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
672 def test_readlinkat(self):
673 os.symlink(support.TESTFN, support.TESTFN + 'link')
674 f = posix.open(posix.getcwd(), posix.O_RDONLY)
675 try:
676 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
677 posix.readlinkat(f, support.TESTFN + 'link'))
678 finally:
679 support.unlink(support.TESTFN + 'link')
680 posix.close(f)
681
682 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
683 def test_renameat(self):
684 support.unlink(support.TESTFN)
685 open(support.TESTFN + 'ren', 'w').close()
686 f = posix.open(posix.getcwd(), posix.O_RDONLY)
687 try:
688 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
689 except:
690 posix.rename(support.TESTFN + 'ren', support.TESTFN)
691 raise
692 else:
693 posix.stat(support.TESTFN) # should not throw exception
694 finally:
695 posix.close(f)
696
697 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
698 def test_symlinkat(self):
699 f = posix.open(posix.getcwd(), posix.O_RDONLY)
700 try:
701 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
702 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
703 finally:
704 posix.close(f)
705 support.unlink(support.TESTFN + 'link')
706
707 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
708 def test_unlinkat(self):
709 f = posix.open(posix.getcwd(), posix.O_RDONLY)
710 open(support.TESTFN + 'del', 'w').close()
711 posix.stat(support.TESTFN + 'del') # should not throw exception
712 try:
713 posix.unlinkat(f, support.TESTFN + 'del')
714 except:
715 support.unlink(support.TESTFN + 'del')
716 raise
717 else:
718 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
719 finally:
720 posix.close(f)
721
722 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
723 def test_utimensat(self):
724 f = posix.open(posix.getcwd(), posix.O_RDONLY)
725 try:
726 now = time.time()
727 posix.utimensat(f, support.TESTFN, None, None)
728 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
729 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
730 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
731 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
732 (int(now), int((now - int(now)) * 1e9)))
733 finally:
734 posix.close(f)
735
736 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
737 def test_mkfifoat(self):
738 support.unlink(support.TESTFN)
739 f = posix.open(posix.getcwd(), posix.O_RDONLY)
740 try:
741 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
742 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
743 finally:
744 posix.close(f)
745
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000746class PosixGroupsTester(unittest.TestCase):
747
748 def setUp(self):
749 if posix.getuid() != 0:
750 raise unittest.SkipTest("not enough privileges")
751 if not hasattr(posix, 'getgroups'):
752 raise unittest.SkipTest("need posix.getgroups")
753 if sys.platform == 'darwin':
754 raise unittest.SkipTest("getgroups(2) is broken on OSX")
755 self.saved_groups = posix.getgroups()
756
757 def tearDown(self):
758 if hasattr(posix, 'setgroups'):
759 posix.setgroups(self.saved_groups)
760 elif hasattr(posix, 'initgroups'):
761 name = pwd.getpwuid(posix.getuid()).pw_name
762 posix.initgroups(name, self.saved_groups[0])
763
764 @unittest.skipUnless(hasattr(posix, 'initgroups'),
765 "test needs posix.initgroups()")
766 def test_initgroups(self):
767 # find missing group
768
Antoine Pitroue5a91012010-09-04 17:32:06 +0000769 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000770 name = pwd.getpwuid(posix.getuid()).pw_name
771 posix.initgroups(name, g)
772 self.assertIn(g, posix.getgroups())
773
774 @unittest.skipUnless(hasattr(posix, 'setgroups'),
775 "test needs posix.setgroups()")
776 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000777 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000778 posix.setgroups(groups)
779 self.assertListEqual(groups, posix.getgroups())
780
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000781
Neal Norwitze241ce82003-02-17 18:17:05 +0000782def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +0100783 try:
784 support.run_unittest(PosixTester, PosixGroupsTester)
785 finally:
786 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +0000787
788if __name__ == '__main__':
789 test_main()