blob: bce4e21e992b45696e8e19a8b9ae2376bdce50fd [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)
202 except OSError as e:
203 self.assertEqual(e.errno, errno.EACCES)
204 self.skipTest("system cannot open directories")
205 with self.assertRaises(IOError) as cm:
206 os.fdopen(fd, 'r')
207 self.assertEqual(cm.exception.errno, errno.EISDIR)
208
Benjamin Peterson15773c82014-05-17 16:07:53 -0700209 @unittest.skipUnless(hasattr(posix, 'fdopen') and
Benjamin Peterson5918f8f2014-05-17 16:33:59 -0700210 not sys.platform.startswith("sunos"),
Benjamin Peterson15773c82014-05-17 16:07:53 -0700211 'test needs posix.fdopen()')
212 def test_fdopen_keeps_fd_open_on_errors(self):
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400213 fd = os.open(test_support.TESTFN, os.O_RDONLY)
Benjamin Peterson15773c82014-05-17 16:07:53 -0700214 self.assertRaises(OSError, posix.fdopen, fd, 'w')
Benjamin Peterson5c863bf2014-04-14 19:45:46 -0400215 os.close(fd) # fd should not be closed.
Benjamin Peterson02ab7a82014-04-09 15:40:18 -0400216
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200217 @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
218 'test needs posix.O_EXLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000219 def test_osexlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200220 fd = os.open(test_support.TESTFN,
221 os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
222 self.assertRaises(OSError, os.open, test_support.TESTFN,
223 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
224 os.close(fd)
225
226 if hasattr(posix, "O_SHLOCK"):
Skip Montanaro98470002005-06-17 01:14:49 +0000227 fd = os.open(test_support.TESTFN,
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200228 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Skip Montanaro98470002005-06-17 01:14:49 +0000229 self.assertRaises(OSError, os.open, test_support.TESTFN,
230 os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
231 os.close(fd)
232
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200233 @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
234 'test needs posix.O_SHLOCK')
Skip Montanaro98470002005-06-17 01:14:49 +0000235 def test_osshlock(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200236 fd1 = os.open(test_support.TESTFN,
237 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
238 fd2 = os.open(test_support.TESTFN,
239 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
240 os.close(fd2)
241 os.close(fd1)
242
243 if hasattr(posix, "O_EXLOCK"):
244 fd = os.open(test_support.TESTFN,
Skip Montanaro98470002005-06-17 01:14:49 +0000245 os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200246 self.assertRaises(OSError, os.open, test_support.TESTFN,
247 os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
248 os.close(fd)
Skip Montanaro98470002005-06-17 01:14:49 +0000249
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200250 @unittest.skipUnless(hasattr(posix, 'fstat'),
251 'test needs posix.fstat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000252 def test_fstat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200253 fp = open(test_support.TESTFN)
254 try:
255 self.assertTrue(posix.fstat(fp.fileno()))
256 finally:
257 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000258
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200259 @unittest.skipUnless(hasattr(posix, 'stat'),
260 'test needs posix.stat()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000261 def test_stat(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200262 self.assertTrue(posix.stat(test_support.TESTFN))
Neal Norwitze241ce82003-02-17 18:17:05 +0000263
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300264 @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()')
265 @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()')
266 def test_makedev(self):
267 st = posix.stat(test_support.TESTFN)
268 dev = st.st_dev
269 self.assertIsInstance(dev, (int, long))
270 self.assertGreaterEqual(dev, 0)
271
272 major = posix.major(dev)
273 self.assertIsInstance(major, (int, long))
274 self.assertGreaterEqual(major, 0)
275 self.assertEqual(posix.major(int(dev)), major)
276 self.assertEqual(posix.major(long(dev)), major)
277 self.assertRaises(TypeError, posix.major, float(dev))
278 self.assertRaises(TypeError, posix.major)
279 self.assertRaises((ValueError, OverflowError), posix.major, -1)
280
281 minor = posix.minor(dev)
282 self.assertIsInstance(minor, (int, long))
283 self.assertGreaterEqual(minor, 0)
284 self.assertEqual(posix.minor(int(dev)), minor)
285 self.assertEqual(posix.minor(long(dev)), minor)
286 self.assertRaises(TypeError, posix.minor, float(dev))
287 self.assertRaises(TypeError, posix.minor)
288 self.assertRaises((ValueError, OverflowError), posix.minor, -1)
289
Victor Stinnerc2f7fb62017-07-27 18:44:43 +0200290 if sys.platform.startswith('freebsd') and dev >= 0x100000000:
291 self.skipTest("bpo-31044: on FreeBSD CURRENT, minor() truncates "
292 "64-bit dev to 32-bit")
293
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300294 self.assertEqual(posix.makedev(major, minor), dev)
295 self.assertEqual(posix.makedev(int(major), int(minor)), dev)
296 self.assertEqual(posix.makedev(long(major), long(minor)), dev)
297 self.assertRaises(TypeError, posix.makedev, float(major), minor)
298 self.assertRaises(TypeError, posix.makedev, major, float(minor))
299 self.assertRaises(TypeError, posix.makedev, major)
300 self.assertRaises(TypeError, posix.makedev)
301
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200302 def _test_all_chown_common(self, chown_func, first_param, stat_func):
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000303 """Common code for chown, fchown and lchown tests."""
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200304 def check_stat(uid, gid):
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200305 if stat_func is not None:
306 stat = stat_func(first_param)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200307 self.assertEqual(stat.st_uid, uid)
308 self.assertEqual(stat.st_gid, gid)
309 uid = os.getuid()
310 gid = os.getgid()
Charles-François Natalif8387642012-04-17 19:46:06 +0200311 # test a successful chown call
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200312 chown_func(first_param, uid, gid)
313 check_stat(uid, gid)
314 chown_func(first_param, -1, gid)
315 check_stat(uid, gid)
316 chown_func(first_param, uid, -1)
317 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200318
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200319 if uid == 0:
320 # Try an amusingly large uid/gid to make sure we handle
321 # large unsigned values. (chown lets you use any
322 # uid/gid you like, even if they aren't defined.)
323 #
324 # This problem keeps coming up:
325 # http://bugs.python.org/issue1747858
326 # http://bugs.python.org/issue4591
327 # http://bugs.python.org/issue15301
328 # Hopefully the fix in 4591 fixes it for good!
329 #
330 # This part of the test only runs when run as root.
331 # Only scary people run their tests as root.
332
333 big_value = 2**31
334 chown_func(first_param, big_value, big_value)
335 check_stat(big_value, big_value)
336 chown_func(first_param, -1, -1)
337 check_stat(big_value, big_value)
338 chown_func(first_param, uid, gid)
339 check_stat(uid, gid)
Charles-François Natalif8387642012-04-17 19:46:06 +0200340 elif platform.system() in ('HP-UX', 'SunOS'):
341 # HP-UX and Solaris can allow a non-root user to chown() to root
342 # (issue #5113)
343 raise unittest.SkipTest("Skipping because of non-standard chown() "
344 "behavior")
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000345 else:
346 # non-root cannot chown to root, raises OSError
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200347 self.assertRaises(OSError, chown_func, first_param, 0, 0)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200348 check_stat(uid, gid)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200349 self.assertRaises(OSError, chown_func, first_param, 0, -1)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200350 check_stat(uid, gid)
Serhiy Storchaka484dee32013-02-21 14:33:45 +0200351 if 0 not in os.getgroups():
Serhiy Storchakafffc4792013-02-20 19:47:31 +0200352 self.assertRaises(OSError, chown_func, first_param, -1, 0)
353 check_stat(uid, gid)
Serhiy Storchaka3e188c42013-02-20 19:39:59 +0200354 # test illegal types
355 for t in str, float:
356 self.assertRaises(TypeError, chown_func, first_param, t(uid), gid)
357 check_stat(uid, gid)
358 self.assertRaises(TypeError, chown_func, first_param, uid, t(gid))
359 check_stat(uid, gid)
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000360
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000361 @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()")
362 def test_chown(self):
363 # raise an OSError if the file does not exist
364 os.unlink(test_support.TESTFN)
365 self.assertRaises(OSError, posix.chown, test_support.TESTFN, -1, -1)
366
367 # re-create the file
368 open(test_support.TESTFN, 'w').close()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200369 self._test_all_chown_common(posix.chown, test_support.TESTFN,
370 getattr(posix, 'stat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000371
372 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
373 def test_fchown(self):
374 os.unlink(test_support.TESTFN)
375
376 # re-create the file
377 test_file = open(test_support.TESTFN, 'w')
378 try:
379 fd = test_file.fileno()
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200380 self._test_all_chown_common(posix.fchown, fd,
381 getattr(posix, 'fstat', None))
Gregory P. Smith9f12d462009-12-23 09:31:11 +0000382 finally:
383 test_file.close()
384
385 @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()")
386 def test_lchown(self):
387 os.unlink(test_support.TESTFN)
388 # create a symlink
Ned Deily43e10542011-06-27 23:41:53 -0700389 os.symlink(_DUMMY_SYMLINK, test_support.TESTFN)
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200390 self._test_all_chown_common(posix.lchown, test_support.TESTFN,
391 getattr(posix, 'lstat', None))
Gregory P. Smithf48da8f2008-03-18 19:05:32 +0000392
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200393 @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000394 def test_chdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200395 posix.chdir(os.curdir)
396 self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
Neal Norwitze241ce82003-02-17 18:17:05 +0000397
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200398 @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000399 def test_lsdir(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200400 self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
Neal Norwitze241ce82003-02-17 18:17:05 +0000401
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200402 @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000403 def test_access(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200404 self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
Neal Norwitze241ce82003-02-17 18:17:05 +0000405
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200406 @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000407 def test_umask(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200408 old_mask = posix.umask(0)
409 self.assertIsInstance(old_mask, int)
410 posix.umask(old_mask)
Neal Norwitze241ce82003-02-17 18:17:05 +0000411
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200412 @unittest.skipUnless(hasattr(posix, 'strerror'),
413 'test needs posix.strerror()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000414 def test_strerror(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200415 self.assertTrue(posix.strerror(0))
Neal Norwitze241ce82003-02-17 18:17:05 +0000416
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200417 @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000418 def test_pipe(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200419 reader, writer = posix.pipe()
420 os.close(reader)
421 os.close(writer)
Neal Norwitze241ce82003-02-17 18:17:05 +0000422
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200423 @unittest.skipUnless(hasattr(posix, 'tempnam'),
424 'test needs posix.tempnam()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000425 def test_tempnam(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200426 with warnings.catch_warnings():
427 warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
428 self.assertTrue(posix.tempnam())
429 self.assertTrue(posix.tempnam(os.curdir))
430 self.assertTrue(posix.tempnam(os.curdir, 'blah'))
Neal Norwitze241ce82003-02-17 18:17:05 +0000431
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200432 @unittest.skipUnless(hasattr(posix, 'tmpfile'),
433 'test needs posix.tmpfile()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000434 def test_tmpfile(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200435 with warnings.catch_warnings():
436 warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
437 fp = posix.tmpfile()
438 fp.close()
Neal Norwitze241ce82003-02-17 18:17:05 +0000439
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200440 @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
Neal Norwitze241ce82003-02-17 18:17:05 +0000441 def test_utime(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200442 now = time.time()
443 posix.utime(test_support.TESTFN, None)
444 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
445 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
446 self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
447 posix.utime(test_support.TESTFN, (int(now), int(now)))
448 posix.utime(test_support.TESTFN, (now, now))
Neal Norwitze241ce82003-02-17 18:17:05 +0000449
Ned Deily43e10542011-06-27 23:41:53 -0700450 def _test_chflags_regular_file(self, chflags_func, target_file):
451 st = os.stat(target_file)
452 self.assertTrue(hasattr(st, 'st_flags'))
Victor Stinner8c7c6972012-12-04 10:07:16 +0100453
454 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
455 try:
456 chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE)
457 except OSError as err:
458 if err.errno != errno.EOPNOTSUPP:
459 raise
460 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
461 self.skipTest(msg)
462
Ned Deily43e10542011-06-27 23:41:53 -0700463 try:
464 new_st = os.stat(target_file)
465 self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags)
466 try:
467 fd = open(target_file, 'w+')
468 except IOError as e:
469 self.assertEqual(e.errno, errno.EPERM)
470 finally:
471 posix.chflags(target_file, st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000472
Ned Deily43e10542011-06-27 23:41:53 -0700473 @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()')
474 def test_chflags(self):
475 self._test_chflags_regular_file(posix.chflags, test_support.TESTFN)
476
477 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
478 def test_lchflags_regular_file(self):
479 self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN)
480
481 @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()')
482 def test_lchflags_symlink(self):
483 testfn_st = os.stat(test_support.TESTFN)
484
485 self.assertTrue(hasattr(testfn_st, 'st_flags'))
486
487 os.symlink(test_support.TESTFN, _DUMMY_SYMLINK)
488 self.teardown_files.append(_DUMMY_SYMLINK)
489 dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
490
Victor Stinner8c7c6972012-12-04 10:07:16 +0100491 # ZFS returns EOPNOTSUPP when attempting to set flag UF_IMMUTABLE.
492 try:
493 posix.lchflags(_DUMMY_SYMLINK,
494 dummy_symlink_st.st_flags | stat.UF_IMMUTABLE)
495 except OSError as err:
496 if err.errno != errno.EOPNOTSUPP:
497 raise
498 msg = 'chflag UF_IMMUTABLE not supported by underlying fs'
499 self.skipTest(msg)
500
Ned Deily43e10542011-06-27 23:41:53 -0700501 try:
502 new_testfn_st = os.stat(test_support.TESTFN)
503 new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK)
504
505 self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags)
506 self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE,
507 new_dummy_symlink_st.st_flags)
508 finally:
509 posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
Martin v. Löwis382abef2007-02-19 10:55:19 +0000510
Serhiy Storchaka787826c2017-06-25 09:50:00 +0300511 @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()")
512 def test_putenv(self):
513 with self.assertRaises(TypeError):
514 os.putenv('FRUIT\0VEGETABLE', 'cabbage')
515 with self.assertRaises(TypeError):
516 os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
517 with self.assertRaises(ValueError):
518 os.putenv('FRUIT=ORANGE', 'lemon')
519
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200520 @unittest.skipUnless(hasattr(posix, 'getcwd'),
521 'test needs posix.getcwd()')
Facundo Batista5596b0c2008-06-22 13:36:20 +0000522 def test_getcwd_long_pathnames(self):
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200523 dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
524 curdir = os.getcwd()
525 base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
Facundo Batista5596b0c2008-06-22 13:36:20 +0000526
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200527 try:
528 os.mkdir(base_path)
529 os.chdir(base_path)
530 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600531 self.skipTest("cannot create directory for testing")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000532
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200533 try:
534 def _create_and_do_getcwd(dirname, current_path_length = 0):
535 try:
536 os.mkdir(dirname)
537 except:
Zachary Ware1f702212013-12-10 14:09:20 -0600538 self.skipTest("mkdir cannot create directory sufficiently "
539 "deep for getcwd test")
Facundo Batista5596b0c2008-06-22 13:36:20 +0000540
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200541 os.chdir(dirname)
542 try:
543 os.getcwd()
544 if current_path_length < 4099:
545 _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
546 except OSError as e:
547 expected_errno = errno.ENAMETOOLONG
548 # The following platforms have quirky getcwd()
549 # behaviour -- see issue 9185 and 15765 for
550 # more information.
551 quirky_platform = (
552 'sunos' in sys.platform or
553 'netbsd' in sys.platform or
554 'openbsd' in sys.platform
555 )
556 if quirky_platform:
557 expected_errno = errno.ERANGE
558 self.assertEqual(e.errno, expected_errno)
559 finally:
560 os.chdir('..')
561 os.rmdir(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000562
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200563 _create_and_do_getcwd(dirname)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000564
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200565 finally:
566 os.chdir(curdir)
567 shutil.rmtree(base_path)
Facundo Batista5596b0c2008-06-22 13:36:20 +0000568
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000569 @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000570 def test_getgroups(self):
Jesus Ceafd3ba7b2014-06-28 18:39:01 +0200571 with os.popen('id -G 2>/dev/null') as idg:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000572 groups = idg.read().strip()
Charles-François Natali666a5732012-05-02 20:00:37 +0200573 ret = idg.close()
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000574
Charles-François Natalidee8dad2012-05-02 20:48:21 +0200575 if ret != None or not groups:
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000576 raise unittest.SkipTest("need working 'id -G'")
577
Ned Deilycc23cc62013-02-02 15:06:45 -0800578 # Issues 16698: OS X ABIs prior to 10.6 have limits on getgroups()
579 if sys.platform == 'darwin':
580 import sysconfig
581 dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0'
Ned Deily1f70b872014-06-25 13:33:57 -0700582 if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6):
Ned Deilycc23cc62013-02-02 15:06:45 -0800583 raise unittest.SkipTest("getgroups(2) is broken prior to 10.6")
584
Ronald Oussorenac72e582010-08-03 07:31:12 +0000585 # 'id -G' and 'os.getgroups()' should return the same
586 # groups, ignoring order and duplicates.
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000587 # #10822 - it is implementation defined whether posix.getgroups()
588 # includes the effective gid so we include it anyway, since id -G does
Ronald Oussoren5719c2f2010-07-24 14:21:29 +0000589 self.assertEqual(
Ronald Oussorenac72e582010-08-03 07:31:12 +0000590 set([int(x) for x in groups.split()]),
Antoine Pitrou8bc59fa2011-01-12 18:56:09 +0000591 set(posix.getgroups() + [posix.getegid()]))
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000592
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +0300593 @test_support.requires_unicode
594 def test_path_with_null_unicode(self):
595 fn = test_support.TESTFN_UNICODE
Serhiy Storchaka77c91062016-07-03 10:53:39 +0300596 try:
597 fn.encode(test_support.TESTFN_ENCODING)
598 except (UnicodeError, TypeError):
599 self.skipTest("Requires unicode filenames support")
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +0300600 fn_with_NUL = fn + u'\0'
601 self.addCleanup(test_support.unlink, fn)
602 test_support.unlink(fn)
603 fd = None
604 try:
605 with self.assertRaises(TypeError):
606 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
607 finally:
608 if fd is not None:
609 os.close(fd)
610 self.assertFalse(os.path.exists(fn))
611 self.assertRaises(TypeError, os.mkdir, fn_with_NUL)
612 self.assertFalse(os.path.exists(fn))
613 open(fn, 'wb').close()
614 self.assertRaises(TypeError, os.stat, fn_with_NUL)
615
616 def test_path_with_null_byte(self):
617 fn = test_support.TESTFN
618 fn_with_NUL = fn + '\0'
619 self.addCleanup(test_support.unlink, fn)
620 test_support.unlink(fn)
621 fd = None
622 try:
623 with self.assertRaises(TypeError):
624 fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises
625 finally:
626 if fd is not None:
627 os.close(fd)
628 self.assertFalse(os.path.exists(fn))
629 self.assertRaises(TypeError, os.mkdir, fn_with_NUL)
630 self.assertFalse(os.path.exists(fn))
631 open(fn, 'wb').close()
632 self.assertRaises(TypeError, os.stat, fn_with_NUL)
633
634
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000635class PosixGroupsTester(unittest.TestCase):
636
637 def setUp(self):
638 if posix.getuid() != 0:
639 raise unittest.SkipTest("not enough privileges")
640 if not hasattr(posix, 'getgroups'):
641 raise unittest.SkipTest("need posix.getgroups")
642 if sys.platform == 'darwin':
643 raise unittest.SkipTest("getgroups(2) is broken on OSX")
644 self.saved_groups = posix.getgroups()
645
646 def tearDown(self):
647 if hasattr(posix, 'setgroups'):
648 posix.setgroups(self.saved_groups)
649 elif hasattr(posix, 'initgroups'):
650 name = pwd.getpwuid(posix.getuid()).pw_name
651 posix.initgroups(name, self.saved_groups[0])
652
653 @unittest.skipUnless(hasattr(posix, 'initgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200654 'test needs posix.initgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000655 def test_initgroups(self):
656 # find missing group
657
Benjamin Petersonbde1cfb2014-03-01 19:14:12 -0500658 g = max(self.saved_groups or [0]) + 1
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000659 name = pwd.getpwuid(posix.getuid()).pw_name
660 posix.initgroups(name, g)
661 self.assertIn(g, posix.getgroups())
662
663 @unittest.skipUnless(hasattr(posix, 'setgroups'),
Serhiy Storchaka32e23e72013-11-03 23:15:46 +0200664 'test needs posix.setgroups()')
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000665 def test_setgroups(self):
666 for groups in [[0], range(16)]:
667 posix.setgroups(groups)
668 self.assertListEqual(groups, posix.getgroups())
669
Facundo Batista5596b0c2008-06-22 13:36:20 +0000670
Neal Norwitze241ce82003-02-17 18:17:05 +0000671def test_main():
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +0000672 test_support.run_unittest(PosixTester, PosixGroupsTester)
Neal Norwitze241ce82003-02-17 18:17:05 +0000673
674if __name__ == '__main__':
675 test_main()