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
58 """File wrapper class that provides extra POSIX file routines."""
60 states
= ['open', 'closed']
67 return "<%s posixfile '%s', mode '%s' at %s>" % \
68 (self
.states
[file.closed
], file.name
, file.mode
, \
72 # Initialization routines
74 def open(self
, name
, mode
='r', bufsize
=-1):
76 return self
.fileopen(__builtin__
.open(name
, mode
, bufsize
))
78 def fileopen(self
, file):
80 if repr(type(file)) != "<type 'file'>":
81 raise TypeError, 'posixfile.fileopen() arg must be file object'
83 # Copy basic file methods
84 for maybemethod
in dir(file):
85 if not maybemethod
.startswith('_'):
86 attr
= getattr(file, maybemethod
)
87 if isinstance(attr
, types
.BuiltinMethodType
):
88 setattr(self
, maybemethod
, attr
)
100 if not hasattr(posix
, 'fdopen'):
101 raise AttributeError, 'dup() method unavailable'
103 return posix
.fdopen(posix
.dup(self
._file
_.fileno()), self
._file
_.mode
)
108 if not hasattr(posix
, 'fdopen'):
109 raise AttributeError, 'dup() method unavailable'
111 posix
.dup2(self
._file
_.fileno(), fd
)
112 return posix
.fdopen(fd
, self
._file
_.mode
)
114 def flags(self
, *which
):
119 raise TypeError, 'Too many arguments'
124 if 'n' in which
: l_flags
= l_flags | os
.O_NDELAY
125 if 'a' in which
: l_flags
= l_flags | os
.O_APPEND
126 if 's' in which
: l_flags
= l_flags | os
.O_SYNC
131 cur_fl
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
132 if '!' in which
: l_flags
= cur_fl
& ~ l_flags
133 else: l_flags
= cur_fl | l_flags
135 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFL
, l_flags
)
138 arg
= ('!' not in which
) # 0 is don't, 1 is do close on exec
139 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFD
, arg
)
142 which
= '' # Return current flags
143 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
144 if os
.O_APPEND
& l_flags
: which
= which
+ 'a'
145 if fcntl
.fcntl(file.fileno(), fcntl
.F_GETFD
, 0) & 1:
147 if os
.O_NDELAY
& l_flags
: which
= which
+ 'n'
148 if os
.O_SYNC
& l_flags
: which
= which
+ 's'
151 def lock(self
, how
, *args
):
154 if 'w' in how
: l_type
= fcntl
.F_WRLCK
155 elif 'r' in how
: l_type
= fcntl
.F_RDLCK
156 elif 'u' in how
: l_type
= fcntl
.F_UNLCK
157 else: raise TypeError, 'no type of lock specified'
159 if '|' in how
: cmd
= fcntl
.F_SETLKW
160 elif '?' in how
: cmd
= fcntl
.F_GETLK
161 else: cmd
= fcntl
.F_SETLK
170 l_len
, l_start
= args
172 l_len
, l_start
, l_whence
= args
174 raise TypeError, 'too many arguments'
176 # Hack by davem@magnet.com to get locking to go on freebsd;
177 # additions for AIX by Vladimir.Marangozov@imag.fr
179 if sys
.platform
in ('netbsd1',
181 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
182 'freebsd6', 'freebsd7',
183 'bsdos2', 'bsdos3', 'bsdos4'):
184 flock
= struct
.pack('lxxxxlxxxxlhh', \
185 l_start
, l_len
, os
.getpid(), l_type
, l_whence
)
186 elif sys
.platform
in ('aix3', 'aix4'):
187 flock
= struct
.pack('hhlllii', \
188 l_type
, l_whence
, l_start
, l_len
, 0, 0, 0)
190 flock
= struct
.pack('hhllhh', \
191 l_type
, l_whence
, l_start
, l_len
, 0, 0)
193 flock
= fcntl
.fcntl(self
._file
_.fileno(), cmd
, flock
)
196 if sys
.platform
in ('netbsd1',
198 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
199 'bsdos2', 'bsdos3', 'bsdos4'):
200 l_start
, l_len
, l_pid
, l_type
, l_whence
= \
201 struct
.unpack('lxxxxlxxxxlhh', flock
)
202 elif sys
.platform
in ('aix3', 'aix4'):
203 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
, l_vfs
= \
204 struct
.unpack('hhlllii', flock
)
205 elif sys
.platform
== "linux2":
206 l_type
, l_whence
, l_start
, l_len
, l_pid
, l_sysid
= \
207 struct
.unpack('hhllhh', flock
)
209 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
= \
210 struct
.unpack('hhllhh', flock
)
212 if l_type
!= fcntl
.F_UNLCK
:
213 if l_type
== fcntl
.F_RDLCK
:
214 return 'r', l_len
, l_start
, l_whence
, l_pid
216 return 'w', l_len
, l_start
, l_whence
, l_pid
218 def open(name
, mode
='r', bufsize
=-1):
219 """Public routine to open a file as a posixfile object."""
220 return _posixfile_().open(name
, mode
, bufsize
)
223 """Public routine to get a posixfile object from a Python file object."""
224 return _posixfile_().fileopen(file)
234 # End of posixfile.py