source: python/trunk/Lib/posixfile.py@ 394

Last change on this file since 394 was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1"""Extended file operations available in POSIX.
2
3f = 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"""
55import warnings
56warnings.warn("The posixfile module is deprecated; "
57 "fcntl.lockf() provides better locking", DeprecationWarning, 2)
58
59class _posixfile_:
60 """File wrapper class that provides extra POSIX file routines."""
61
62 states = ['open', 'closed']
63
64 #
65 # Internal routines
66 #
67 def __repr__(self):
68 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:])
72
73 #
74 # Initialization routines
75 #
76 def open(self, name, mode='r', bufsize=-1):
77 import __builtin__
78 return self.fileopen(__builtin__.open(name, mode, bufsize))
79
80 def fileopen(self, file):
81 import types
82 if repr(type(file)) != "<type 'file'>":
83 raise TypeError, 'posixfile.fileopen() arg must be file object'
84 self._file_ = file
85 # Copy basic file methods
86 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)
91 return self
92
93 #
94 # New methods
95 #
96 def file(self):
97 return self._file_
98
99 def dup(self):
100 import posix
101
102 if not hasattr(posix, 'fdopen'):
103 raise AttributeError, 'dup() method unavailable'
104
105 return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
106
107 def dup2(self, fd):
108 import posix
109
110 if not hasattr(posix, 'fdopen'):
111 raise AttributeError, 'dup() method unavailable'
112
113 posix.dup2(self._file_.fileno(), fd)
114 return posix.fdopen(fd, self._file_.mode)
115
116 def flags(self, *which):
117 import fcntl, os
118
119 if which:
120 if len(which) > 1:
121 raise TypeError, 'Too many arguments'
122 which = which[0]
123 else: which = '?'
124
125 l_flags = 0
126 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
129
130 file = self._file_
131
132 if '=' not in which:
133 cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
134 if '!' in which: l_flags = cur_fl & ~ l_flags
135 else: l_flags = cur_fl | l_flags
136
137 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
138
139 if 'c' in which:
140 arg = ('!' not in which) # 0 is don't, 1 is do close on exec
141 l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
142
143 if '?' in which:
144 which = '' # Return current flags
145 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:
148 which = which + 'c'
149 if os.O_NDELAY & l_flags: which = which + 'n'
150 if os.O_SYNC & l_flags: which = which + 's'
151 return which
152
153 def lock(self, how, *args):
154 import struct, fcntl
155
156 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
159 else: raise TypeError, 'no type of lock specified'
160
161 if '|' in how: cmd = fcntl.F_SETLKW
162 elif '?' in how: cmd = fcntl.F_GETLK
163 else: cmd = fcntl.F_SETLK
164
165 l_whence = 0
166 l_start = 0
167 l_len = 0
168
169 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'
177
178 # Hack by davem@magnet.com to get locking to go on freebsd;
179 # additions for AIX by Vladimir.Marangozov@imag.fr
180 import sys, os
181 if sys.platform in ('netbsd1',
182 'openbsd2',
183 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
184 'freebsd6', 'freebsd7', 'freebsd8',
185 'bsdos2', 'bsdos3', 'bsdos4'):
186 flock = struct.pack('lxxxxlxxxxlhh', \
187 l_start, l_len, os.getpid(), l_type, l_whence)
188 elif sys.platform in ('aix3', 'aix4'):
189 flock = struct.pack('hhlllii', \
190 l_type, l_whence, l_start, l_len, 0, 0, 0)
191 else:
192 flock = struct.pack('hhllhh', \
193 l_type, l_whence, l_start, l_len, 0, 0)
194
195 flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
196
197 if '?' in how:
198 if sys.platform in ('netbsd1',
199 'openbsd2',
200 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
201 'bsdos2', 'bsdos3', 'bsdos4'):
202 l_start, l_len, l_pid, l_type, l_whence = \
203 struct.unpack('lxxxxlxxxxlhh', flock)
204 elif sys.platform in ('aix3', 'aix4'):
205 l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
206 struct.unpack('hhlllii', flock)
207 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)
213
214 if l_type != fcntl.F_UNLCK:
215 if l_type == fcntl.F_RDLCK:
216 return 'r', l_len, l_start, l_whence, l_pid
217 else:
218 return 'w', l_len, l_start, l_whence, l_pid
219
220def open(name, mode='r', bufsize=-1):
221 """Public routine to open a file as a posixfile object."""
222 return _posixfile_().open(name, mode, bufsize)
223
224def fileopen(file):
225 """Public routine to get a posixfile object from a Python file object."""
226 return _posixfile_().fileopen(file)
227
228#
229# Constants
230#
231SEEK_SET = 0
232SEEK_CUR = 1
233SEEK_END = 2
234
235#
236# End of posixfile.py
237#
Note: See TracBrowser for help on using the repository browser.