blob: 14bd356a0e11c314f8e0efab479c910569cecfc8 [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
Ned Deily3eb67d52011-06-28 00:00:28 -070019_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp')
Neal Norwitze241ce82003-02-17 18:17:05 +000020
21class PosixTester(unittest.TestCase):
22
23 def setUp(self):
24 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000025 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000026 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070027 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000028 self._warnings_manager = support.check_warnings()
29 self._warnings_manager.__enter__()
30 warnings.filterwarnings('ignore', '.* potential security risk .*',
31 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000032
33 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070034 for teardown_file in self.teardown_files:
35 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000036 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000037
38 def testNoArgFunctions(self):
39 # test posix functions which take no arguments and have
40 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000041 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000042 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000043 "getegid", "geteuid", "getgid", "getgroups",
Ross Lagerwall7807c352011-03-17 20:20:30 +020044 "getpid", "getpgrp", "getppid", "getuid", "sync",
Neal Norwitze241ce82003-02-17 18:17:05 +000045 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000046
Neal Norwitze241ce82003-02-17 18:17:05 +000047 for name in NO_ARG_FUNCTIONS:
48 posix_func = getattr(posix, name, None)
49 if posix_func is not None:
50 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000051 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000052
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000053 if hasattr(posix, 'getresuid'):
54 def test_getresuid(self):
55 user_ids = posix.getresuid()
56 self.assertEqual(len(user_ids), 3)
57 for val in user_ids:
58 self.assertGreaterEqual(val, 0)
59
60 if hasattr(posix, 'getresgid'):
61 def test_getresgid(self):
62 group_ids = posix.getresgid()
63 self.assertEqual(len(group_ids), 3)
64 for val in group_ids:
65 self.assertGreaterEqual(val, 0)
66
67 if hasattr(posix, 'setresuid'):
68 def test_setresuid(self):
69 current_user_ids = posix.getresuid()
70 self.assertIsNone(posix.setresuid(*current_user_ids))
71 # -1 means don't change that value.
72 self.assertIsNone(posix.setresuid(-1, -1, -1))
73
74 def test_setresuid_exception(self):
75 # Don't do this test if someone is silly enough to run us as root.
76 current_user_ids = posix.getresuid()
77 if 0 not in current_user_ids:
78 new_user_ids = (current_user_ids[0]+1, -1, -1)
79 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
80
81 if hasattr(posix, 'setresgid'):
82 def test_setresgid(self):
83 current_group_ids = posix.getresgid()
84 self.assertIsNone(posix.setresgid(*current_group_ids))
85 # -1 means don't change that value.
86 self.assertIsNone(posix.setresgid(-1, -1, -1))
87
88 def test_setresgid_exception(self):
89 # Don't do this test if someone is silly enough to run us as root.
90 current_group_ids = posix.getresgid()
91 if 0 not in current_group_ids:
92 new_group_ids = (current_group_ids[0]+1, -1, -1)
93 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
94
Antoine Pitroub7572f02009-12-02 20:46:48 +000095 @unittest.skipUnless(hasattr(posix, 'initgroups'),
96 "test needs os.initgroups()")
97 def test_initgroups(self):
98 # It takes a string and an integer; check that it raises a TypeError
99 # for other argument lists.
100 self.assertRaises(TypeError, posix.initgroups)
101 self.assertRaises(TypeError, posix.initgroups, None)
102 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
103 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
104
105 # If a non-privileged user invokes it, it should fail with OSError
106 # EPERM.
107 if os.getuid() != 0:
108 name = pwd.getpwuid(posix.getuid()).pw_name
109 try:
110 posix.initgroups(name, 13)
111 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000112 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000113 else:
114 self.fail("Expected OSError to be raised by initgroups")
115
Neal Norwitze241ce82003-02-17 18:17:05 +0000116 def test_statvfs(self):
117 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000118 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000119
120 def test_fstatvfs(self):
121 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000122 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000123 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000124 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000125 finally:
126 fp.close()
127
128 def test_ftruncate(self):
129 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000130 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000131 try:
132 # we need to have some data to truncate
133 fp.write('test')
134 fp.flush()
135 posix.ftruncate(fp.fileno(), 0)
136 finally:
137 fp.close()
138
Ross Lagerwall7807c352011-03-17 20:20:30 +0200139 @unittest.skipUnless(hasattr(posix, 'truncate'), "test needs posix.truncate()")
140 def test_truncate(self):
141 with open(support.TESTFN, 'w') as fp:
142 fp.write('test')
143 fp.flush()
144 posix.truncate(support.TESTFN, 0)
145
146 @unittest.skipUnless(hasattr(posix, 'fexecve'), "test needs posix.fexecve()")
147 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200148 @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
Ross Lagerwall7807c352011-03-17 20:20:30 +0200149 def test_fexecve(self):
150 fp = os.open(sys.executable, os.O_RDONLY)
151 try:
152 pid = os.fork()
153 if pid == 0:
154 os.chdir(os.path.split(sys.executable)[0])
155 posix.fexecve(fp, [sys.executable, '-c', 'pass'], os.environ)
156 else:
Ross Lagerwalldedf6cf2011-03-20 18:27:05 +0200157 self.assertEqual(os.waitpid(pid, 0), (pid, 0))
Ross Lagerwall7807c352011-03-17 20:20:30 +0200158 finally:
159 os.close(fp)
160
161 @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()")
162 @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()")
163 def test_waitid(self):
164 pid = os.fork()
165 if pid == 0:
166 os.chdir(os.path.split(sys.executable)[0])
167 posix.execve(sys.executable, [sys.executable, '-c', 'pass'], os.environ)
168 else:
169 res = posix.waitid(posix.P_PID, pid, posix.WEXITED)
170 self.assertEqual(pid, res.si_pid)
171
172 @unittest.skipUnless(hasattr(posix, 'lockf'), "test needs posix.lockf()")
173 def test_lockf(self):
174 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
175 try:
176 os.write(fd, b'test')
177 os.lseek(fd, 0, os.SEEK_SET)
178 posix.lockf(fd, posix.F_LOCK, 4)
179 # section is locked
180 posix.lockf(fd, posix.F_ULOCK, 4)
181 finally:
182 os.close(fd)
183
184 @unittest.skipUnless(hasattr(posix, 'pread'), "test needs posix.pread()")
185 def test_pread(self):
186 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
187 try:
188 os.write(fd, b'test')
189 os.lseek(fd, 0, os.SEEK_SET)
190 self.assertEqual(b'es', posix.pread(fd, 2, 1))
191 # the first pread() shoudn't disturb the file offset
192 self.assertEqual(b'te', posix.read(fd, 2))
193 finally:
194 os.close(fd)
195
196 @unittest.skipUnless(hasattr(posix, 'pwrite'), "test needs posix.pwrite()")
197 def test_pwrite(self):
198 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
199 try:
200 os.write(fd, b'test')
201 os.lseek(fd, 0, os.SEEK_SET)
202 posix.pwrite(fd, b'xx', 1)
203 self.assertEqual(b'txxt', posix.read(fd, 4))
204 finally:
205 os.close(fd)
206
207 @unittest.skipUnless(hasattr(posix, 'posix_fallocate'),
208 "test needs posix.posix_fallocate()")
209 def test_posix_fallocate(self):
210 fd = os.open(support.TESTFN, os.O_WRONLY | os.O_CREAT)
211 try:
212 posix.posix_fallocate(fd, 0, 10)
213 except OSError as inst:
214 # issue10812, ZFS doesn't appear to support posix_fallocate,
215 # so skip Solaris-based since they are likely to have ZFS.
216 if inst.errno != errno.EINVAL or not sys.platform.startswith("sunos"):
217 raise
218 finally:
219 os.close(fd)
220
221 @unittest.skipUnless(hasattr(posix, 'posix_fadvise'),
222 "test needs posix.posix_fadvise()")
223 def test_posix_fadvise(self):
224 fd = os.open(support.TESTFN, os.O_RDONLY)
225 try:
226 posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
227 finally:
228 os.close(fd)
229
230 @unittest.skipUnless(hasattr(posix, 'futimes'), "test needs posix.futimes()")
231 def test_futimes(self):
232 now = time.time()
233 fd = os.open(support.TESTFN, os.O_RDONLY)
234 try:
235 posix.futimes(fd, None)
236 self.assertRaises(TypeError, posix.futimes, fd, (None, None))
237 self.assertRaises(TypeError, posix.futimes, fd, (now, None))
238 self.assertRaises(TypeError, posix.futimes, fd, (None, now))
239 posix.futimes(fd, (int(now), int(now)))
240 posix.futimes(fd, (now, now))
241 finally:
242 os.close(fd)
243
244 @unittest.skipUnless(hasattr(posix, 'lutimes'), "test needs posix.lutimes()")
245 def test_lutimes(self):
246 now = time.time()
247 posix.lutimes(support.TESTFN, None)
248 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, None))
249 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (now, None))
250 self.assertRaises(TypeError, posix.lutimes, support.TESTFN, (None, now))
251 posix.lutimes(support.TESTFN, (int(now), int(now)))
252 posix.lutimes(support.TESTFN, (now, now))
253
254 @unittest.skipUnless(hasattr(posix, 'futimens'), "test needs posix.futimens()")
255 def test_futimens(self):
256 now = time.time()
257 fd = os.open(support.TESTFN, os.O_RDONLY)
258 try:
259 self.assertRaises(TypeError, posix.futimens, fd, (None, None), (None, None))
260 self.assertRaises(TypeError, posix.futimens, fd, (now, 0), None)
261 self.assertRaises(TypeError, posix.futimens, fd, None, (now, 0))
262 posix.futimens(fd, (int(now), int((now - int(now)) * 1e9)),
263 (int(now), int((now - int(now)) * 1e9)))
264 finally:
265 os.close(fd)
266
267 @unittest.skipUnless(hasattr(posix, 'writev'), "test needs posix.writev()")
268 def test_writev(self):
269 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
270 try:
271 os.writev(fd, (b'test1', b'tt2', b't3'))
272 os.lseek(fd, 0, os.SEEK_SET)
273 self.assertEqual(b'test1tt2t3', posix.read(fd, 10))
274 finally:
275 os.close(fd)
276
277 @unittest.skipUnless(hasattr(posix, 'readv'), "test needs posix.readv()")
278 def test_readv(self):
279 fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT)
280 try:
281 os.write(fd, b'test1tt2t3')
282 os.lseek(fd, 0, os.SEEK_SET)
283 buf = [bytearray(i) for i in [5, 3, 2]]
284 self.assertEqual(posix.readv(fd, buf), 10)
285 self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf])
286 finally:
287 os.close(fd)
288
Neal Norwitze241ce82003-02-17 18:17:05 +0000289 def test_dup(self):
290 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000291 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000292 try:
293 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000294 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000295 os.close(fd)
296 finally:
297 fp.close()
298
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000299 def test_confstr(self):
300 if hasattr(posix, 'confstr'):
301 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
302 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
303
Neal Norwitze241ce82003-02-17 18:17:05 +0000304 def test_dup2(self):
305 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000306 fp1 = open(support.TESTFN)
307 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000308 try:
309 posix.dup2(fp1.fileno(), fp2.fileno())
310 finally:
311 fp1.close()
312 fp2.close()
313
Charles-François Natali1e045b12011-05-22 20:42:32 +0200314 @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC")
Charles-François Natali239bb962011-06-03 12:55:15 +0200315 @support.requires_linux_version(2, 6, 23)
Charles-François Natali1e045b12011-05-22 20:42:32 +0200316 def test_oscloexec(self):
317 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
Victor Stinnerbf816222011-06-30 23:25:47 +0200413 support.create_empty_file(support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000414 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
Ned Deily3eb67d52011-06-28 00:00:28 -0700432 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000433 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()")
Charles-François Natali239bb962011-06-03 12:55:15 +0200482 @support.requires_linux_version(2, 6, 27)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200483 def test_pipe2(self):
484 self.assertRaises(TypeError, os.pipe2, 'DEADBEEF')
485 self.assertRaises(TypeError, os.pipe2, 0, 0)
486
Charles-François Natali368f34b2011-06-06 19:49:47 +0200487 # try calling with flags = 0, like os.pipe()
488 r, w = os.pipe2(0)
Charles-François Natalidaafdd52011-05-29 20:07:40 +0200489 os.close(r)
490 os.close(w)
491
492 # test flags
493 r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK)
494 self.addCleanup(os.close, r)
495 self.addCleanup(os.close, w)
496 self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
497 self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFD) & fcntl.FD_CLOEXEC)
498 # try reading from an empty pipe: this should fail, not block
499 self.assertRaises(OSError, os.read, r, 1)
500 # try a write big enough to fill-up the pipe: this should either
501 # fail or perform a partial write, not block
502 try:
503 os.write(w, b'x' * support.PIPE_MAX_SIZE)
504 except OSError:
505 pass
506
Neal Norwitze241ce82003-02-17 18:17:05 +0000507 def test_utime(self):
508 if hasattr(posix, 'utime'):
509 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000510 posix.utime(support.TESTFN, None)
511 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
512 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
513 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
514 posix.utime(support.TESTFN, (int(now), int(now)))
515 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000516
Ned Deily3eb67d52011-06-28 00:00:28 -0700517 def _test_chflags_regular_file(self, chflags_func, target_file):
518 st = os.stat(target_file)
519 self.assertTrue(hasattr(st, 'st_flags'))
520 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
521 try:
522 new_st = os.stat(target_file)
523 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
524 try:
525 fd = open(target_file, 'w+')
526 except IOError as e:
527 self.assertEqual(e.errno, errno.EPERM)
528 finally:
529 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000530
Ned Deily3eb67d52011-06-28 00:00:28 -0700531 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
532 def test_chflags(self):
533 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
534
535 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
536 def test_lchflags_regular_file(self):
537 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
538
539 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
540 def test_lchflags_symlink(self):
541 testfn_st = os.stat(support.TESTFN)
542
543 self.assertTrue(hasattr(testfn_st, 'st_flags'))
544
545 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
546 self.teardown_files.append(_DUMMY_SYMLINK)
547 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
548
549 posix.lchflags(_DUMMY_SYMLINK,
550 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
551 try:
552 new_testfn_st = os.stat(support.TESTFN)
553 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
554
555 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
556 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
557 new_dummy_symlink_st.st_flags)
558 finally:
559 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000560
Guido van Rossum98297ee2007-11-06 21:34:58 +0000561 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000562 if os.name == "nt":
563 item_type = str
564 else:
565 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000566 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000567 self.assertEqual(type(k), item_type)
568 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000569
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000570 def test_getcwd_long_pathnames(self):
571 if hasattr(posix, 'getcwd'):
572 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
573 curdir = os.getcwd()
574 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
575
576 try:
577 os.mkdir(base_path)
578 os.chdir(base_path)
579 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000580# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000581# because the test results in Error in that case.
582# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000583# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000584 return
585
586 def _create_and_do_getcwd(dirname, current_path_length = 0):
587 try:
588 os.mkdir(dirname)
589 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000590 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000591
592 os.chdir(dirname)
593 try:
594 os.getcwd()
595 if current_path_length < 1027:
596 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
597 finally:
598 os.chdir('..')
599 os.rmdir(dirname)
600
601 _create_and_do_getcwd(dirname)
602
603 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000604 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000605 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000606
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +0200607 @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()")
608 @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()")
609 @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()")
610 def test_getgrouplist(self):
611 with os.popen('id -G') as idg:
612 groups = idg.read().strip()
613
614 if not groups:
615 raise unittest.SkipTest("need working 'id -G'")
616
617 self.assertEqual(
618 set([int(x) for x in groups.split()]),
619 set(posix.getgrouplist(pwd.getpwuid(os.getuid())[0],
620 pwd.getpwuid(os.getuid())[3])))
621
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000622 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000623 def test_getgroups(self):
624 with os.popen('id -G') as idg:
625 groups = idg.read().strip()
626
627 if not groups:
628 raise unittest.SkipTest("need working 'id -G'")
629
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000630 # 'id -G' and 'os.getgroups()' should return the same
631 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000632 # #10822 - it is implementation defined whether posix.getgroups()
633 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000634 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000635 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000636 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000637
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000638 # tests for the posix *at functions follow
639
640 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
641 def test_faccessat(self):
642 f = posix.open(posix.getcwd(), posix.O_RDONLY)
643 try:
644 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
645 finally:
646 posix.close(f)
647
648 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
649 def test_fchmodat(self):
650 os.chmod(support.TESTFN, stat.S_IRUSR)
651
652 f = posix.open(posix.getcwd(), posix.O_RDONLY)
653 try:
654 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
655
656 s = posix.stat(support.TESTFN)
657 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
658 finally:
659 posix.close(f)
660
661 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
662 def test_fchownat(self):
663 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200664 support.create_empty_file(support.TESTFN)
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000665
666 f = posix.open(posix.getcwd(), posix.O_RDONLY)
667 try:
668 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
669 finally:
670 posix.close(f)
671
672 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
673 def test_fstatat(self):
674 support.unlink(support.TESTFN)
675 with open(support.TESTFN, 'w') as outfile:
676 outfile.write("testline\n")
677
678 f = posix.open(posix.getcwd(), posix.O_RDONLY)
679 try:
680 s1 = posix.stat(support.TESTFN)
681 s2 = posix.fstatat(f, support.TESTFN)
682 self.assertEqual(s1, s2)
683 finally:
684 posix.close(f)
685
686 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
687 def test_futimesat(self):
688 f = posix.open(posix.getcwd(), posix.O_RDONLY)
689 try:
690 now = time.time()
691 posix.futimesat(f, support.TESTFN, None)
692 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
693 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
694 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
695 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
696 posix.futimesat(f, support.TESTFN, (now, now))
697 finally:
698 posix.close(f)
699
700 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
701 def test_linkat(self):
702 f = posix.open(posix.getcwd(), posix.O_RDONLY)
703 try:
704 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
705 # should have same inodes
706 self.assertEqual(posix.stat(support.TESTFN)[1],
707 posix.stat(support.TESTFN + 'link')[1])
708 finally:
709 posix.close(f)
710 support.unlink(support.TESTFN + 'link')
711
712 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
713 def test_mkdirat(self):
714 f = posix.open(posix.getcwd(), posix.O_RDONLY)
715 try:
716 posix.mkdirat(f, support.TESTFN + 'dir')
717 posix.stat(support.TESTFN + 'dir') # should not raise exception
718 finally:
719 posix.close(f)
720 support.rmtree(support.TESTFN + 'dir')
721
722 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
723 "don't have mknodat()/S_IFIFO")
724 def test_mknodat(self):
725 # Test using mknodat() to create a FIFO (the only use specified
726 # by POSIX).
727 support.unlink(support.TESTFN)
728 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
729 f = posix.open(posix.getcwd(), posix.O_RDONLY)
730 try:
731 posix.mknodat(f, support.TESTFN, mode, 0)
732 except OSError as e:
733 # Some old systems don't allow unprivileged users to use
734 # mknod(), or only support creating device nodes.
735 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
736 else:
737 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
738 finally:
739 posix.close(f)
740
741 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
742 def test_openat(self):
743 support.unlink(support.TESTFN)
744 with open(support.TESTFN, 'w') as outfile:
745 outfile.write("testline\n")
746 a = posix.open(posix.getcwd(), posix.O_RDONLY)
747 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
748 try:
749 res = posix.read(b, 9).decode(encoding="utf-8")
750 self.assertEqual("testline\n", res)
751 finally:
752 posix.close(a)
753 posix.close(b)
754
755 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
756 def test_readlinkat(self):
757 os.symlink(support.TESTFN, support.TESTFN + 'link')
758 f = posix.open(posix.getcwd(), posix.O_RDONLY)
759 try:
760 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
761 posix.readlinkat(f, support.TESTFN + 'link'))
762 finally:
763 support.unlink(support.TESTFN + 'link')
764 posix.close(f)
765
766 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
767 def test_renameat(self):
768 support.unlink(support.TESTFN)
Victor Stinnerbf816222011-06-30 23:25:47 +0200769 support.create_empty_file(support.TESTFN + 'ren')
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000770 f = posix.open(posix.getcwd(), posix.O_RDONLY)
771 try:
772 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
773 except:
774 posix.rename(support.TESTFN + 'ren', support.TESTFN)
775 raise
776 else:
777 posix.stat(support.TESTFN) # should not throw exception
778 finally:
779 posix.close(f)
780
781 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
782 def test_symlinkat(self):
783 f = posix.open(posix.getcwd(), posix.O_RDONLY)
784 try:
785 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
786 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
787 finally:
788 posix.close(f)
789 support.unlink(support.TESTFN + 'link')
790
791 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
792 def test_unlinkat(self):
793 f = posix.open(posix.getcwd(), posix.O_RDONLY)
Victor Stinnerbf816222011-06-30 23:25:47 +0200794 support.create_empty_file(support.TESTFN + 'del')
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000795 posix.stat(support.TESTFN + 'del') # should not throw exception
796 try:
797 posix.unlinkat(f, support.TESTFN + 'del')
798 except:
799 support.unlink(support.TESTFN + 'del')
800 raise
801 else:
802 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
803 finally:
804 posix.close(f)
805
806 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
807 def test_utimensat(self):
808 f = posix.open(posix.getcwd(), posix.O_RDONLY)
809 try:
810 now = time.time()
811 posix.utimensat(f, support.TESTFN, None, None)
812 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
813 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
814 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
815 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
816 (int(now), int((now - int(now)) * 1e9)))
817 finally:
818 posix.close(f)
819
820 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
821 def test_mkfifoat(self):
822 support.unlink(support.TESTFN)
823 f = posix.open(posix.getcwd(), posix.O_RDONLY)
824 try:
825 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
826 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
827 finally:
828 posix.close(f)
829
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000830class PosixGroupsTester(unittest.TestCase):
831
832 def setUp(self):
833 if posix.getuid() != 0:
834 raise unittest.SkipTest("not enough privileges")
835 if not hasattr(posix, 'getgroups'):
836 raise unittest.SkipTest("need posix.getgroups")
837 if sys.platform == 'darwin':
838 raise unittest.SkipTest("getgroups(2) is broken on OSX")
839 self.saved_groups = posix.getgroups()
840
841 def tearDown(self):
842 if hasattr(posix, 'setgroups'):
843 posix.setgroups(self.saved_groups)
844 elif hasattr(posix, 'initgroups'):
845 name = pwd.getpwuid(posix.getuid()).pw_name
846 posix.initgroups(name, self.saved_groups[0])
847
848 @unittest.skipUnless(hasattr(posix, 'initgroups'),
849 "test needs posix.initgroups()")
850 def test_initgroups(self):
851 # find missing group
852
Antoine Pitroue5a91012010-09-04 17:32:06 +0000853 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000854 name = pwd.getpwuid(posix.getuid()).pw_name
855 posix.initgroups(name, g)
856 self.assertIn(g, posix.getgroups())
857
858 @unittest.skipUnless(hasattr(posix, 'setgroups'),
859 "test needs posix.setgroups()")
860 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000861 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000862 posix.setgroups(groups)
863 self.assertListEqual(groups, posix.getgroups())
864
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000865
Neal Norwitze241ce82003-02-17 18:17:05 +0000866def test_main():
Antoine Pitrou68c95922011-03-20 17:33:57 +0100867 try:
868 support.run_unittest(PosixTester, PosixGroupsTester)
869 finally:
870 support.reap_children()
Neal Norwitze241ce82003-02-17 18:17:05 +0000871
872if __name__ == '__main__':
873 test_main()