1 """Test program for the fcntl C module. 2 3 OS/2+EMX doesn't support the file locking operations. 4 5 """ 6 import os 7 import struct 8 import sys 9 import _testcapi 10 import unittest 11 from test.test_support import (verbose, TESTFN, unlink, run_unittest, 12 import_module) 13 14 # Skip test if no fnctl module. 15 fcntl = import_module('fcntl') 16 17 18 # TODO - Write tests for flock() and lockf(). 19 20 def get_lockdata(): 21 if sys.platform.startswith('atheos'): 22 start_len = "qq" 23 else: 24 try: 25 os.O_LARGEFILE 26 except AttributeError: 27 start_len = "ll" 28 else: 29 start_len = "qq" 30 31 if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd', 'bsdos')) 32 or sys.platform == 'darwin'): 33 if struct.calcsize('l') == 8: 34 off_t = 'l' 35 pid_t = 'i' 36 else: 37 off_t = 'lxxxx' 38 pid_t = 'l' 39 lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0, 40 fcntl.F_WRLCK, 0) 41 elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']: 42 lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) 43 elif sys.platform in ['os2emx']: 44 lockdata = None 45 else: 46 lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) 47 if lockdata: 48 if verbose: 49 print 'struct.pack: ', repr(lockdata) 50 return lockdata 51 52 lockdata = get_lockdata() 53 54 55 class TestFcntl(unittest.TestCase): 56 57 def setUp(self): 58 self.f = None 59 60 def tearDown(self): 61 if self.f and not self.f.closed: 62 self.f.close() 63 unlink(TESTFN) 64 65 def test_fcntl_fileno(self): 66 # the example from the library docs 67 self.f = open(TESTFN, 'w') 68 rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) 69 if verbose: 70 print 'Status from fcntl with O_NONBLOCK: ', rv 71 if sys.platform not in ['os2emx']: 72 rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata) 73 if verbose: 74 print 'String from fcntl with F_SETLKW: ', repr(rv) 75 self.f.close() 76 77 def test_fcntl_file_descriptor(self): 78 # again, but pass the file rather than numeric descriptor 79 self.f = open(TESTFN, 'w') 80 rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK) 81 if sys.platform not in ['os2emx']: 82 rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) 83 self.f.close() 84 85 def test_fcntl_bad_file(self): 86 class F: 87 def __init__(self, fn): 88 self.fn = fn 89 def fileno(self): 90 return self.fn 91 self.assertRaises(ValueError, fcntl.fcntl, -1, fcntl.F_SETFL, os.O_NONBLOCK) 92 self.assertRaises(ValueError, fcntl.fcntl, F(-1), fcntl.F_SETFL, os.O_NONBLOCK) 93 self.assertRaises(TypeError, fcntl.fcntl, 'spam', fcntl.F_SETFL, os.O_NONBLOCK) 94 self.assertRaises(TypeError, fcntl.fcntl, F('spam'), fcntl.F_SETFL, os.O_NONBLOCK) 95 # Issue 15989 96 self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MAX + 1, 97 fcntl.F_SETFL, os.O_NONBLOCK) 98 self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MAX + 1), 99 fcntl.F_SETFL, os.O_NONBLOCK) 100 self.assertRaises(ValueError, fcntl.fcntl, _testcapi.INT_MIN - 1, 101 fcntl.F_SETFL, os.O_NONBLOCK) 102 self.assertRaises(ValueError, fcntl.fcntl, F(_testcapi.INT_MIN - 1), 103 fcntl.F_SETFL, os.O_NONBLOCK) 104 105 def test_fcntl_64_bit(self): 106 # Issue #1309352: fcntl shouldn't fail when the third arg fits in a 107 # C 'long' but not in a C 'int'. 108 try: 109 cmd = fcntl.F_NOTIFY 110 # This flag is larger than 2**31 in 64-bit builds 111 flags = fcntl.DN_MULTISHOT 112 except AttributeError: 113 self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable") 114 fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY) 115 try: 116 fcntl.fcntl(fd, cmd, flags) 117 finally: 118 os.close(fd) 119 120 121 def test_main(): 122 run_unittest(TestFcntl) 123 124 if __name__ == '__main__': 125 test_main() 126