blob: ff2910779bc6511afe41066a600ce53f16545bae [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""Extended file operations available in POSIX.
Guido van Rossum78f8dea1994-05-18 11:07:44 +00002
Guido van Rossum54f22ed2000-02-04 15:10:34 +00003f = posixfile.open(filename, [mode, [bufsize]])
4 will create a new posixfile object
5
6f = posixfile.fileopen(fileobject)
7 will create a posixfile object from a builtin file object
8
9f.file()
10 will return the original builtin file object
11
12f.dup()
13 will return a new file object based on a new filedescriptor
14
15f.dup2(fd)
16 will return a new file object based on the given filedescriptor
17
18f.flags(mode)
19 will turn on the associated flag (merge)
20 mode can contain the following characters:
21
22 (character representing a flag)
23 a append only flag
24 c close on exec flag
25 n no delay flag
26 s synchronization flag
27 (modifiers)
28 ! turn flags 'off' instead of default 'on'
29 = copy flags 'as is' instead of default 'merge'
30 ? return a string in which the characters represent the flags
31 that are set
32
33 note: - the '!' and '=' modifiers are mutually exclusive.
34 - the '?' modifier will return the status of the flags after they
35 have been changed by other characters in the mode string
36
37f.lock(mode [, len [, start [, whence]]])
38 will (un)lock a region
39 mode can contain the following characters:
40
41 (character representing type of lock)
42 u unlock
43 r read lock
44 w write lock
45 (modifiers)
46 | wait until the lock can be granted
47 ? return the first lock conflicting with the requested lock
48 or 'None' if there is no conflict. The lock returned is in the
49 format (mode, len, start, whence, pid) where mode is a
50 character representing the type of lock ('r' or 'w')
51
52 note: - the '?' modifier prevents a region from being locked; it is
53 query only
54"""
Brett Cannon41bf2fa2007-05-20 23:57:38 +000055import warnings
56warnings.warn("The posixfile module is deprecated; "
57 "fcntl.lockf() provides better locking", DeprecationWarning, 2)
Fred Drake9242a4a2001-10-24 22:03:35 +000058
Guido van Rossum78f8dea1994-05-18 11:07:44 +000059class _posixfile_:
Guido van Rossum54f22ed2000-02-04 15:10:34 +000060 """File wrapper class that provides extra POSIX file routines."""
61
Guido van Rossumc762bec1994-05-18 11:08:10 +000062 states = ['open', 'closed']
63
Guido van Rossum78f8dea1994-05-18 11:07:44 +000064 #
65 # Internal routines
66 #
67 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000068 file = self._file_
69 return "<%s posixfile '%s', mode '%s' at %s>" % \
70 (self.states[file.closed], file.name, file.mode, \
71 hex(id(self))[2:])
Guido van Rossum78f8dea1994-05-18 11:07:44 +000072
Guido van Rossum78f8dea1994-05-18 11:07:44 +000073 #
74 # Initialization routines
75 #
Guido van Rossum13c503e1995-03-16 15:58:12 +000076 def open(self, name, mode='r', bufsize=-1):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000077 import __builtin__
78 return self.fileopen(__builtin__.open(name, mode, bufsize))
Guido van Rossum78f8dea1994-05-18 11:07:44 +000079
Guido van Rossumc762bec1994-05-18 11:08:10 +000080 def fileopen(self, file):
Tim Peters22cd7682001-09-18 05:40:24 +000081 import types
Walter Dörwald70a6b492004-02-12 17:35:32 +000082 if repr(type(file)) != "<type 'file'>":
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000083 raise TypeError, 'posixfile.fileopen() arg must be file object'
84 self._file_ = file
85 # Copy basic file methods
Tim Peters22cd7682001-09-18 05:40:24 +000086 for maybemethod in dir(file):
87 if not maybemethod.startswith('_'):
88 attr = getattr(file, maybemethod)
89 if isinstance(attr, types.BuiltinMethodType):
90 setattr(self, maybemethod, attr)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 return self
Guido van Rossum78f8dea1994-05-18 11:07:44 +000092
93 #
94 # New methods
95 #
96 def file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000097 return self._file_
Guido van Rossum78f8dea1994-05-18 11:07:44 +000098
99 def dup(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000100 import posix
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000101
Guido van Rossume9901f32001-04-10 15:44:33 +0000102 if not hasattr(posix, 'fdopen'):
103 raise AttributeError, 'dup() method unavailable'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000104
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000105 return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000106
107 def dup2(self, fd):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000108 import posix
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000109
Guido van Rossume9901f32001-04-10 15:44:33 +0000110 if not hasattr(posix, 'fdopen'):
111 raise AttributeError, 'dup() method unavailable'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000112
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000113 posix.dup2(self._file_.fileno(), fd)
114 return posix.fdopen(fd, self._file_.mode)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000115
Guido van Rossumc762bec1994-05-18 11:08:10 +0000116 def flags(self, *which):
Andrew M. Kuchling86c7e222001-08-13 14:47:12 +0000117 import fcntl, os
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000118
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000119 if which:
120 if len(which) > 1:
121 raise TypeError, 'Too many arguments'
122 which = which[0]
123 else: which = '?'
Guido van Rossumc762bec1994-05-18 11:08:10 +0000124
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000125 l_flags = 0
Fred Drakea94414a2001-05-10 15:33:31 +0000126 if 'n' in which: l_flags = l_flags | os.O_NDELAY
127 if 'a' in which: l_flags = l_flags | os.O_APPEND
128 if 's' in which: l_flags = l_flags | os.O_SYNC
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000129
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000130 file = self._file_
Guido van Rossumc762bec1994-05-18 11:08:10 +0000131
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000132 if '=' not in which:
Fred Drakea94414a2001-05-10 15:33:31 +0000133 cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000134 if '!' in which: l_flags = cur_fl & ~ l_flags
135 else: l_flags = cur_fl | l_flags
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000136
Fred Drakea94414a2001-05-10 15:33:31 +0000137 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000138
Tim Peters2344fae2001-01-15 00:50:52 +0000139 if 'c' in which:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000140 arg = ('!' not in which) # 0 is don't, 1 is do close on exec
Fred Drakea94414a2001-05-10 15:33:31 +0000141 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000142
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000143 if '?' in which:
144 which = '' # Return current flags
Fred Drakea94414a2001-05-10 15:33:31 +0000145 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
146 if os.O_APPEND & l_flags: which = which + 'a'
147 if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000148 which = which + 'c'
Fred Drakea94414a2001-05-10 15:33:31 +0000149 if os.O_NDELAY & l_flags: which = which + 'n'
150 if os.O_SYNC & l_flags: which = which + 's'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000151 return which
Tim Peters2344fae2001-01-15 00:50:52 +0000152
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000153 def lock(self, how, *args):
Fred Drakea94414a2001-05-10 15:33:31 +0000154 import struct, fcntl
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000155
Fred Drakea94414a2001-05-10 15:33:31 +0000156 if 'w' in how: l_type = fcntl.F_WRLCK
157 elif 'r' in how: l_type = fcntl.F_RDLCK
158 elif 'u' in how: l_type = fcntl.F_UNLCK
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000159 else: raise TypeError, 'no type of lock specified'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000160
Fred Drakea94414a2001-05-10 15:33:31 +0000161 if '|' in how: cmd = fcntl.F_SETLKW
162 elif '?' in how: cmd = fcntl.F_GETLK
163 else: cmd = fcntl.F_SETLK
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000164
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000165 l_whence = 0
166 l_start = 0
167 l_len = 0
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000168
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 if len(args) == 1:
170 l_len = args[0]
171 elif len(args) == 2:
172 l_len, l_start = args
173 elif len(args) == 3:
174 l_len, l_start, l_whence = args
175 elif len(args) > 3:
176 raise TypeError, 'too many arguments'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000177
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000178 # Hack by davem@magnet.com to get locking to go on freebsd;
179 # additions for AIX by Vladimir.Marangozov@imag.fr
Guido van Rossum7698d121996-07-30 16:28:45 +0000180 import sys, os
Guido van Rossum027188a1999-02-23 04:14:32 +0000181 if sys.platform in ('netbsd1',
Guido van Rossum5274c331999-12-06 14:51:05 +0000182 'openbsd2',
Guido van Rossum2d218632000-08-29 14:57:27 +0000183 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
Hye-Shik Changea684742007-10-28 12:38:09 +0000184 'freebsd6', 'freebsd7', 'freebsd8',
Hye-Shik Chang4e422812005-07-17 02:36:59 +0000185 'bsdos2', 'bsdos3', 'bsdos4'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000186 flock = struct.pack('lxxxxlxxxxlhh', \
Tim Peters2344fae2001-01-15 00:50:52 +0000187 l_start, l_len, os.getpid(), l_type, l_whence)
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000188 elif sys.platform in ('aix3', 'aix4'):
Guido van Rossum0f6a3bf1996-08-20 20:23:34 +0000189 flock = struct.pack('hhlllii', \
190 l_type, l_whence, l_start, l_len, 0, 0, 0)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000191 else:
192 flock = struct.pack('hhllhh', \
193 l_type, l_whence, l_start, l_len, 0, 0)
Guido van Rossum7698d121996-07-30 16:28:45 +0000194
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000195 flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000196
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000197 if '?' in how:
Guido van Rossum027188a1999-02-23 04:14:32 +0000198 if sys.platform in ('netbsd1',
Guido van Rossum5274c331999-12-06 14:51:05 +0000199 'openbsd2',
Guido van Rossum2d218632000-08-29 14:57:27 +0000200 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
Guido van Rossum027188a1999-02-23 04:14:32 +0000201 'bsdos2', 'bsdos3', 'bsdos4'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000202 l_start, l_len, l_pid, l_type, l_whence = \
203 struct.unpack('lxxxxlxxxxlhh', flock)
Raymond Hettingerdbecd932005-02-06 06:57:08 +0000204 elif sys.platform in ('aix3', 'aix4'):
Guido van Rossum0f6a3bf1996-08-20 20:23:34 +0000205 l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
206 struct.unpack('hhlllii', flock)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000207 elif sys.platform == "linux2":
208 l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
209 struct.unpack('hhllhh', flock)
210 else:
211 l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
212 struct.unpack('hhllhh', flock)
Guido van Rossum7698d121996-07-30 16:28:45 +0000213
Fred Drakea94414a2001-05-10 15:33:31 +0000214 if l_type != fcntl.F_UNLCK:
215 if l_type == fcntl.F_RDLCK:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000216 return 'r', l_len, l_start, l_whence, l_pid
217 else:
218 return 'w', l_len, l_start, l_whence, l_pid
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000219
Guido van Rossum28aa2291995-03-23 10:39:49 +0000220def open(name, mode='r', bufsize=-1):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000221 """Public routine to open a file as a posixfile object."""
Guido van Rossum28aa2291995-03-23 10:39:49 +0000222 return _posixfile_().open(name, mode, bufsize)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000223
Guido van Rossumc762bec1994-05-18 11:08:10 +0000224def fileopen(file):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000225 """Public routine to get a posixfile object from a Python file object."""
Guido van Rossumc762bec1994-05-18 11:08:10 +0000226 return _posixfile_().fileopen(file)
227
228#
229# Constants
230#
231SEEK_SET = 0
232SEEK_CUR = 1
233SEEK_END = 2
234
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000235#
236# End of posixfile.py
237#