blob: 5a26d649d38f0237daccd27a1b9d9956b9289b1f [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 Nataliab2d58e2012-04-17 19:48:35 +020012import platform
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
Ned Deilyba2eab22011-07-26 13:53:55 -070016import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000017import unittest
18import warnings
R. David Murraya21e4ca2009-03-31 23:16:50 +000019
Ned Deilyba2eab22011-07-26 13:53:55 -070020_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
21 support.TESTFN + '-dummy-symlink')
Neal Norwitze241ce82003-02-17 18:17:05 +000022
23class PosixTester(unittest.TestCase):
24
25 def setUp(self):
26 # create empty file
Benjamin Petersonee8712c2008-05-20 21:35:26 +000027 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000028 fp.close()
Ned Deily3eb67d52011-06-28 00:00:28 -070029 self.teardown_files = [ support.TESTFN ]
Brett Cannonc8d502e2010-03-20 21:53:28 +000030 self._warnings_manager = support.check_warnings()
31 self._warnings_manager.__enter__()
32 warnings.filterwarnings('ignore', '.* potential security risk .*',
33 RuntimeWarning)
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily3eb67d52011-06-28 00:00:28 -070036 for teardown_file in self.teardown_files:
37 support.unlink(teardown_file)
Brett Cannonc8d502e2010-03-20 21:53:28 +000038 self._warnings_manager.__exit__(None, None, None)
Neal Norwitze241ce82003-02-17 18:17:05 +000039
40 def testNoArgFunctions(self):
41 # test posix functions which take no arguments and have
42 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
Guido van Rossumf0af3e32008-10-02 18:55:37 +000043 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdb", "uname",
Guido van Rossum687b9c02007-10-25 23:18:51 +000044 "times", "getloadavg",
Neal Norwitze241ce82003-02-17 18:17:05 +000045 "getegid", "geteuid", "getgid", "getgroups",
46 "getpid", "getpgrp", "getppid", "getuid",
47 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000048
Neal Norwitze241ce82003-02-17 18:17:05 +000049 for name in NO_ARG_FUNCTIONS:
50 posix_func = getattr(posix, name, None)
51 if posix_func is not None:
52 posix_func()
Neal Norwitz2ff51a82003-02-17 22:40:31 +000053 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000054
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000055 if hasattr(posix, 'getresuid'):
56 def test_getresuid(self):
57 user_ids = posix.getresuid()
58 self.assertEqual(len(user_ids), 3)
59 for val in user_ids:
60 self.assertGreaterEqual(val, 0)
61
62 if hasattr(posix, 'getresgid'):
63 def test_getresgid(self):
64 group_ids = posix.getresgid()
65 self.assertEqual(len(group_ids), 3)
66 for val in group_ids:
67 self.assertGreaterEqual(val, 0)
68
69 if hasattr(posix, 'setresuid'):
70 def test_setresuid(self):
71 current_user_ids = posix.getresuid()
72 self.assertIsNone(posix.setresuid(*current_user_ids))
73 # -1 means don't change that value.
74 self.assertIsNone(posix.setresuid(-1, -1, -1))
75
76 def test_setresuid_exception(self):
77 # Don't do this test if someone is silly enough to run us as root.
78 current_user_ids = posix.getresuid()
79 if 0 not in current_user_ids:
80 new_user_ids = (current_user_ids[0]+1, -1, -1)
81 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
82
83 if hasattr(posix, 'setresgid'):
84 def test_setresgid(self):
85 current_group_ids = posix.getresgid()
86 self.assertIsNone(posix.setresgid(*current_group_ids))
87 # -1 means don't change that value.
88 self.assertIsNone(posix.setresgid(-1, -1, -1))
89
90 def test_setresgid_exception(self):
91 # Don't do this test if someone is silly enough to run us as root.
92 current_group_ids = posix.getresgid()
93 if 0 not in current_group_ids:
94 new_group_ids = (current_group_ids[0]+1, -1, -1)
95 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
96
Antoine Pitroub7572f02009-12-02 20:46:48 +000097 @unittest.skipUnless(hasattr(posix, 'initgroups'),
98 "test needs os.initgroups()")
99 def test_initgroups(self):
100 # It takes a string and an integer; check that it raises a TypeError
101 # for other argument lists.
102 self.assertRaises(TypeError, posix.initgroups)
103 self.assertRaises(TypeError, posix.initgroups, None)
104 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
105 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
106
107 # If a non-privileged user invokes it, it should fail with OSError
108 # EPERM.
109 if os.getuid() != 0:
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200110 try:
111 name = pwd.getpwuid(posix.getuid()).pw_name
112 except KeyError:
113 # the current UID may not have a pwd entry
114 raise unittest.SkipTest("need a pwd entry")
Antoine Pitroub7572f02009-12-02 20:46:48 +0000115 try:
116 posix.initgroups(name, 13)
117 except OSError as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000118 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitroub7572f02009-12-02 20:46:48 +0000119 else:
120 self.fail("Expected OSError to be raised by initgroups")
121
Neal Norwitze241ce82003-02-17 18:17:05 +0000122 def test_statvfs(self):
123 if hasattr(posix, 'statvfs'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000124 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000125
126 def test_fstatvfs(self):
127 if hasattr(posix, 'fstatvfs'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000128 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000129 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000130 self.assertTrue(posix.fstatvfs(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000131 finally:
132 fp.close()
133
134 def test_ftruncate(self):
135 if hasattr(posix, 'ftruncate'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000136 fp = open(support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +0000137 try:
138 # we need to have some data to truncate
139 fp.write('test')
140 fp.flush()
141 posix.ftruncate(fp.fileno(), 0)
142 finally:
143 fp.close()
144
145 def test_dup(self):
146 if hasattr(posix, 'dup'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000147 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000148 try:
149 fd = posix.dup(fp.fileno())
Ezio Melottie9615932010-01-24 19:26:24 +0000150 self.assertIsInstance(fd, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000151 os.close(fd)
152 finally:
153 fp.close()
154
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000155 def test_confstr(self):
156 if hasattr(posix, 'confstr'):
157 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
158 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
159
Neal Norwitze241ce82003-02-17 18:17:05 +0000160 def test_dup2(self):
161 if hasattr(posix, 'dup2'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000162 fp1 = open(support.TESTFN)
163 fp2 = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000164 try:
165 posix.dup2(fp1.fileno(), fp2.fileno())
166 finally:
167 fp1.close()
168 fp2.close()
169
Skip Montanaro98470002005-06-17 01:14:49 +0000170 def test_osexlock(self):
171 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000172 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000173 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000174 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000175 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
176 os.close(fd)
177
178 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000180 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000181 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000182 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
183 os.close(fd)
184
185 def test_osshlock(self):
186 if hasattr(posix, "O_SHLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000187 fd1 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000188 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000189 fd2 = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000190 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
191 os.close(fd2)
192 os.close(fd1)
193
194 if hasattr(posix, "O_EXLOCK"):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000195 fd = os.open(support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000196 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000197 self.assertRaises(OSError, os.open, support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000198 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
199 os.close(fd)
200
Neal Norwitze241ce82003-02-17 18:17:05 +0000201 def test_fstat(self):
202 if hasattr(posix, 'fstat'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000203 fp = open(support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000204 try:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000205 self.assertTrue(posix.fstat(fp.fileno()))
Neal Norwitze241ce82003-02-17 18:17:05 +0000206 finally:
207 fp.close()
208
209 def test_stat(self):
210 if hasattr(posix, 'stat'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000211 self.assertTrue(posix.stat(support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000212
Benjamin Peterson052a02b2010-08-17 01:27:09 +0000213 @unittest.skipUnless(hasattr(posix, 'mkfifo'), "don't have mkfifo()")
214 def test_mkfifo(self):
215 support.unlink(support.TESTFN)
216 posix.mkfifo(support.TESTFN, stat.S_IRUSR | stat.S_IWUSR)
217 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
218
219 @unittest.skipUnless(hasattr(posix, 'mknod') and hasattr(stat, 'S_IFIFO'),
220 "don't have mknod()/S_IFIFO")
221 def test_mknod(self):
222 # Test using mknod() to create a FIFO (the only use specified
223 # by POSIX).
224 support.unlink(support.TESTFN)
225 mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR
226 try:
227 posix.mknod(support.TESTFN, mode, 0)
228 except OSError as e:
229 # Some old systems don't allow unprivileged users to use
230 # mknod(), or only support creating device nodes.
231 self.assertIn(e.errno, (errno.EPERM, errno.EINVAL))
232 else:
233 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
234
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200235 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000236 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200237 def check_stat(uid, gid):
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200238 if stat_func is not None:
239 stat = stat_func(first_param)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200240 self.assertEqual(stat.st_uid, uid)
241 self.assertEqual(stat.st_gid, gid)
242 uid = os.getuid()
243 gid = os.getgid()
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200244 # test a successful chown call
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200245 chown_func(first_param, uid, gid)
246 check_stat(uid, gid)
247 chown_func(first_param, -1, gid)
248 check_stat(uid, gid)
249 chown_func(first_param, uid, -1)
250 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200251
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200252 if uid == 0:
253 # Try an amusingly large uid/gid to make sure we handle
254 # large unsigned values. (chown lets you use any
255 # uid/gid you like, even if they aren't defined.)
256 #
257 # This problem keeps coming up:
258 # http://bugs.python.org/issue1747858
259 # http://bugs.python.org/issue4591
260 # http://bugs.python.org/issue15301
261 # Hopefully the fix in 4591 fixes it for good!
262 #
263 # This part of the test only runs when run as root.
264 # Only scary people run their tests as root.
265
266 big_value = 2**31
267 chown_func(first_param, big_value, big_value)
268 check_stat(big_value, big_value)
269 chown_func(first_param, -1, -1)
270 check_stat(big_value, big_value)
271 chown_func(first_param, uid, gid)
272 check_stat(uid, gid)
Charles-François Nataliab2d58e2012-04-17 19:48:35 +0200273 elif platform.system() in ('HP-UX', 'SunOS'):
274 # HP-UX and Solaris can allow a non-root user to chown() to root
275 # (issue #5113)
276 raise unittest.SkipTest("Skipping because of non-standard chown() "
277 "behavior")
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000278 else:
279 # non-root cannot chown to root, raises OSError
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200280 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200281 check_stat(uid, gid)
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200282 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200283 check_stat(uid, gid)
Serhiy Storchakab3d62ce2013-02-20 19:48:22 +0200284 if gid != 0:
285 self.assertRaises(OSError, chown_func, first_param, -1, 0)
286 check_stat(uid, gid)
Serhiy Storchaka54db2fd2013-02-20 19:40:25 +0200287 # test illegal types
288 for t in str, float:
289 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
290 check_stat(uid, gid)
291 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
292 check_stat(uid, gid)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000293
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000294 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
295 def test_chown(self):
296 # raise an OSError if the file does not exist
297 os.unlink(support.TESTFN)
298 self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1)
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000299
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000300 # re-create the file
301 open(support.TESTFN, 'w').close()
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200302 self._test_all_chown_common(posix.chown, support.TESTFN,
303 getattr(posix, 'stat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000304
305 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
306 def test_fchown(self):
307 os.unlink(support.TESTFN)
308
309 # re-create the file
310 test_file = open(support.TESTFN, 'w')
311 try:
312 fd = test_file.fileno()
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200313 self._test_all_chown_common(posix.fchown, fd,
314 getattr(posix, 'fstat', None))
Benjamin Peterson1baf4652009-12-31 03:11:23 +0000315 finally:
316 test_file.close()
317
318 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
319 def test_lchown(self):
320 os.unlink(support.TESTFN)
321 # create a symlink
Ned Deily3eb67d52011-06-28 00:00:28 -0700322 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
Serhiy Storchakae4ad8aa2013-02-12 09:24:16 +0200323 self._test_all_chown_common(posix.lchown, support.TESTFN,
324 getattr(posix, 'lstat', None))
Christian Heimesd5e2b6f2008-03-19 21:50:51 +0000325
Neal Norwitze241ce82003-02-17 18:17:05 +0000326 def test_chdir(self):
327 if hasattr(posix, 'chdir'):
328 posix.chdir(os.curdir)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000329 self.assertRaises(OSError, posix.chdir, support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000330
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +0000331 def test_listdir(self):
332 if hasattr(posix, 'listdir'):
333 self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
334
335 def test_listdir_default(self):
336 # When listdir is called without argument, it's the same as listdir(os.curdir)
337 if hasattr(posix, 'listdir'):
338 self.assertTrue(support.TESTFN in posix.listdir())
Neal Norwitze241ce82003-02-17 18:17:05 +0000339
340 def test_access(self):
341 if hasattr(posix, 'access'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000342 self.assertTrue(posix.access(support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000343
344 def test_umask(self):
345 if hasattr(posix, 'umask'):
346 old_mask = posix.umask(0)
Ezio Melottie9615932010-01-24 19:26:24 +0000347 self.assertIsInstance(old_mask, int)
Neal Norwitze241ce82003-02-17 18:17:05 +0000348 posix.umask(old_mask)
349
350 def test_strerror(self):
351 if hasattr(posix, 'strerror'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000352 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000353
354 def test_pipe(self):
355 if hasattr(posix, 'pipe'):
356 reader, writer = posix.pipe()
357 os.close(reader)
358 os.close(writer)
359
Neal Norwitze241ce82003-02-17 18:17:05 +0000360 def test_utime(self):
361 if hasattr(posix, 'utime'):
362 now = time.time()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000363 posix.utime(support.TESTFN, None)
364 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, None))
365 self.assertRaises(TypeError, posix.utime, support.TESTFN, (now, None))
366 self.assertRaises(TypeError, posix.utime, support.TESTFN, (None, now))
367 posix.utime(support.TESTFN, (int(now), int(now)))
368 posix.utime(support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000369
Ned Deily3eb67d52011-06-28 00:00:28 -0700370 def _test_chflags_regular_file(self, chflags_func, target_file):
371 st = os.stat(target_file)
372 self.assertTrue(hasattr(st, 'st_flags'))
Trent Nelsonee253eb2012-08-21 23:41:43 +0000373
374 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
375 try:
376 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
377 except OSError as err:
378 if err.errno != errno.EOPNOTSUPP:
379 raise
380 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
381 self.skipTest(msg)
382
Ned Deily3eb67d52011-06-28 00:00:28 -0700383 try:
384 new_st = os.stat(target_file)
385 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
386 try:
387 fd = open(target_file, 'w+')
388 except IOError as e:
389 self.assertEqual(e.errno, errno.EPERM)
390 finally:
391 posix.chflags(target_file, st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000392
Ned Deily3eb67d52011-06-28 00:00:28 -0700393 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
394 def test_chflags(self):
395 self._test_chflags_regular_file(posix.chflags, support.TESTFN)
396
397 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
398 def test_lchflags_regular_file(self):
399 self._test_chflags_regular_file(posix.lchflags, support.TESTFN)
400
401 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
402 def test_lchflags_symlink(self):
403 testfn_st = os.stat(support.TESTFN)
404
405 self.assertTrue(hasattr(testfn_st, 'st_flags'))
406
407 os.symlink(support.TESTFN, _DUMMY_SYMLINK)
408 self.teardown_files.append(_DUMMY_SYMLINK)
409 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
410
Trent Nelsonee253eb2012-08-21 23:41:43 +0000411 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
412 try:
413 posix.lchflags(_DUMMY_SYMLINK,
414 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
415 except OSError as err:
416 if err.errno != errno.EOPNOTSUPP:
417 raise
418 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
419 self.skipTest(msg)
420
Ned Deily3eb67d52011-06-28 00:00:28 -0700421 try:
422 new_testfn_st = os.stat(support.TESTFN)
423 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
424
425 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
426 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
427 new_dummy_symlink_st.st_flags)
428 finally:
429 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Thomas Wouterscf297e42007-02-23 15:07:44 +0000430
Guido van Rossum98297ee2007-11-06 21:34:58 +0000431 def test_environ(self):
Victor Stinner17b490d2010-05-06 22:19:30 +0000432 if os.name == "nt":
433 item_type = str
434 else:
435 item_type = bytes
Guido van Rossum98297ee2007-11-06 21:34:58 +0000436 for k, v in posix.environ.items():
Victor Stinner17b490d2010-05-06 22:19:30 +0000437 self.assertEqual(type(k), item_type)
438 self.assertEqual(type(v), item_type)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000439
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000440 def test_getcwd_long_pathnames(self):
441 if hasattr(posix, 'getcwd'):
442 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
443 curdir = os.getcwd()
444 base_path = os.path.abspath(support.TESTFN) + '.getcwd'
445
446 try:
447 os.mkdir(base_path)
448 os.chdir(base_path)
449 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000450# Just returning nothing instead of the SkipTest exception,
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000451# because the test results in Error in that case.
452# Is that ok?
Benjamin Petersone549ead2009-03-28 21:42:05 +0000453# raise unittest.SkipTest("cannot create directory for testing")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000454 return
455
456 def _create_and_do_getcwd(dirname, current_path_length = 0):
457 try:
458 os.mkdir(dirname)
459 except:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000460 raise unittest.SkipTest("mkdir cannot create directory sufficiently deep for getcwd test")
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000461
462 os.chdir(dirname)
463 try:
464 os.getcwd()
465 if current_path_length < 1027:
466 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
467 finally:
468 os.chdir('..')
469 os.rmdir(dirname)
470
471 _create_and_do_getcwd(dirname)
472
473 finally:
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000474 os.chdir(curdir)
R. David Murray414c91f2009-07-09 20:12:31 +0000475 support.rmtree(base_path)
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000476
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000477 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000478 def test_getgroups(self):
479 with os.popen('id -G') as idg:
480 groups = idg.read().strip()
Charles-François Natalie8a255a2012-05-02 20:01:38 +0200481 ret = idg.close()
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000482
Charles-François Natali39687ee2012-05-02 20:49:14 +0200483 if ret != None or not groups:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000484 raise unittest.SkipTest("need working 'id -G'")
485
Ned Deily028915e2013-02-02 15:08:52 -0800486 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
487 if sys.platform == 'darwin':
488 import sysconfig
489 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
490 if float(dt) < 10.6:
491 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
492
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000493 # 'id -G' and 'os.getgroups()' should return the same
494 # groups, ignoring order and duplicates.
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000495 # #10822 - it is implementation defined whether posix.getgroups()
496 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussorencb615e62010-07-24 14:15:19 +0000497 self.assertEqual(
Ronald Oussoren7fb6f512010-08-01 19:18:13 +0000498 set([int(x) for x in groups.split()]),
Antoine Pitrou318b8f32011-01-12 18:45:27 +0000499 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000500
501class PosixGroupsTester(unittest.TestCase):
502
503 def setUp(self):
504 if posix.getuid() != 0:
505 raise unittest.SkipTest("not enough privileges")
506 if not hasattr(posix, 'getgroups'):
507 raise unittest.SkipTest("need posix.getgroups")
508 if sys.platform == 'darwin':
509 raise unittest.SkipTest("getgroups(2) is broken on OSX")
510 self.saved_groups = posix.getgroups()
511
512 def tearDown(self):
513 if hasattr(posix, 'setgroups'):
514 posix.setgroups(self.saved_groups)
515 elif hasattr(posix, 'initgroups'):
516 name = pwd.getpwuid(posix.getuid()).pw_name
517 posix.initgroups(name, self.saved_groups[0])
518
519 @unittest.skipUnless(hasattr(posix, 'initgroups'),
520 "test needs posix.initgroups()")
521 def test_initgroups(self):
522 # find missing group
523
Antoine Pitroue5a91012010-09-04 17:32:06 +0000524 g = max(self.saved_groups) + 1
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000525 name = pwd.getpwuid(posix.getuid()).pw_name
526 posix.initgroups(name, g)
527 self.assertIn(g, posix.getgroups())
528
529 @unittest.skipUnless(hasattr(posix, 'setgroups'),
530 "test needs posix.setgroups()")
531 def test_setgroups(self):
Antoine Pitroue5a91012010-09-04 17:32:06 +0000532 for groups in [[0], list(range(16))]:
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000533 posix.setgroups(groups)
534 self.assertListEqual(groups, posix.getgroups())
535
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000536
Neal Norwitze241ce82003-02-17 18:17:05 +0000537def test_main():
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +0000538 support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000539
540if __name__ == '__main__':
541 test_main()