blob: f977187fec1b24cb8bc9b0ca25d7e6bc87cfb567 [file] [log] [blame]
Roger E. Massefb01d4b1996-12-17 17:41:09 +00001"""Test program for the fcntl C module.
Roger E. Massefb01d4b1996-12-17 17:41:09 +00002"""
Christian Heimese25f35e2008-03-20 10:49:03 +00003import os
4import struct
5import sys
Serhiy Storchaka78980432013-01-15 01:12:17 +02006import _testcapi
Christian Heimesdd15f6c2008-03-16 00:07:10 +00007import unittest
R. David Murraya21e4ca2009-03-31 23:16:50 +00008from test.support import verbose, TESTFN, unlink, run_unittest, import_module
9
10# Skip test if no fnctl module.
11fcntl = import_module('fcntl')
12
Roger E. Massefb01d4b1996-12-17 17:41:09 +000013
Christian Heimese25f35e2008-03-20 10:49:03 +000014# TODO - Write tests for flock() and lockf().
Martin v. Löwisa660a342001-10-18 22:07:48 +000015
Christian Heimesdd15f6c2008-03-16 00:07:10 +000016def get_lockdata():
Antoine Pitrou6103ab12009-10-24 20:11:21 +000017 try:
18 os.O_LARGEFILE
19 except AttributeError:
20 start_len = "ll"
Hye-Shik Changac89f6e2005-04-04 15:21:04 +000021 else:
Antoine Pitrou6103ab12009-10-24 20:11:21 +000022 start_len = "qq"
Fred Drakebc7809b2001-05-09 21:11:59 +000023
Victor Stinnere6747472011-08-21 00:39:18 +020024 if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd', 'bsdos'))
25 or sys.platform == 'darwin'):
Christian Heimesdd15f6c2008-03-16 00:07:10 +000026 if struct.calcsize('l') == 8:
27 off_t = 'l'
28 pid_t = 'i'
29 else:
30 off_t = 'lxxxx'
31 pid_t = 'l'
32 lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0,
33 fcntl.F_WRLCK, 0)
34 elif sys.platform in ['aix3', 'aix4', 'hp-uxB', 'unixware7']:
35 lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000036 else:
37 lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
38 if lockdata:
39 if verbose:
40 print('struct.pack: ', repr(lockdata))
41 return lockdata
Fred Drakebc7809b2001-05-09 21:11:59 +000042
Christian Heimesdd15f6c2008-03-16 00:07:10 +000043lockdata = get_lockdata()
Roger E. Massefb01d4b1996-12-17 17:41:09 +000044
Christian Heimesdd15f6c2008-03-16 00:07:10 +000045class TestFcntl(unittest.TestCase):
46
47 def setUp(self):
48 self.f = None
49
50 def tearDown(self):
Antoine Pitrou61f77b52009-05-24 15:46:13 +000051 if self.f and not self.f.closed:
Christian Heimesdd15f6c2008-03-16 00:07:10 +000052 self.f.close()
53 unlink(TESTFN)
54
55 def test_fcntl_fileno(self):
56 # the example from the library docs
Victor Stinnera6d2c762011-06-30 18:20:11 +020057 self.f = open(TESTFN, 'wb')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000058 rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
59 if verbose:
60 print('Status from fcntl with O_NONBLOCK: ', rv)
Jesus Ceaf1af7052012-10-05 02:48:46 +020061 rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata)
62 if verbose:
63 print('String from fcntl with F_SETLKW: ', repr(rv))
Christian Heimesdd15f6c2008-03-16 00:07:10 +000064 self.f.close()
65
66 def test_fcntl_file_descriptor(self):
67 # again, but pass the file rather than numeric descriptor
Victor Stinnera6d2c762011-06-30 18:20:11 +020068 self.f = open(TESTFN, 'wb')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000069 rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK)
Jesus Ceaf1af7052012-10-05 02:48:46 +020070 rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000071 self.f.close()
Fred Drakebc7809b2001-05-09 21:11:59 +000072
Serhiy Storchaka78980432013-01-15 01:12:17 +020073 def test_fcntl_bad_file(self):
74 class F:
75 def __init__(self, fn):
76 self.fn = fn
77 def fileno(self):
78 return self.fn
79 self.assertRaises(ValueError, fcntl.fcntl, -1, fcntl.F_SETFL, os.O_NONBLOCK)
80 self.assertRaises(ValueError, fcntl.fcntl, F(-1), fcntl.F_SETFL, os.O_NONBLOCK)
81 self.assertRaises(TypeError, fcntl.fcntl, 'spam', fcntl.F_SETFL, os.O_NONBLOCK)
82 self.assertRaises(TypeError, fcntl.fcntl, F('spam'), fcntl.F_SETFL, os.O_NONBLOCK)
83 # Issue 15989
84 self.assertRaises(OverflowError, fcntl.fcntl, _testcapi.INT_MAX + 1,
85 fcntl.F_SETFL, os.O_NONBLOCK)
86 self.assertRaises(OverflowError, fcntl.fcntl, F(_testcapi.INT_MAX + 1),
87 fcntl.F_SETFL, os.O_NONBLOCK)
88 self.assertRaises(OverflowError, fcntl.fcntl, _testcapi.INT_MIN - 1,
89 fcntl.F_SETFL, os.O_NONBLOCK)
90 self.assertRaises(OverflowError, fcntl.fcntl, F(_testcapi.INT_MIN - 1),
91 fcntl.F_SETFL, os.O_NONBLOCK)
92
Antoine Pitrou61f77b52009-05-24 15:46:13 +000093 def test_fcntl_64_bit(self):
94 # Issue #1309352: fcntl shouldn't fail when the third arg fits in a
95 # C 'long' but not in a C 'int'.
96 try:
97 cmd = fcntl.F_NOTIFY
98 # This flag is larger than 2**31 in 64-bit builds
99 flags = fcntl.DN_MULTISHOT
100 except AttributeError:
101 self.skipTest("F_NOTIFY or DN_MULTISHOT unavailable")
102 fd = os.open(os.path.dirname(os.path.abspath(TESTFN)), os.O_RDONLY)
103 try:
104 fcntl.fcntl(fd, cmd, flags)
105 finally:
106 os.close(fd)
107
Fred Drakebc7809b2001-05-09 21:11:59 +0000108
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000109def test_main():
110 run_unittest(TestFcntl)
Fred Drakebc7809b2001-05-09 21:11:59 +0000111
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000112if __name__ == '__main__':
113 test_main()