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):
78 if `
type(file)`
!= "<type 'file'>":
79 raise TypeError, 'posixfile.fileopen() arg must be file object'
81 # Copy basic file methods
82 for method
in file.__methods
__:
83 setattr(self
, method
, getattr(file, method
))
95 if not hasattr(posix
, 'fdopen'):
96 raise AttributeError, 'dup() method unavailable'
98 return posix
.fdopen(posix
.dup(self
._file
_.fileno()), self
._file
_.mode
)
103 if not hasattr(posix
, 'fdopen'):
104 raise AttributeError, 'dup() method unavailable'
106 posix
.dup2(self
._file
_.fileno(), fd
)
107 return posix
.fdopen(fd
, self
._file
_.mode
)
109 def flags(self
, *which
):
114 raise TypeError, 'Too many arguments'
119 if 'n' in which
: l_flags
= l_flags | os
.O_NDELAY
120 if 'a' in which
: l_flags
= l_flags | os
.O_APPEND
121 if 's' in which
: l_flags
= l_flags | os
.O_SYNC
126 cur_fl
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
127 if '!' in which
: l_flags
= cur_fl
& ~ l_flags
128 else: l_flags
= cur_fl | l_flags
130 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFL
, l_flags
)
133 arg
= ('!' not in which
) # 0 is don't, 1 is do close on exec
134 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_SETFD
, arg
)
137 which
= '' # Return current flags
138 l_flags
= fcntl
.fcntl(file.fileno(), fcntl
.F_GETFL
, 0)
139 if os
.O_APPEND
& l_flags
: which
= which
+ 'a'
140 if fcntl
.fcntl(file.fileno(), fcntl
.F_GETFD
, 0) & 1:
142 if os
.O_NDELAY
& l_flags
: which
= which
+ 'n'
143 if os
.O_SYNC
& l_flags
: which
= which
+ 's'
146 def lock(self
, how
, *args
):
149 if 'w' in how
: l_type
= fcntl
.F_WRLCK
150 elif 'r' in how
: l_type
= fcntl
.F_RDLCK
151 elif 'u' in how
: l_type
= fcntl
.F_UNLCK
152 else: raise TypeError, 'no type of lock specified'
154 if '|' in how
: cmd
= fcntl
.F_SETLKW
155 elif '?' in how
: cmd
= fcntl
.F_GETLK
156 else: cmd
= fcntl
.F_SETLK
165 l_len
, l_start
= args
167 l_len
, l_start
, l_whence
= args
169 raise TypeError, 'too many arguments'
171 # Hack by davem@magnet.com to get locking to go on freebsd;
172 # additions for AIX by Vladimir.Marangozov@imag.fr
174 if sys
.platform
in ('netbsd1',
176 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
177 'bsdos2', 'bsdos3', 'bsdos4'):
178 flock
= struct
.pack('lxxxxlxxxxlhh', \
179 l_start
, l_len
, os
.getpid(), l_type
, l_whence
)
180 elif sys
.platform
in ['aix3', 'aix4']:
181 flock
= struct
.pack('hhlllii', \
182 l_type
, l_whence
, l_start
, l_len
, 0, 0, 0)
184 flock
= struct
.pack('hhllhh', \
185 l_type
, l_whence
, l_start
, l_len
, 0, 0)
187 flock
= fcntl
.fcntl(self
._file
_.fileno(), cmd
, flock
)
190 if sys
.platform
in ('netbsd1',
192 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
193 'bsdos2', 'bsdos3', 'bsdos4'):
194 l_start
, l_len
, l_pid
, l_type
, l_whence
= \
195 struct
.unpack('lxxxxlxxxxlhh', flock
)
196 elif sys
.platform
in ['aix3', 'aix4']:
197 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
, l_vfs
= \
198 struct
.unpack('hhlllii', flock
)
199 elif sys
.platform
== "linux2":
200 l_type
, l_whence
, l_start
, l_len
, l_pid
, l_sysid
= \
201 struct
.unpack('hhllhh', flock
)
203 l_type
, l_whence
, l_start
, l_len
, l_sysid
, l_pid
= \
204 struct
.unpack('hhllhh', flock
)
206 if l_type
!= fcntl
.F_UNLCK
:
207 if l_type
== fcntl
.F_RDLCK
:
208 return 'r', l_len
, l_start
, l_whence
, l_pid
210 return 'w', l_len
, l_start
, l_whence
, l_pid
212 def open(name
, mode
='r', bufsize
=-1):
213 """Public routine to open a file as a posixfile object."""
214 return _posixfile_().open(name
, mode
, bufsize
)
217 """Public routine to get a posixfile object from a Python file object."""
218 return _posixfile_().fileopen(file)
228 # End of posixfile.py