blob: e2eb02478115a4cf19c30cc4d6d74c8009ddf1a0 [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"""
Guido van Rossum78f8dea1994-05-18 11:07:44 +000055
Fred Drake9242a4a2001-10-24 22:03:35 +000056import warnings
57warnings.warn(
58 "The posixfile module is obsolete and will disappear in the future",
59 DeprecationWarning)
60del warnings
61
62
Guido van Rossum78f8dea1994-05-18 11:07:44 +000063class _posixfile_:
Guido van Rossum54f22ed2000-02-04 15:10:34 +000064 """File wrapper class that provides extra POSIX file routines."""
65
Guido van Rossumc762bec1994-05-18 11:08:10 +000066 states = ['open', 'closed']
67
Guido van Rossum78f8dea1994-05-18 11:07:44 +000068 #
69 # Internal routines
70 #
71 def __repr__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000072 file = self._file_
73 return "<%s posixfile '%s', mode '%s' at %s>" % \
74 (self.states[file.closed], file.name, file.mode, \
75 hex(id(self))[2:])
Guido van Rossum78f8dea1994-05-18 11:07:44 +000076
Guido van Rossum78f8dea1994-05-18 11:07:44 +000077 #
78 # Initialization routines
79 #
Guido van Rossum13c503e1995-03-16 15:58:12 +000080 def open(self, name, mode='r', bufsize=-1):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 import __builtin__
82 return self.fileopen(__builtin__.open(name, mode, bufsize))
Guido van Rossum78f8dea1994-05-18 11:07:44 +000083
Guido van Rossumc762bec1994-05-18 11:08:10 +000084 def fileopen(self, file):
Tim Peters22cd7682001-09-18 05:40:24 +000085 import types
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000086 if `type(file)` != "<type 'file'>":
87 raise TypeError, 'posixfile.fileopen() arg must be file object'
88 self._file_ = file
89 # Copy basic file methods
Tim Peters22cd7682001-09-18 05:40:24 +000090 for maybemethod in dir(file):
91 if not maybemethod.startswith('_'):
92 attr = getattr(file, maybemethod)
93 if isinstance(attr, types.BuiltinMethodType):
94 setattr(self, maybemethod, attr)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000095 return self
Guido van Rossum78f8dea1994-05-18 11:07:44 +000096
97 #
98 # New methods
99 #
100 def file(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000101 return self._file_
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000102
103 def dup(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000104 import posix
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000105
Guido van Rossume9901f32001-04-10 15:44:33 +0000106 if not hasattr(posix, 'fdopen'):
107 raise AttributeError, 'dup() method unavailable'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000108
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000109 return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000110
111 def dup2(self, fd):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000112 import posix
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000113
Guido van Rossume9901f32001-04-10 15:44:33 +0000114 if not hasattr(posix, 'fdopen'):
115 raise AttributeError, 'dup() method unavailable'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000116
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000117 posix.dup2(self._file_.fileno(), fd)
118 return posix.fdopen(fd, self._file_.mode)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000119
Guido van Rossumc762bec1994-05-18 11:08:10 +0000120 def flags(self, *which):
Andrew M. Kuchling86c7e222001-08-13 14:47:12 +0000121 import fcntl, os
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000122
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000123 if which:
124 if len(which) > 1:
125 raise TypeError, 'Too many arguments'
126 which = which[0]
127 else: which = '?'
Guido van Rossumc762bec1994-05-18 11:08:10 +0000128
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000129 l_flags = 0
Fred Drakea94414a2001-05-10 15:33:31 +0000130 if 'n' in which: l_flags = l_flags | os.O_NDELAY
131 if 'a' in which: l_flags = l_flags | os.O_APPEND
132 if 's' in which: l_flags = l_flags | os.O_SYNC
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000133
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000134 file = self._file_
Guido van Rossumc762bec1994-05-18 11:08:10 +0000135
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000136 if '=' not in which:
Fred Drakea94414a2001-05-10 15:33:31 +0000137 cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000138 if '!' in which: l_flags = cur_fl & ~ l_flags
139 else: l_flags = cur_fl | l_flags
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000140
Fred Drakea94414a2001-05-10 15:33:31 +0000141 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000142
Tim Peters2344fae2001-01-15 00:50:52 +0000143 if 'c' in which:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000144 arg = ('!' not in which) # 0 is don't, 1 is do close on exec
Fred Drakea94414a2001-05-10 15:33:31 +0000145 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000146
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000147 if '?' in which:
148 which = '' # Return current flags
Fred Drakea94414a2001-05-10 15:33:31 +0000149 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
150 if os.O_APPEND & l_flags: which = which + 'a'
151 if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000152 which = which + 'c'
Fred Drakea94414a2001-05-10 15:33:31 +0000153 if os.O_NDELAY & l_flags: which = which + 'n'
154 if os.O_SYNC & l_flags: which = which + 's'
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000155 return which
Tim Peters2344fae2001-01-15 00:50:52 +0000156
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000157 def lock(self, how, *args):
Fred Drakea94414a2001-05-10 15:33:31 +0000158 import struct, fcntl
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000159
Fred Drakea94414a2001-05-10 15:33:31 +0000160 if 'w' in how: l_type = fcntl.F_WRLCK
161 elif 'r' in how: l_type = fcntl.F_RDLCK
162 elif 'u' in how: l_type = fcntl.F_UNLCK
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000163 else: raise TypeError, 'no type of lock specified'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000164
Fred Drakea94414a2001-05-10 15:33:31 +0000165 if '|' in how: cmd = fcntl.F_SETLKW
166 elif '?' in how: cmd = fcntl.F_GETLK
167 else: cmd = fcntl.F_SETLK
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000168
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 l_whence = 0
170 l_start = 0
171 l_len = 0
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000172
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000173 if len(args) == 1:
174 l_len = args[0]
175 elif len(args) == 2:
176 l_len, l_start = args
177 elif len(args) == 3:
178 l_len, l_start, l_whence = args
179 elif len(args) > 3:
180 raise TypeError, 'too many arguments'
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000181
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000182 # Hack by davem@magnet.com to get locking to go on freebsd;
183 # additions for AIX by Vladimir.Marangozov@imag.fr
Guido van Rossum7698d121996-07-30 16:28:45 +0000184 import sys, os
Guido van Rossum027188a1999-02-23 04:14:32 +0000185 if sys.platform in ('netbsd1',
Guido van Rossum5274c331999-12-06 14:51:05 +0000186 'openbsd2',
Guido van Rossum2d218632000-08-29 14:57:27 +0000187 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
Guido van Rossum027188a1999-02-23 04:14:32 +0000188 'bsdos2', 'bsdos3', 'bsdos4'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000189 flock = struct.pack('lxxxxlxxxxlhh', \
Tim Peters2344fae2001-01-15 00:50:52 +0000190 l_start, l_len, os.getpid(), l_type, l_whence)
Guido van Rossum0f6a3bf1996-08-20 20:23:34 +0000191 elif sys.platform in ['aix3', 'aix4']:
192 flock = struct.pack('hhlllii', \
193 l_type, l_whence, l_start, l_len, 0, 0, 0)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000194 else:
195 flock = struct.pack('hhllhh', \
196 l_type, l_whence, l_start, l_len, 0, 0)
Guido van Rossum7698d121996-07-30 16:28:45 +0000197
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000198 flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000199
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000200 if '?' in how:
Guido van Rossum027188a1999-02-23 04:14:32 +0000201 if sys.platform in ('netbsd1',
Guido van Rossum5274c331999-12-06 14:51:05 +0000202 'openbsd2',
Guido van Rossum2d218632000-08-29 14:57:27 +0000203 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
Guido van Rossum027188a1999-02-23 04:14:32 +0000204 'bsdos2', 'bsdos3', 'bsdos4'):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000205 l_start, l_len, l_pid, l_type, l_whence = \
206 struct.unpack('lxxxxlxxxxlhh', flock)
Guido van Rossum0f6a3bf1996-08-20 20:23:34 +0000207 elif sys.platform in ['aix3', 'aix4']:
208 l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
209 struct.unpack('hhlllii', flock)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000210 elif sys.platform == "linux2":
211 l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
212 struct.unpack('hhllhh', flock)
213 else:
214 l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
215 struct.unpack('hhllhh', flock)
Guido van Rossum7698d121996-07-30 16:28:45 +0000216
Fred Drakea94414a2001-05-10 15:33:31 +0000217 if l_type != fcntl.F_UNLCK:
218 if l_type == fcntl.F_RDLCK:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000219 return 'r', l_len, l_start, l_whence, l_pid
220 else:
221 return 'w', l_len, l_start, l_whence, l_pid
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000222
Guido van Rossum28aa2291995-03-23 10:39:49 +0000223def open(name, mode='r', bufsize=-1):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000224 """Public routine to open a file as a posixfile object."""
Guido van Rossum28aa2291995-03-23 10:39:49 +0000225 return _posixfile_().open(name, mode, bufsize)
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000226
Guido van Rossumc762bec1994-05-18 11:08:10 +0000227def fileopen(file):
Guido van Rossum54f22ed2000-02-04 15:10:34 +0000228 """Public routine to get a posixfile object from a Python file object."""
Guido van Rossumc762bec1994-05-18 11:08:10 +0000229 return _posixfile_().fileopen(file)
230
231#
232# Constants
233#
234SEEK_SET = 0
235SEEK_CUR = 1
236SEEK_END = 2
237
Guido van Rossum78f8dea1994-05-18 11:07:44 +0000238#
239# End of posixfile.py
240#