2 # Start of posixfile.py
6 # Extended file operations
8 # f = posixfile.open(filename, [mode, [bufsize]])
9 # will create a new posixfile object
11 # f = posixfile.fileopen(fileobject)
12 # will create a posixfile object from a builtin file object
15 # will return the original builtin file object
18 # will return a new file object based on a new filedescriptor
21 # will return a new file object based on the given filedescriptor
24 # will turn on the associated flag (merge)
25 # mode can contain the following characters:
27 # (character representing a flag)
29 # c close on exec flag
31 # s synchronization flag
33 # ! turn flags 'off' instead of default 'on'
34 # = copy flags 'as is' instead of default 'merge'
35 # ? return a string in which the characters represent the flags
38 # note: - the '!' and '=' modifiers are mutually exclusive.
39 # - the '?' modifier will return the status of the flags after they
40 # have been changed by other characters in the mode string
42 # f.lock(mode [, len [, start [, whence]]])
43 # will (un)lock a region
44 # mode can contain the following characters:
46 # (character representing type of lock)
51 # | wait until the lock can be granted
52 # ? return the first lock conflicting with the requested lock
53 # or 'None' if there is no conflict. The lock returned is in the
54 # format (mode, len, start, whence, pid) where mode is a
55 # character representing the type of lock ('r' or 'w')
57 # note: - the '?' modifier prevents a region from being locked; it is
62 states
= ['open', 'closed']
69 return "<%s posixfile '%s', mode '%s' at %s>" % \
70 (self
.states
[file.closed
], file.name
, file.mode
, \
77 # Initialization routines
79 def open(self
, name
, mode
='r', bufsize
=-1):
81 return self
.fileopen(__builtin__
.open(name
, mode
, bufsize
))
83 def fileopen(self
, file):
84 if `
type(file)`
!= "<type 'file'>":
85 raise TypeError, 'posixfile.fileopen() arg must be file object'
87 # Copy basic file methods
88 for method
in file.__methods
__:
89 setattr(self
, method
, getattr(file, method
))
101 try: ignore
= posix
.fdopen
102 except: raise AttributeError, 'dup() method unavailable'
104 return posix
.fdopen(posix
.dup(self
._file
_.fileno()), self
._file
_.mode
)
109 try: ignore
= posix
.fdopen
110 except: raise AttributeError, 'dup() method unavailable'
112 posix
.dup2(self
._file
_.fileno(), fd
)
113 return posix
.fdopen(fd
, self
._file
_.mode
)
115 def flags(self
, *which
):
120 raise TypeError, 'Too many arguments'
125 if 'n' in which
: l_flags
= l_flags | FCNTL
.O_NDELAY
126 if 'a' in which
: l_flags
= l_flags | FCNTL
.O_APPEND
127 if 's' in which
: l_flags
= l_flags | FCNTL
.O_SYNC
132 cur_fl
= fcntl
.fcntl(file.fileno(), FCNTL
.F_GETFL
, 0)
133 if '!' in which
: l_flags
= cur_fl
& ~ l_flags
134 else: l_flags
= cur_fl | l_flags
136 l_flags
= fcntl
.fcntl(file.fileno(), FCNTL
.F_SETFL
, l_flags
)
139 arg
= ('!' not in which
) # 0 is don't, 1 is do close on exec
140 l_flags
= fcntl
.fcntl(file.fileno(), FCNTL
.F_SETFD
, arg
)
143 which
= '' # Return current flags
144 l_flags
= fcntl
.fcntl(file.fileno(), FCNTL
.F_GETFL
, 0)
145 if FCNTL
.O_APPEND
& l_flags
: which
= which
+ 'a'
146 if fcntl
.fcntl(file.fileno(), FCNTL
.F_GETFD
, 0) & 1:
148 if FCNTL
.O_NDELAY
& l_flags
: which
= which
+ 'n'
149 if FCNTL
.O_SYNC
& l_flags
: which
= which
+ 's'
152 def lock(self
, how
, *args
):
153 import struct
, fcntl
, FCNTL
155 if 'w' in how
: l_type
= FCNTL
.F_WRLCK
156 elif 'r' in how
: l_type
= FCNTL
.F_RDLCK
157 elif 'u' in how
: l_type
= FCNTL
.F_UNLCK
158 else: raise TypeError, 'no type of lock specified'
160 if '|' in how
: cmd
= FCNTL
.F_SETLKW
161 elif '?' in how
: cmd
= FCNTL
.F_GETLK
162 else: cmd
= FCNTL
.F_SETLK
171 l_len
, l_start
= args
173 l_len
, l_start
, l_whence
= args
175 raise TypeError, 'too many arguments'
177 # Hack by davem@magnet.com to get locking to go on freebsd;
178 # additions for AIX by Vladimir.Marangozov@imag.fr
180 if sys
.platform
in ('netbsd1', 'freebsd2', 'freebsd3'):
181 flock
= struct
.pack('lxxxxlxxxxlhh', \
182 l_start
, l_len
, os
.getpid(), l_type
, l_whence
)
183 elif sys
.platform
in ['aix3', 'aix4']:
184 flock
= struct
.pack('hhlllii', \
185 l_type
, l_whence
, l_start
, l_len
, 0, 0, 0)
187 flock
= struct
.pack('hhllhh', \
188 l_type
, l_whence
, l_start
, l_len
, 0, 0)
190 flock
= fcntl
.fcntl(self
._file
_.fileno(), cmd
, flock
)
193 if sys
.platform
in ('netbsd1', 'freebsd2', 'freebsd3'):
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
213 # Public routine to obtain a posixfile object
215 def open(name
, mode
='r', bufsize
=-1):
216 return _posixfile_().open(name
, mode
, bufsize
)
219 return _posixfile_().fileopen(file)
229 # End of posixfile.py