blob: 23c2100d7a31a8d062b864cebbce0b1d61f9715c [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",
40 "getpid", "getpgrp", "getppid", "getuid",
41 ]
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
135 def test_dup(self):
136 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000137 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 try:
139 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000140 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000141 os.close(fd)
142 finally:
143 fp.close()
144
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000145 def test_confstr(self):
146 if hasattr(posix, 'confstr'):
147 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
148 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
149
Neal Norwitze241ce82003-02-17 18:17:05 +0000150 def test_dup2(self):
151 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000152 fp1 = open(support.TESTFN)
153 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000154 try:
155 posix.dup2(fp1.fileno(), fp2.fileno())
156 finally:
157 fp1.close()
158 fp2.close()
159
Skip Montanaro98470002005-06-17 01:14:49 +0000160 def test_osexlock(self):
161 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000162 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000163 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000164 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000165 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
166 os.close(fd)
167
168 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000169 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000170 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000171 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000172 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
173 os.close(fd)
174
175 def test_osshlock(self):
176 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000177 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000178 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000180 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
181 os.close(fd2)
182 os.close(fd1)
183
184 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000185 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000186 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000187 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000188 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
189 os.close(fd)
190
Neal Norwitze241ce82003-02-17 18:17:05 +0000191 def test_fstat(self):
192 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000193 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000194 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000195 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000196 finally:
197 fp.close()
198
199 def test_stat(self):
200 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000201 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000202
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000203 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
204 def test_mkfifo(self):
205 support.unlink(support.TESTFN)
206 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
207 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
208
209 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
210 "don't have mknod()/S_IFIFO")
211 def test_mknod(self):
212 # Test using mknod() to create a FIFO (the only use specified
213 # by POSIX).
214 support.unlink(support.TESTFN)
215 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
216 try:
217 posix.mknod(support.TESTFN, mode, 0)
218 except OSError as e:
219 # Some old systems don't allow unprivileged users to use
220 # mknod(), or only support creating device nodes.
221 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
222 else:
223 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
224
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000225 def _test_all_chown_common(self, chown_func, first_param):
226 """Common code for chown, fchown and lchown tests."""
227 if os.getuid() == 0:
228 try:
229 # Many linux distros have a nfsnobody user as MAX_UID-2
230 # that makes a good test case for signedness issues.
231 # http://bugs.python.org/issue1747858
232 # This part of the test only runs when run as root.
233 # Only scary people run their tests as root.
234 ent = pwd.getpwnam('nfsnobody')
235 chown_func(first_param, ent.pw_uid, ent.pw_gid)
236 except KeyError:
237 pass
238 else:
239 # non-root cannot chown to root, raises OSError
240 self.assertRaises(OSError, chown_func,
241 first_param, 0, 0)
242 # test a successful chown call
243 chown_func(first_param, os.getuid(), os.getgid())
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000244
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000245 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
246 def test_chown(self):
247 # raise an OSError if the file does not exist
248 os.unlink(support.TESTFN)
249 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000250
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000251 # re-create the file
252 open(support.TESTFN, 'w').close()
253 self._test_all_chown_common(posix.chown, support.TESTFN)
254
255 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
256 def test_fchown(self):
257 os.unlink(support.TESTFN)
258
259 # re-create the file
260 test_file = open(support.TESTFN, 'w')
261 try:
262 fd = test_file.fileno()
263 self._test_all_chown_common(posix.fchown, fd)
264 finally:
265 test_file.close()
266
267 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
268 def test_lchown(self):
269 os.unlink(support.TESTFN)
270 # create a symlink
271 os.symlink('/tmp/dummy-symlink-target', support.TESTFN)
272 self._test_all_chown_common(posix.lchown, support.TESTFN)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000273
Neal Norwitze241ce82003-02-17 18:17:05 +0000274 def test_chdir(self):
275 if hasattr(posix, 'chdir'):
276 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000277 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000278
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000279 def test_listdir(self):
280 if hasattr(posix, 'listdir'):
281 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
282
283 def test_listdir_default(self):
284 # When listdir is called without argument, it's the same as listdir(os.curdir)
285 if hasattr(posix, 'listdir'):
286 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000287
Antoine Pitrou8250e232011-02-25 23:41:16 +0000288 @unittest.skipUnless(hasattr(posix, 'fdlistdir'), "test needs posix.fdlistdir()")
289 def test_fdlistdir(self):
290 f = posix.open(posix.getcwd(), posix.O_RDONLY)
291 self.assertEqual(
292 sorted(posix.listdir('.')),
293 sorted(posix.fdlistdir(f))
294 )
295 # Check the fd was closed by fdlistdir
296 with self.assertRaises(OSError) as ctx:
297 posix.close(f)
298 self.assertEqual(ctx.exception.errno, errno.EBADF)
299
Neal Norwitze241ce82003-02-17 18:17:05 +0000300 def test_access(self):
301 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000302 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000303
304 def test_umask(self):
305 if hasattr(posix, 'umask'):
306 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000307 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000308 posix.umask(old_mask)
309
310 def test_strerror(self):
311 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000312 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000313
314 def test_pipe(self):
315 if hasattr(posix, 'pipe'):
316 reader, writer = posix.pipe()
317 os.close(reader)
318 os.close(writer)
319
Neal Norwitze241ce82003-02-17 18:17:05 +0000320 def test_utime(self):
321 if hasattr(posix, 'utime'):
322 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000323 posix.utime(support.TESTFN, None)
324 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
325 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
326 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
327 posix.utime(support.TESTFN, (int(now), int(now)))
328 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000329
Thomas Wouterscf297e42007-02-23 15:07:44 +0000330 def test_chflags(self):
331 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000332 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000333 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000334 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000335
336 def test_lchflags(self):
337 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000338 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000339 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000340 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000341
Guido van Rossum98297ee2007-11-06 21:34:58 +0000342 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000343 if os.name == "nt":
344 item_type = str
345 else:
346 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000347 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000348 self.assertEqual(type(k), item_type)
349 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000350
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000351 def test_getcwd_long_pathnames(self):
352 if hasattr(posix, 'getcwd'):
353 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
354 curdir = os.getcwd()
355 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
356
357 try:
358 os.mkdir(base_path)
359 os.chdir(base_path)
360 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000361# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000362# because the test results in Error in that case.
363# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000364# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000365 return
366
367 def _create_and_do_getcwd(dirname, current_path_length = 0):
368 try:
369 os.mkdir(dirname)
370 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000371 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000372
373 os.chdir(dirname)
374 try:
375 os.getcwd()
376 if current_path_length < 1027:
377 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
378 finally:
379 os.chdir('..')
380 os.rmdir(dirname)
381
382 _create_and_do_getcwd(dirname)
383
384 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000385 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000386 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000387
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000388 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000389 def test_getgroups(self):
390 with os.popen('id -G') as idg:
391 groups = idg.read().strip()
392
393 if not groups:
394 raise unittest.SkipTest("need working 'id -G'")
395
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000396 # 'id -G' and 'os.getgroups()' should return the same
397 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000398 # #10822 - it is implementation defined whether posix.getgroups()
399 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000400 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000401 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000402 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000403
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000404 # tests for the posix *at functions follow
405
406 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
407 def test_faccessat(self):
408 f = posix.open(posix.getcwd(), posix.O_RDONLY)
409 try:
410 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
411 finally:
412 posix.close(f)
413
414 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
415 def test_fchmodat(self):
416 os.chmod(support.TESTFN, stat.S_IRUSR)
417
418 f = posix.open(posix.getcwd(), posix.O_RDONLY)
419 try:
420 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
421
422 s = posix.stat(support.TESTFN)
423 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
424 finally:
425 posix.close(f)
426
427 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
428 def test_fchownat(self):
429 support.unlink(support.TESTFN)
430 open(support.TESTFN, 'w').close()
431
432 f = posix.open(posix.getcwd(), posix.O_RDONLY)
433 try:
434 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
435 finally:
436 posix.close(f)
437
438 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
439 def test_fstatat(self):
440 support.unlink(support.TESTFN)
441 with open(support.TESTFN, 'w') as outfile:
442 outfile.write("testline\n")
443
444 f = posix.open(posix.getcwd(), posix.O_RDONLY)
445 try:
446 s1 = posix.stat(support.TESTFN)
447 s2 = posix.fstatat(f, support.TESTFN)
448 self.assertEqual(s1, s2)
449 finally:
450 posix.close(f)
451
452 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
453 def test_futimesat(self):
454 f = posix.open(posix.getcwd(), posix.O_RDONLY)
455 try:
456 now = time.time()
457 posix.futimesat(f, support.TESTFN, None)
458 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
459 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
460 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
461 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
462 posix.futimesat(f, support.TESTFN, (now, now))
463 finally:
464 posix.close(f)
465
466 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
467 def test_linkat(self):
468 f = posix.open(posix.getcwd(), posix.O_RDONLY)
469 try:
470 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
471 # should have same inodes
472 self.assertEqual(posix.stat(support.TESTFN)[1],
473 posix.stat(support.TESTFN + 'link')[1])
474 finally:
475 posix.close(f)
476 support.unlink(support.TESTFN + 'link')
477
478 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
479 def test_mkdirat(self):
480 f = posix.open(posix.getcwd(), posix.O_RDONLY)
481 try:
482 posix.mkdirat(f, support.TESTFN + 'dir')
483 posix.stat(support.TESTFN + 'dir') # should not raise exception
484 finally:
485 posix.close(f)
486 support.rmtree(support.TESTFN + 'dir')
487
488 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
489 "don't have mknodat()/S_IFIFO")
490 def test_mknodat(self):
491 # Test using mknodat() to create a FIFO (the only use specified
492 # by POSIX).
493 support.unlink(support.TESTFN)
494 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
495 f = posix.open(posix.getcwd(), posix.O_RDONLY)
496 try:
497 posix.mknodat(f, support.TESTFN, mode, 0)
498 except OSError as e:
499 # Some old systems don't allow unprivileged users to use
500 # mknod(), or only support creating device nodes.
501 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
502 else:
503 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
504 finally:
505 posix.close(f)
506
507 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
508 def test_openat(self):
509 support.unlink(support.TESTFN)
510 with open(support.TESTFN, 'w') as outfile:
511 outfile.write("testline\n")
512 a = posix.open(posix.getcwd(), posix.O_RDONLY)
513 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
514 try:
515 res = posix.read(b, 9).decode(encoding="utf-8")
516 self.assertEqual("testline\n", res)
517 finally:
518 posix.close(a)
519 posix.close(b)
520
521 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
522 def test_readlinkat(self):
523 os.symlink(support.TESTFN, support.TESTFN + 'link')
524 f = posix.open(posix.getcwd(), posix.O_RDONLY)
525 try:
526 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
527 posix.readlinkat(f, support.TESTFN + 'link'))
528 finally:
529 support.unlink(support.TESTFN + 'link')
530 posix.close(f)
531
532 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
533 def test_renameat(self):
534 support.unlink(support.TESTFN)
535 open(support.TESTFN + 'ren', 'w').close()
536 f = posix.open(posix.getcwd(), posix.O_RDONLY)
537 try:
538 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
539 except:
540 posix.rename(support.TESTFN + 'ren', support.TESTFN)
541 raise
542 else:
543 posix.stat(support.TESTFN) # should not throw exception
544 finally:
545 posix.close(f)
546
547 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
548 def test_symlinkat(self):
549 f = posix.open(posix.getcwd(), posix.O_RDONLY)
550 try:
551 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
552 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
553 finally:
554 posix.close(f)
555 support.unlink(support.TESTFN + 'link')
556
557 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
558 def test_unlinkat(self):
559 f = posix.open(posix.getcwd(), posix.O_RDONLY)
560 open(support.TESTFN + 'del', 'w').close()
561 posix.stat(support.TESTFN + 'del') # should not throw exception
562 try:
563 posix.unlinkat(f, support.TESTFN + 'del')
564 except:
565 support.unlink(support.TESTFN + 'del')
566 raise
567 else:
568 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
569 finally:
570 posix.close(f)
571
572 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
573 def test_utimensat(self):
574 f = posix.open(posix.getcwd(), posix.O_RDONLY)
575 try:
576 now = time.time()
577 posix.utimensat(f, support.TESTFN, None, None)
578 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
579 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
580 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
581 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
582 (int(now), int((now - int(now)) * 1e9)))
583 finally:
584 posix.close(f)
585
586 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
587 def test_mkfifoat(self):
588 support.unlink(support.TESTFN)
589 f = posix.open(posix.getcwd(), posix.O_RDONLY)
590 try:
591 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
592 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
593 finally:
594 posix.close(f)
595
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000596class PosixGroupsTester(unittest.TestCase):
597
598 def setUp(self):
599 if posix.getuid() != 0:
600 raise unittest.SkipTest("not enough privileges")
601 if not hasattr(posix, 'getgroups'):
602 raise unittest.SkipTest("need posix.getgroups")
603 if sys.platform == 'darwin':
604 raise unittest.SkipTest("getgroups(2) is broken on OSX")
605 self.saved_groups = posix.getgroups()
606
607 def tearDown(self):
608 if hasattr(posix, 'setgroups'):
609 posix.setgroups(self.saved_groups)
610 elif hasattr(posix, 'initgroups'):
611 name = pwd.getpwuid(posix.getuid()).pw_name
612 posix.initgroups(name, self.saved_groups[0])
613
614 @unittest.skipUnless(hasattr(posix, 'initgroups'),
615 "test needs posix.initgroups()")
616 def test_initgroups(self):
617 # find missing group
618
Antoine Pitroue5a91012010-09-04 17:32:06 +0000619 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000620 name = pwd.getpwuid(posix.getuid()).pw_name
621 posix.initgroups(name, g)
622 self.assertIn(g, posix.getgroups())
623
624 @unittest.skipUnless(hasattr(posix, 'setgroups'),
625 "test needs posix.setgroups()")
626 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000627 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000628 posix.setgroups(groups)
629 self.assertListEqual(groups, posix.getgroups())
630
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000631
Neal Norwitze241ce82003-02-17 18:17:05 +0000632def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000633 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000634
635if __name__ == '__main__':
636 test_main()