blob: 2fb8200e62a257645fe9710e8f7bf6918f42c826 [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
288 def test_access(self):
289 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000290 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000291
292 def test_umask(self):
293 if hasattr(posix, 'umask'):
294 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000295 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000296 posix.umask(old_mask)
297
298 def test_strerror(self):
299 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000300 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000301
302 def test_pipe(self):
303 if hasattr(posix, 'pipe'):
304 reader, writer = posix.pipe()
305 os.close(reader)
306 os.close(writer)
307
Neal Norwitze241ce82003-02-17 18:17:05 +0000308 def test_utime(self):
309 if hasattr(posix, 'utime'):
310 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000311 posix.utime(support.TESTFN, None)
312 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
313 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
314 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
315 posix.utime(support.TESTFN, (int(now), int(now)))
316 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000317
Thomas Wouterscf297e42007-02-23 15:07:44 +0000318 def test_chflags(self):
319 if hasattr(posix, 'chflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000320 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000321 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000322 posix.chflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000323
324 def test_lchflags(self):
325 if hasattr(posix, 'lchflags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000326 st = os.stat(support.TESTFN)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000327 if hasattr(st, 'st_flags'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000328 posix.lchflags(support.TESTFN, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000329
Guido van Rossum98297ee2007-11-06 21:34:58 +0000330 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000331 if os.name == "nt":
332 item_type = str
333 else:
334 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000335 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000336 self.assertEqual(type(k), item_type)
337 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000338
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000339 def test_getcwd_long_pathnames(self):
340 if hasattr(posix, 'getcwd'):
341 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
342 curdir = os.getcwd()
343 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
344
345 try:
346 os.mkdir(base_path)
347 os.chdir(base_path)
348 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000349# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000350# because the test results in Error in that case.
351# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000352# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000353 return
354
355 def _create_and_do_getcwd(dirname, current_path_length = 0):
356 try:
357 os.mkdir(dirname)
358 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000359 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000360
361 os.chdir(dirname)
362 try:
363 os.getcwd()
364 if current_path_length < 1027:
365 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
366 finally:
367 os.chdir('..')
368 os.rmdir(dirname)
369
370 _create_and_do_getcwd(dirname)
371
372 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000373 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000374 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000375
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000376 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000377 def test_getgroups(self):
378 with os.popen('id -G') as idg:
379 groups = idg.read().strip()
380
381 if not groups:
382 raise unittest.SkipTest("need working 'id -G'")
383
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000384 # 'id -G' and 'os.getgroups()' should return the same
385 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000386 # #10822 - it is implementation defined whether posix.getgroups()
387 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000388 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000389 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000390 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000391
Antoine Pitrouf65132d2011-02-25 23:25:17 +0000392 # tests for the posix *at functions follow
393
394 @unittest.skipUnless(hasattr(posix, 'faccessat'), "test needs posix.faccessat()")
395 def test_faccessat(self):
396 f = posix.open(posix.getcwd(), posix.O_RDONLY)
397 try:
398 self.assertTrue(posix.faccessat(f, support.TESTFN, os.R_OK))
399 finally:
400 posix.close(f)
401
402 @unittest.skipUnless(hasattr(posix, 'fchmodat'), "test needs posix.fchmodat()")
403 def test_fchmodat(self):
404 os.chmod(support.TESTFN, stat.S_IRUSR)
405
406 f = posix.open(posix.getcwd(), posix.O_RDONLY)
407 try:
408 posix.fchmodat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
409
410 s = posix.stat(support.TESTFN)
411 self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR)
412 finally:
413 posix.close(f)
414
415 @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()")
416 def test_fchownat(self):
417 support.unlink(support.TESTFN)
418 open(support.TESTFN, 'w').close()
419
420 f = posix.open(posix.getcwd(), posix.O_RDONLY)
421 try:
422 posix.fchownat(f, support.TESTFN, os.getuid(), os.getgid())
423 finally:
424 posix.close(f)
425
426 @unittest.skipUnless(hasattr(posix, 'fstatat'), "test needs posix.fstatat()")
427 def test_fstatat(self):
428 support.unlink(support.TESTFN)
429 with open(support.TESTFN, 'w') as outfile:
430 outfile.write("testline\n")
431
432 f = posix.open(posix.getcwd(), posix.O_RDONLY)
433 try:
434 s1 = posix.stat(support.TESTFN)
435 s2 = posix.fstatat(f, support.TESTFN)
436 self.assertEqual(s1, s2)
437 finally:
438 posix.close(f)
439
440 @unittest.skipUnless(hasattr(posix, 'futimesat'), "test needs posix.futimesat()")
441 def test_futimesat(self):
442 f = posix.open(posix.getcwd(), posix.O_RDONLY)
443 try:
444 now = time.time()
445 posix.futimesat(f, support.TESTFN, None)
446 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, None))
447 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (now, None))
448 self.assertRaises(TypeError, posix.futimesat, f, support.TESTFN, (None, now))
449 posix.futimesat(f, support.TESTFN, (int(now), int(now)))
450 posix.futimesat(f, support.TESTFN, (now, now))
451 finally:
452 posix.close(f)
453
454 @unittest.skipUnless(hasattr(posix, 'linkat'), "test needs posix.linkat()")
455 def test_linkat(self):
456 f = posix.open(posix.getcwd(), posix.O_RDONLY)
457 try:
458 posix.linkat(f, support.TESTFN, f, support.TESTFN + 'link')
459 # should have same inodes
460 self.assertEqual(posix.stat(support.TESTFN)[1],
461 posix.stat(support.TESTFN + 'link')[1])
462 finally:
463 posix.close(f)
464 support.unlink(support.TESTFN + 'link')
465
466 @unittest.skipUnless(hasattr(posix, 'mkdirat'), "test needs posix.mkdirat()")
467 def test_mkdirat(self):
468 f = posix.open(posix.getcwd(), posix.O_RDONLY)
469 try:
470 posix.mkdirat(f, support.TESTFN + 'dir')
471 posix.stat(support.TESTFN + 'dir') # should not raise exception
472 finally:
473 posix.close(f)
474 support.rmtree(support.TESTFN + 'dir')
475
476 @unittest.skipUnless(hasattr(posix, 'mknodat') and hasattr(stat, 'S_IFIFO'),
477 "don't have mknodat()/S_IFIFO")
478 def test_mknodat(self):
479 # Test using mknodat() to create a FIFO (the only use specified
480 # by POSIX).
481 support.unlink(support.TESTFN)
482 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
483 f = posix.open(posix.getcwd(), posix.O_RDONLY)
484 try:
485 posix.mknodat(f, support.TESTFN, mode, 0)
486 except OSError as e:
487 # Some old systems don't allow unprivileged users to use
488 # mknod(), or only support creating device nodes.
489 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
490 else:
491 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
492 finally:
493 posix.close(f)
494
495 @unittest.skipUnless(hasattr(posix, 'openat'), "test needs posix.openat()")
496 def test_openat(self):
497 support.unlink(support.TESTFN)
498 with open(support.TESTFN, 'w') as outfile:
499 outfile.write("testline\n")
500 a = posix.open(posix.getcwd(), posix.O_RDONLY)
501 b = posix.openat(a, support.TESTFN, posix.O_RDONLY)
502 try:
503 res = posix.read(b, 9).decode(encoding="utf-8")
504 self.assertEqual("testline\n", res)
505 finally:
506 posix.close(a)
507 posix.close(b)
508
509 @unittest.skipUnless(hasattr(posix, 'readlinkat'), "test needs posix.readlinkat()")
510 def test_readlinkat(self):
511 os.symlink(support.TESTFN, support.TESTFN + 'link')
512 f = posix.open(posix.getcwd(), posix.O_RDONLY)
513 try:
514 self.assertEqual(posix.readlink(support.TESTFN + 'link'),
515 posix.readlinkat(f, support.TESTFN + 'link'))
516 finally:
517 support.unlink(support.TESTFN + 'link')
518 posix.close(f)
519
520 @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()")
521 def test_renameat(self):
522 support.unlink(support.TESTFN)
523 open(support.TESTFN + 'ren', 'w').close()
524 f = posix.open(posix.getcwd(), posix.O_RDONLY)
525 try:
526 posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN)
527 except:
528 posix.rename(support.TESTFN + 'ren', support.TESTFN)
529 raise
530 else:
531 posix.stat(support.TESTFN) # should not throw exception
532 finally:
533 posix.close(f)
534
535 @unittest.skipUnless(hasattr(posix, 'symlinkat'), "test needs posix.symlinkat()")
536 def test_symlinkat(self):
537 f = posix.open(posix.getcwd(), posix.O_RDONLY)
538 try:
539 posix.symlinkat(support.TESTFN, f, support.TESTFN + 'link')
540 self.assertEqual(posix.readlink(support.TESTFN + 'link'), support.TESTFN)
541 finally:
542 posix.close(f)
543 support.unlink(support.TESTFN + 'link')
544
545 @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()")
546 def test_unlinkat(self):
547 f = posix.open(posix.getcwd(), posix.O_RDONLY)
548 open(support.TESTFN + 'del', 'w').close()
549 posix.stat(support.TESTFN + 'del') # should not throw exception
550 try:
551 posix.unlinkat(f, support.TESTFN + 'del')
552 except:
553 support.unlink(support.TESTFN + 'del')
554 raise
555 else:
556 self.assertRaises(OSError, posix.stat, support.TESTFN + 'link')
557 finally:
558 posix.close(f)
559
560 @unittest.skipUnless(hasattr(posix, 'utimensat'), "test needs posix.utimensat()")
561 def test_utimensat(self):
562 f = posix.open(posix.getcwd(), posix.O_RDONLY)
563 try:
564 now = time.time()
565 posix.utimensat(f, support.TESTFN, None, None)
566 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
567 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
568 self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
569 posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
570 (int(now), int((now - int(now)) * 1e9)))
571 finally:
572 posix.close(f)
573
574 @unittest.skipUnless(hasattr(posix, 'mkfifoat'), "don't have mkfifoat()")
575 def test_mkfifoat(self):
576 support.unlink(support.TESTFN)
577 f = posix.open(posix.getcwd(), posix.O_RDONLY)
578 try:
579 posix.mkfifoat(f, support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
580 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
581 finally:
582 posix.close(f)
583
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000584class PosixGroupsTester(unittest.TestCase):
585
586 def setUp(self):
587 if posix.getuid() != 0:
588 raise unittest.SkipTest("not enough privileges")
589 if not hasattr(posix, 'getgroups'):
590 raise unittest.SkipTest("need posix.getgroups")
591 if sys.platform == 'darwin':
592 raise unittest.SkipTest("getgroups(2) is broken on OSX")
593 self.saved_groups = posix.getgroups()
594
595 def tearDown(self):
596 if hasattr(posix, 'setgroups'):
597 posix.setgroups(self.saved_groups)
598 elif hasattr(posix, 'initgroups'):
599 name = pwd.getpwuid(posix.getuid()).pw_name
600 posix.initgroups(name, self.saved_groups[0])
601
602 @unittest.skipUnless(hasattr(posix, 'initgroups'),
603 "test needs posix.initgroups()")
604 def test_initgroups(self):
605 # find missing group
606
Antoine Pitroue5a91012010-09-04 17:32:06 +0000607 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000608 name = pwd.getpwuid(posix.getuid()).pw_name
609 posix.initgroups(name, g)
610 self.assertIn(g, posix.getgroups())
611
612 @unittest.skipUnless(hasattr(posix, 'setgroups'),
613 "test needs posix.setgroups()")
614 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000615 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000616 posix.setgroups(groups)
617 self.assertListEqual(groups, posix.getgroups())
618
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000619
Neal Norwitze241ce82003-02-17 18:17:05 +0000620def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000621 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000622
623if __name__ == '__main__':
624 test_main()