blob: c4283b604b96ab4fba05291413a956dea36de17a [file] [log] [blame]
Neal Norwitze241ce82003-02-17 18:17:05 +00001"Test posix functions"
2
Walter Dörwald21d3a322003-05-01 17:45:56 +00003from test import test_support
Neal Norwitze241ce82003-02-17 18:17:05 +00004
R. David Murray95fb46c2009-04-21 13:06:04 +00005# Skip these tests if there is no posix module.
6posix = test_support.import_module('posix')
Neal Norwitze241ce82003-02-17 18:17:05 +00007
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008import errno
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00009import sys
Neal Norwitze241ce82003-02-17 18:17:05 +000010import time
11import os
Charles-François Natalif8387642012-04-17 19:46:06 +020012import platform
Gregory P. Smithf48da8f2008-03-18 19:05:32 +000013import pwd
Facundo Batista5596b0c2008-06-22 13:36:20 +000014import shutil
Ned Deily43e10542011-06-27 23:41:53 -070015import stat
Stefan Krah182ae642010-07-13 19:17:08 +000016import sys
Ned Deilyd88131a2011-07-26 13:52:14 -070017import tempfile
Neal Norwitze241ce82003-02-17 18:17:05 +000018import unittest
19import warnings
R. David Murray59beec32009-03-30 19:04:00 +000020
Ned Deilyd88131a2011-07-26 13:52:14 -070021_DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(),
22 test_support.TESTFN + '-dummy-symlink')
R. David Murray59beec32009-03-30 19:04:00 +000023
Neal Norwitze241ce82003-02-17 18:17:05 +000024warnings.filterwarnings('ignore', '.* potential security risk .*',
25 RuntimeWarning)
26
27class PosixTester(unittest.TestCase):
28
29 def setUp(self):
30 # create empty file
Walter Dörwald21d3a322003-05-01 17:45:56 +000031 fp = open(test_support.TESTFN, 'w+')
Neal Norwitze241ce82003-02-17 18:17:05 +000032 fp.close()
Ned Deily43e10542011-06-27 23:41:53 -070033 self.teardown_files = [ test_support.TESTFN ]
Neal Norwitze241ce82003-02-17 18:17:05 +000034
35 def tearDown(self):
Ned Deily43e10542011-06-27 23:41:53 -070036 for teardown_file in self.teardown_files:
37 os.unlink(teardown_file)
Neal Norwitze241ce82003-02-17 18:17:05 +000038
39 def testNoArgFunctions(self):
40 # test posix functions which take no arguments and have
41 # no side-effects which we need to cleanup (e.g., fork, wait, abort)
42 NO_ARG_FUNCTIONS = [ "ctermid", "getcwd", "getcwdu", "uname",
Neal Norwitz71b13e82003-02-23 22:12:24 +000043 "times", "getloadavg", "tmpnam",
Neal Norwitze241ce82003-02-17 18:17:05 +000044 "getegid", "geteuid", "getgid", "getgroups",
45 "getpid", "getpgrp", "getppid", "getuid",
46 ]
Neal Norwitz71b13e82003-02-23 22:12:24 +000047
Antoine Pitroub0614612011-01-02 20:04:52 +000048 with warnings.catch_warnings():
49 warnings.filterwarnings("ignore", "", DeprecationWarning)
50 for name in NO_ARG_FUNCTIONS:
51 posix_func = getattr(posix, name, None)
52 if posix_func is not None:
53 posix_func()
54 self.assertRaises(TypeError, posix_func, 1)
Neal Norwitze241ce82003-02-17 18:17:05 +000055
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020056 @unittest.skipUnless(hasattr(posix, 'getresuid'),
57 'test needs posix.getresuid()')
58 def test_getresuid(self):
59 user_ids = posix.getresuid()
60 self.assertEqual(len(user_ids), 3)
61 for val in user_ids:
62 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000063
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020064 @unittest.skipUnless(hasattr(posix, 'getresgid'),
65 'test needs posix.getresgid()')
66 def test_getresgid(self):
67 group_ids = posix.getresgid()
68 self.assertEqual(len(group_ids), 3)
69 for val in group_ids:
70 self.assertGreaterEqual(val, 0)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000071
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020072 @unittest.skipUnless(hasattr(posix, 'setresuid'),
73 'test needs posix.setresuid()')
74 def test_setresuid(self):
75 current_user_ids = posix.getresuid()
76 self.assertIsNone(posix.setresuid(*current_user_ids))
77 # -1 means don't change that value.
78 self.assertIsNone(posix.setresuid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000079
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020080 @unittest.skipUnless(hasattr(posix, 'setresuid'),
81 'test needs posix.setresuid()')
82 def test_setresuid_exception(self):
83 # Don't do this test if someone is silly enough to run us as root.
84 current_user_ids = posix.getresuid()
85 if 0 not in current_user_ids:
86 new_user_ids = (current_user_ids[0]+1, -1, -1)
87 self.assertRaises(OSError, posix.setresuid, *new_user_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +000088
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020089 @unittest.skipUnless(hasattr(posix, 'setresgid'),
90 'test needs posix.setresgid()')
91 def test_setresgid(self):
92 current_group_ids = posix.getresgid()
93 self.assertIsNone(posix.setresgid(*current_group_ids))
94 # -1 means don't change that value.
95 self.assertIsNone(posix.setresgid(-1, -1, -1))
Martin v. Löwis50ea4562009-11-27 13:56:01 +000096
Serhiy Storchaka32e23e72013-11-03 23:15:46 +020097 @unittest.skipUnless(hasattr(posix, 'setresgid'),
98 'test needs posix.setresgid()')
99 def test_setresgid_exception(self):
100 # Don't do this test if someone is silly enough to run us as root.
101 current_group_ids = posix.getresgid()
102 if 0 not in current_group_ids:
103 new_group_ids = (current_group_ids[0]+1, -1, -1)
104 self.assertRaises(OSError, posix.setresgid, *new_group_ids)
Martin v. Löwis50ea4562009-11-27 13:56:01 +0000105
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000106 @unittest.skipUnless(hasattr(posix, 'initgroups'),
107 "test needs os.initgroups()")
108 def test_initgroups(self):
109 # It takes a string and an integer; check that it raises a TypeError
110 # for other argument lists.
111 self.assertRaises(TypeError, posix.initgroups)
112 self.assertRaises(TypeError, posix.initgroups, None)
113 self.assertRaises(TypeError, posix.initgroups, 3, "foo")
114 self.assertRaises(TypeError, posix.initgroups, "foo", 3, object())
115
116 # If a non-privileged user invokes it, it should fail with OSError
117 # EPERM.
118 if os.getuid() != 0:
Charles-François Natali666a5732012-05-02 20:00:37 +0200119 try:
120 name = pwd.getpwuid(posix.getuid()).pw_name
121 except KeyError:
122 # the current UID may not have a pwd entry
123 raise unittest.SkipTest("need a pwd entry")
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000124 try:
125 posix.initgroups(name, 13)
126 except OSError as e:
Ezio Melotti2623a372010-11-21 13:34:58 +0000127 self.assertEqual(e.errno, errno.EPERM)
Antoine Pitrou30b3b352009-12-02 20:37:54 +0000128 else:
129 self.fail("Expected OSError to be raised by initgroups")
130
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200131 @unittest.skipUnless(hasattr(posix, 'statvfs'),
132 'test needs posix.statvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000133 def test_statvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200134 self.assertTrue(posix.statvfs(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000135
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200136 @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
137 'test needs posix.fstatvfs()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000138 def test_fstatvfs(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200139 fp = open(test_support.TESTFN)
140 try:
141 self.assertTrue(posix.fstatvfs(fp.fileno()))
142 finally:
143 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000144
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200145 @unittest.skipUnless(hasattr(posix, 'ftruncate'),
146 'test needs posix.ftruncate()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000147 def test_ftruncate(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200148 fp = open(test_support.TESTFN, 'w+')
149 try:
150 # we need to have some data to truncate
151 fp.write('test')
152 fp.flush()
153 posix.ftruncate(fp.fileno(), 0)
154 finally:
155 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000156
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200157 @unittest.skipUnless(hasattr(posix, 'dup'),
158 'test needs posix.dup()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000159 def test_dup(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200160 fp = open(test_support.TESTFN)
161 try:
162 fd = posix.dup(fp.fileno())
163 self.assertIsInstance(fd, int)
164 os.close(fd)
165 finally:
166 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000167
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200168 @unittest.skipUnless(hasattr(posix, 'confstr'),
169 'test needs posix.confstr()')
Skip Montanaro94785ef2006-04-20 01:29:48 +0000170 def test_confstr(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200171 self.assertRaises(ValueError, posix.confstr, "CS_garbage")
172 self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
Skip Montanaro94785ef2006-04-20 01:29:48 +0000173
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200174 @unittest.skipUnless(hasattr(posix, 'dup2'),
175 'test needs posix.dup2()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000176 def test_dup2(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200177 fp1 = open(test_support.TESTFN)
178 fp2 = open(test_support.TESTFN)
179 try:
180 posix.dup2(fp1.fileno(), fp2.fileno())
181 finally:
182 fp1.close()
183 fp2.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000184
185 def fdopen_helper(self, *args):
Walter Dörwald21d3a322003-05-01 17:45:56 +0000186 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Neal Norwitze241ce82003-02-17 18:17:05 +0000187 fp2 = posix.fdopen(fd, *args)
188 fp2.close()
189
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200190 @unittest.skipUnless(hasattr(posix, 'fdopen'),
191 'test needs posix.fdopen()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000192 def test_fdopen(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200193 self.fdopen_helper()
194 self.fdopen_helper('r')
195 self.fdopen_helper('r', 100)
Neal Norwitze241ce82003-02-17 18:17:05 +0000196
Benjamin Petersone3737542014-08-24 10:37:12 -0500197 @unittest.skipUnless(hasattr(posix, 'fdopen'),
198 'test needs posix.fdopen()')
199 def test_fdopen_directory(self):
200 try:
201 fd = os.open('.', os.O_RDONLY)
Victor Stinner27058192018-06-05 00:36:42 +0200202 self.addCleanup(os.close, fd)
Benjamin Petersone3737542014-08-24 10:37:12 -0500203 except OSError as e:
204 self.assertEqual(e.errno, errno.EACCES)
205 self.skipTest("system cannot open directories")
206 with self.assertRaises(IOError) as cm:
207 os.fdopen(fd, 'r')
208 self.assertEqual(cm.exception.errno, errno.EISDIR)
209
Benjamin Peterson15773c82014-05-17 16:07:53 -0700210 @unittest.skipUnless(hasattr(posix, 'fdopen') and
Benjamin Peterson5918f8f2014-05-17 16:33:59 -0700211 not sys.platform.startswith("sunos"),
Benjamin Peterson15773c82014-05-17 16:07:53 -0700212 'test needs posix.fdopen()')
213 def test_fdopen_keeps_fd_open_on_errors(self):
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400214 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Benjamin Peterson15773c82014-05-17 16:07:53 -0700215 self.assertRaises(OSError, posix.fdopen, fd, 'w')
Benjamin Peterson5c863bf2014-04-14 19:45:46 -0400216 os.close(fd) # fd should not be closed.
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400217
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200218 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
219 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000220 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200221 fd = os.open(test_support.TESTFN,
222 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
223 self.assertRaises(OSError, os.open, test_support.TESTFN,
224 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
225 os.close(fd)
226
227 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000228 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200229 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000230 self.assertRaises(OSError, os.open, test_support.TESTFN,
231 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
232 os.close(fd)
233
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200234 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
235 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000236 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200237 fd1 = os.open(test_support.TESTFN,
238 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
239 fd2 = os.open(test_support.TESTFN,
240 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
241 os.close(fd2)
242 os.close(fd1)
243
244 if hasattr(posix, "O_EXLOCK"):
245 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000246 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200247 self.assertRaises(OSError, os.open, test_support.TESTFN,
248 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
249 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000250
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200251 @unittest.skipUnless(hasattr(posix, 'fstat'),
252 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000253 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200254 fp = open(test_support.TESTFN)
255 try:
256 self.assertTrue(posix.fstat(fp.fileno()))
257 finally:
258 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000259
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200260 @unittest.skipUnless(hasattr(posix, 'stat'),
261 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000262 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200263 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000264
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300265 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
266 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
267 def test_makedev(self):
268 st = posix.stat(test_support.TESTFN)
269 dev = st.st_dev
270 self.assertIsInstance(dev, (int, long))
271 self.assertGreaterEqual(dev, 0)
272
273 major = posix.major(dev)
274 self.assertIsInstance(major, (int, long))
275 self.assertGreaterEqual(major, 0)
276 self.assertEqual(posix.major(int(dev)), major)
277 self.assertEqual(posix.major(long(dev)), major)
278 self.assertRaises(TypeError, posix.major, float(dev))
279 self.assertRaises(TypeError, posix.major)
280 self.assertRaises((ValueError, OverflowError), posix.major, -1)
281
282 minor = posix.minor(dev)
283 self.assertIsInstance(minor, (int, long))
284 self.assertGreaterEqual(minor, 0)
285 self.assertEqual(posix.minor(int(dev)), minor)
286 self.assertEqual(posix.minor(long(dev)), minor)
287 self.assertRaises(TypeError, posix.minor, float(dev))
288 self.assertRaises(TypeError, posix.minor)
289 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
290
Victor Stinnerc2f7fb62017-07-27 18:44:43 +0200291 if sys.platform.startswith('freebsd') and dev >= 0x100000000:
292 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
293 "64-bit dev to 32-bit")
294
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300295 self.assertEqual(posix.makedev(major, minor), dev)
296 self.assertEqual(posix.makedev(int(major), int(minor)), dev)
297 self.assertEqual(posix.makedev(long(major), long(minor)), dev)
298 self.assertRaises(TypeError, posix.makedev, float(major), minor)
299 self.assertRaises(TypeError, posix.makedev, major, float(minor))
300 self.assertRaises(TypeError, posix.makedev, major)
301 self.assertRaises(TypeError, posix.makedev)
302
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200303 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000304 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200305 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200306 if stat_func is not None:
307 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200308 self.assertEqual(stat.st_uid, uid)
309 self.assertEqual(stat.st_gid, gid)
310 uid = os.getuid()
311 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200312 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200313 chown_func(first_param, uid, gid)
314 check_stat(uid, gid)
315 chown_func(first_param, -1, gid)
316 check_stat(uid, gid)
317 chown_func(first_param, uid, -1)
318 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200319
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200320 if uid == 0:
321 # Try an amusingly large uid/gid to make sure we handle
322 # large unsigned values. (chown lets you use any
323 # uid/gid you like, even if they aren't defined.)
324 #
325 # This problem keeps coming up:
326 # http://bugs.python.org/issue1747858
327 # http://bugs.python.org/issue4591
328 # http://bugs.python.org/issue15301
329 # Hopefully the fix in 4591 fixes it for good!
330 #
331 # This part of the test only runs when run as root.
332 # Only scary people run their tests as root.
333
334 big_value = 2**31
335 chown_func(first_param, big_value, big_value)
336 check_stat(big_value, big_value)
337 chown_func(first_param, -1, -1)
338 check_stat(big_value, big_value)
339 chown_func(first_param, uid, gid)
340 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200341 elif platform.system() in ('HP-UX', 'SunOS'):
342 # HP-UX and Solaris can allow a non-root user to chown() to root
343 # (issue #5113)
344 raise unittest.SkipTest("Skipping because of non-standard chown() "
345 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000346 else:
347 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200348 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200349 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200350 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200351 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200352 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200353 self.assertRaises(OSError, chown_func, first_param, -1, 0)
354 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200355 # test illegal types
356 for t in str, float:
357 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
358 check_stat(uid, gid)
359 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
360 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000361
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000362 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
363 def test_chown(self):
364 # raise an OSError if the file does not exist
365 os.unlink(test_support.TESTFN)
366 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
367
368 # re-create the file
369 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200370 self._test_all_chown_common(posix.chown, test_support.TESTFN,
371 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000372
373 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
374 def test_fchown(self):
375 os.unlink(test_support.TESTFN)
376
377 # re-create the file
378 test_file = open(test_support.TESTFN, 'w')
379 try:
380 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200381 self._test_all_chown_common(posix.fchown, fd,
382 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000383 finally:
384 test_file.close()
385
386 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
387 def test_lchown(self):
388 os.unlink(test_support.TESTFN)
389 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700390 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200391 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
392 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000393
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200394 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000395 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200396 posix.chdir(os.curdir)
397 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000398
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200399 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000400 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200401 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000402
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200403 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000404 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200405 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000406
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200407 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000408 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200409 old_mask = posix.umask(0)
410 self.assertIsInstance(old_mask, int)
411 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000412
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200413 @unittest.skipUnless(hasattr(posix, 'strerror'),
414 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000415 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200416 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000417
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200418 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000419 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200420 reader, writer = posix.pipe()
421 os.close(reader)
422 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000423
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200424 @unittest.skipUnless(hasattr(posix, 'tempnam'),
425 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000426 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200427 with warnings.catch_warnings():
428 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
429 self.assertTrue(posix.tempnam())
430 self.assertTrue(posix.tempnam(os.curdir))
431 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000432
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200433 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
434 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000435 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200436 with warnings.catch_warnings():
437 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
438 fp = posix.tmpfile()
439 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000440
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200441 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000442 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200443 now = time.time()
444 posix.utime(test_support.TESTFN, None)
445 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
446 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
447 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
448 posix.utime(test_support.TESTFN, (int(now), int(now)))
449 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000450
Ned Deily43e10542011-06-27 23:41:53 -0700451 def _test_chflags_regular_file(self, chflags_func, target_file):
452 st = os.stat(target_file)
453 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100454
455 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
456 try:
457 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
458 except OSError as err:
459 if err.errno != errno.EOPNOTSUPP:
460 raise
461 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
462 self.skipTest(msg)
463
Ned Deily43e10542011-06-27 23:41:53 -0700464 try:
465 new_st = os.stat(target_file)
466 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
467 try:
468 fd = open(target_file, 'w+')
469 except IOError as e:
470 self.assertEqual(e.errno, errno.EPERM)
471 finally:
472 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000473
Ned Deily43e10542011-06-27 23:41:53 -0700474 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
475 def test_chflags(self):
476 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
477
478 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
479 def test_lchflags_regular_file(self):
480 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
481
482 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
483 def test_lchflags_symlink(self):
484 testfn_st = os.stat(test_support.TESTFN)
485
486 self.assertTrue(hasattr(testfn_st, 'st_flags'))
487
488 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
489 self.teardown_files.append(_DUMMY_SYMLINK)
490 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
491
Victor Stinner8c7c6972012-12-04 10:07:16 +0100492 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
493 try:
494 posix.lchflags(_DUMMY_SYMLINK,
495 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
496 except OSError as err:
497 if err.errno != errno.EOPNOTSUPP:
498 raise
499 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
500 self.skipTest(msg)
501
Ned Deily43e10542011-06-27 23:41:53 -0700502 try:
503 new_testfn_st = os.stat(test_support.TESTFN)
504 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
505
506 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
507 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
508 new_dummy_symlink_st.st_flags)
509 finally:
510 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000511
Serhiy Storchaka787826c2017-06-25 09:50:00 +0300512 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
513 def test_putenv(self):
514 with self.assertRaises(TypeError):
515 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
516 with self.assertRaises(TypeError):
517 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
518 with self.assertRaises(ValueError):
519 os.putenv('FRUIT=ORANGE', 'lemon')
520
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200521 @unittest.skipUnless(hasattr(posix, 'getcwd'),
522 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000523 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200524 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
525 curdir = os.getcwd()
526 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000527
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200528 try:
529 os.mkdir(base_path)
530 os.chdir(base_path)
531 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600532 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000533
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200534 try:
535 def _create_and_do_getcwd(dirname, current_path_length = 0):
536 try:
537 os.mkdir(dirname)
538 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600539 self.skipTest("mkdir cannot create directory sufficiently "
540 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000541
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200542 os.chdir(dirname)
543 try:
544 os.getcwd()
545 if current_path_length < 4099:
546 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
547 except OSError as e:
548 expected_errno = errno.ENAMETOOLONG
549 # The following platforms have quirky getcwd()
550 # behaviour -- see issue 9185 and 15765 for
551 # more information.
552 quirky_platform = (
553 'sunos' in sys.platform or
554 'netbsd' in sys.platform or
555 'openbsd' in sys.platform
556 )
557 if quirky_platform:
558 expected_errno = errno.ERANGE
559 self.assertEqual(e.errno, expected_errno)
560 finally:
561 os.chdir('..')
562 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000563
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200564 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000565
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200566 finally:
567 os.chdir(curdir)
568 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000569
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000570 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000571 def test_getgroups(self):
Jesus Ceafd3ba7b2014-06-28 18:39:01 +0200572 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000573 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200574 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000575
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200576 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000577 raise unittest.SkipTest("need working 'id -G'")
578
Ned Deilycc23cc62013-02-02 15:06:45 -0800579 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
580 if sys.platform == 'darwin':
581 import sysconfig
582 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily1f70b872014-06-25 13:33:57 -0700583 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deilycc23cc62013-02-02 15:06:45 -0800584 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
585
Ronald Oussorenac72e582010-08-03 07:31:12 +0000586 # 'id -G' and 'os.getgroups()' should return the same
587 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000588 # #10822 - it is implementation defined whether posix.getgroups()
589 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000590 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000591 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000592 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000593
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +0300594 @test_support.requires_unicode
595 def test_path_with_null_unicode(self):
596 fn = test_support.TESTFN_UNICODE
Serhiy Storchaka77c91062016-07-03 10:53:39 +0300597 try:
598 fn.encode(test_support.TESTFN_ENCODING)
599 except (UnicodeError, TypeError):
600 self.skipTest("Requires unicode filenames support")
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +0300601 fn_with_NUL = fn + u'\0'
602 self.addCleanup(test_support.unlink, fn)
603 test_support.unlink(fn)
604 fd = None
605 try:
606 with self.assertRaises(TypeError):
607 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
608 finally:
609 if fd is not None:
610 os.close(fd)
611 self.assertFalse(os.path.exists(fn))
612 self.assertRaises(TypeError, os.mkdir, fn_with_NUL)
613 self.assertFalse(os.path.exists(fn))
614 open(fn, 'wb').close()
615 self.assertRaises(TypeError, os.stat, fn_with_NUL)
616
617 def test_path_with_null_byte(self):
618 fn = test_support.TESTFN
619 fn_with_NUL = fn + '\0'
620 self.addCleanup(test_support.unlink, fn)
621 test_support.unlink(fn)
622 fd = None
623 try:
624 with self.assertRaises(TypeError):
625 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
626 finally:
627 if fd is not None:
628 os.close(fd)
629 self.assertFalse(os.path.exists(fn))
630 self.assertRaises(TypeError, os.mkdir, fn_with_NUL)
631 self.assertFalse(os.path.exists(fn))
632 open(fn, 'wb').close()
633 self.assertRaises(TypeError, os.stat, fn_with_NUL)
634
635
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000636class PosixGroupsTester(unittest.TestCase):
637
638 def setUp(self):
639 if posix.getuid() != 0:
640 raise unittest.SkipTest("not enough privileges")
641 if not hasattr(posix, 'getgroups'):
642 raise unittest.SkipTest("need posix.getgroups")
643 if sys.platform == 'darwin':
644 raise unittest.SkipTest("getgroups(2) is broken on OSX")
645 self.saved_groups = posix.getgroups()
646
647 def tearDown(self):
648 if hasattr(posix, 'setgroups'):
649 posix.setgroups(self.saved_groups)
650 elif hasattr(posix, 'initgroups'):
651 name = pwd.getpwuid(posix.getuid()).pw_name
652 posix.initgroups(name, self.saved_groups[0])
653
654 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200655 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000656 def test_initgroups(self):
657 # find missing group
658
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500659 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000660 name = pwd.getpwuid(posix.getuid()).pw_name
661 posix.initgroups(name, g)
662 self.assertIn(g, posix.getgroups())
663
664 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200665 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000666 def test_setgroups(self):
667 for groups in [[0], range(16)]:
668 posix.setgroups(groups)
669 self.assertListEqual(groups, posix.getgroups())
670
Facundo Batista5596b0c2008-06-22 13:36:20 +0000671
Neal Norwitze241ce82003-02-17 18:17:05 +0000672def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000673 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000674
675if __name__ == '__main__':
676 test_main()