1 """Extended file operations available in POSIX.
3 f = posixfile.open(filename, [mode, [bufsize]])
4 will create a new posixfile object
6 f = posixfile.fileopen(fileobject)
7 will create a posixfile object from a builtin file object
10 will return the original builtin file object
13 will return a new file object based on a new filedescriptor
16 will return a new file object based on the given filedescriptor
19 will turn on the associated flag (merge)
20 mode can contain the following characters:
22 (character representing a flag)
26 s synchronization flag
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
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
37 f.lock(mode [, len [, start [, whence]]])
38 will (un)lock a region
39 mode can contain the following characters:
41 (character representing type of lock)
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')
52 note: - the '?' modifier prevents a region from being locked; it is
57 """File wrapper class that provides extra POSIX file routines."""
59 states
= ['open', 'closed']
66 return "<%s posixfile '%s', mode '%s' at %s>" % \
67 (self
.states
[file.closed
], file.name
, file.mode
, \
71 # Initialization routines
73 def open(self
, name
, mode
='r', bufsize
=-1):
75 return self
.fileopen(__builtin__
.open(name
, mode
, bufsize
))
77 def fileopen(self
, file):
79 if `
type(file)`
!= "<type 'file'>":
80 raise TypeError, 'posixfile.fileopen() arg must be file object'
82 # Copy basic file methods
83 for maybemethod
in dir(file):
84 if not maybemethod
.startswith('_'):
85 attr
= getattr(file, maybemethod
)
86 if isinstance(attr
, types
.BuiltinMethodType
):
87 setattr(self
, maybemethod
, attr
)
99 if not hasattr(posix
, 'fdopen'):
100 raise AttributeError, 'dup() method unavailable'
102 return posix
.fdopen(posix
.dup(self
._file
_.fileno()), self
._file
_.mode
)
107 if not hasattr(posix
, 'fdopen'):
108 raise AttributeError, 'dup() method unavailable'
110 posix
.dup2(self
._file
_.fileno(), fd
)
111 return posix
.fdopen(fd
, self
._file
_.mode
)
113 def flags(self
, *which
):
118 raise TypeError, 'Too many arguments'
123 if 'n' in which
: l_flags
= l_flags | os
.O_NDELAY
124 if 'a' in which
: l_flags
= l_flags | os
.O_APPEND
125 if 's' in which
: l_flags
= l_flags | os
.O_SYNC
130 cur_fl
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
131 if '!' in which
: l_flags
= cur_fl
& ~ l_flags
132 else: l_flags
= cur_fl | l_flags
134 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFL
, l_flags
)
137 arg
= ('!' not in which
) # 0 is don't, 1 is do close on exec
138 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFD
, arg
)
141 which
= '' # Return current flags
142 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
143 if os
.O_APPEND
& l_flags
: which
= which
+ 'a'
144 if fcntl
.fcntl(file.fileno(), fcntl
.F_GETFD
, 0) & 1:
146 if os
.O_NDELAY
& l_flags
: which
= which
+ 'n'
147 if os
.O_SYNC
& l_flags
: which
= which
+ 's'
150 def lock(self
, how
, *args
):
153 if 'w' in how
: l_type
= fcntl
.F_WRLCK
154 elif 'r' in how
: l_type
= fcntl
.F_RDLCK
155 elif 'u' in how
: l_type
= fcntl
.F_UNLCK
156 else: raise TypeError, 'no type of lock specified'
158 if '|' in how
: cmd
= fcntl
.F_SETLKW
159 elif '?' in how
: cmd
= fcntl
.F_GETLK
160 else: cmd
= fcntl
.F_SETLK
169 l_len
, l_start
= args
171 l_len
, l_start
, l_whence
= args
173 raise TypeError, 'too many arguments'
175 # Hack by davem@magnet.com to get locking to go on freebsd;
176 # additions for AIX by Vladimir.Marangozov@imag.fr
178 if sys
.platform
in ('netbsd1',
180 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
181 'bsdos2', 'bsdos3', 'bsdos4'):
182 flock
= struct
.pack('lxxxxlxxxxlhh', \
183 l_start
, l_len
, os
.getpid(), l_type
, l_whence
)
184 elif sys
.platform
in ['aix3', 'aix4']:
185 flock
= struct
.pack('hhlllii', \
186 l_type
, l_whence
, l_start
, l_len
, 0, 0, 0)
188 flock
= struct
.pack('hhllhh', \
189 l_type
, l_whence
, l_start
, l_len
, 0, 0)
191 flock
= fcntl
.fcntl(self
._file
_.fileno(), cmd
, flock
)
194 if sys
.platform
in ('netbsd1',
196 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
197 'bsdos2', 'bsdos3', 'bsdos4'):
198 l_start
, l_len
, l_pid
, l_type
, l_whence
= \
199 struct
.unpack('lxxxxlxxxxlhh', flock
)
200 elif sys
.platform
in ['aix3', 'aix4']:
201 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
, l_vfs
= \
202 struct
.unpack('hhlllii', flock
)
203 elif sys
.platform
== "linux2":
204 l_type
, l_whence
, l_start
, l_len
, l_pid
, l_sysid
= \
205 struct
.unpack('hhllhh', flock
)
207 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
= \
208 struct
.unpack('hhllhh', flock
)
210 if l_type
!= fcntl
.F_UNLCK
:
211 if l_type
== fcntl
.F_RDLCK
:
212 return 'r', l_len
, l_start
, l_whence
, l_pid
214 return 'w', l_len
, l_start
, l_whence
, l_pid
216 def open(name
, mode
='r', bufsize
=-1):
217 """Public routine to open a file as a posixfile object."""
218 return _posixfile_().open(name
, mode
, bufsize
)
221 """Public routine to get a posixfile object from a Python file object."""
222 return _posixfile_().fileopen(file)
232 # End of posixfile.py