% Manual text and implementation by Jaap Vermeulen
\section{\module{posixfile} ---
         File-like objects with locking support}

\declaremodule{builtin}{posixfile}
  \platform{Unix}
\modulesynopsis{A file-like object with support for locking.}
\moduleauthor{Jaap Vermeulen}{}
\sectionauthor{Jaap Vermeulen}{}


\indexii{\POSIX{}}{file object}

\strong{Note:} This module will become obsolete in a future release.
The locking operation that it provides is done better and more
portably by the \function{fcntl.lockf()} call.%
\withsubitem{(in module fcntl)}{\ttindex{lockf()}}

This module implements some additional functionality over the built-in
file objects.  In particular, it implements file locking, control over
the file flags, and an easy interface to duplicate the file object.
The module defines a new file object, the posixfile object.  It
has all the standard file object methods and adds the methods
described below.  This module only works for certain flavors of
\UNIX{}, since it uses \function{fcntl.fcntl()} for file locking.%
\withsubitem{(in module fcntl)}{\ttindex{fcntl()}}

To instantiate a posixfile object, use the \function{open()} function
in the \module{posixfile} module.  The resulting object looks and
feels roughly the same as a standard file object.

The \module{posixfile} module defines the following constants:


\begin{datadesc}{SEEK_SET}
Offset is calculated from the start of the file.
\end{datadesc}

\begin{datadesc}{SEEK_CUR}
Offset is calculated from the current position in the file.
\end{datadesc}

\begin{datadesc}{SEEK_END}
Offset is calculated from the end of the file.
\end{datadesc}

The \module{posixfile} module defines the following functions:


\begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}}
 Create a new posixfile object with the given filename and mode.  The
 \var{filename}, \var{mode} and \var{bufsize} arguments are
 interpreted the same way as by the built-in \function{open()}
 function.
\end{funcdesc}

\begin{funcdesc}{fileopen}{fileobject}
 Create a new posixfile object with the given standard file object.
 The resulting object has the same filename and mode as the original
 file object.
\end{funcdesc}

The posixfile object defines the following additional methods:

\setindexsubitem{(posixfile method)}
\begin{funcdesc}{lock}{fmt, \optional{len\optional{, start\optional{, whence}}}}
 Lock the specified section of the file that the file object is
 referring to.  The format is explained
 below in a table.  The \var{len} argument specifies the length of the
 section that should be locked. The default is \code{0}. \var{start}
 specifies the starting offset of the section, where the default is
 \code{0}.  The \var{whence} argument specifies where the offset is
 relative to. It accepts one of the constants \constant{SEEK_SET},
 \constant{SEEK_CUR} or \constant{SEEK_END}.  The default is
 \constant{SEEK_SET}.  For more information about the arguments refer
 to the \manpage{fcntl}{2} manual page on your system.
\end{funcdesc}

\begin{funcdesc}{flags}{\optional{flags}}
 Set the specified flags for the file that the file object is referring
 to.  The new flags are ORed with the old flags, unless specified
 otherwise.  The format is explained below in a table.  Without
 the \var{flags} argument
 a string indicating the current flags is returned (this is
 the same as the \samp{?} modifier).  For more information about the
 flags refer to the \manpage{fcntl}{2} manual page on your system.
\end{funcdesc}

\begin{funcdesc}{dup}{}
 Duplicate the file object and the underlying file pointer and file
 descriptor.  The resulting object behaves as if it were newly
 opened.
\end{funcdesc}

\begin{funcdesc}{dup2}{fd}
 Duplicate the file object and the underlying file pointer and file
 descriptor.  The new object will have the given file descriptor.
 Otherwise the resulting object behaves as if it were newly opened.
\end{funcdesc}

\begin{funcdesc}{file}{}
 Return the standard file object that the posixfile object is based
 on.  This is sometimes necessary for functions that insist on a
 standard file object.
\end{funcdesc}

All methods raise \exception{IOError} when the request fails.

Format characters for the \method{lock()} method have the following
meaning:

\begin{tableii}{c|l}{samp}{Format}{Meaning}
  \lineii{u}{unlock the specified region}
  \lineii{r}{request a read lock for the specified section}
  \lineii{w}{request a write lock for the specified section}
\end{tableii}

In addition the following modifiers can be added to the format:

\begin{tableiii}{c|l|c}{samp}{Modifier}{Meaning}{Notes}
  \lineiii{|}{wait until the lock has been granted}{}
  \lineiii{?}{return the first lock conflicting with the requested lock, or
              \code{None} if there is no conflict.}{(1)} 
\end{tableiii}

\noindent
Note:

\begin{description}
\item[(1)] The lock returned is in the format \code{(\var{mode}, \var{len},
\var{start}, \var{whence}, \var{pid})} where \var{mode} is a character
representing the type of lock ('r' or 'w').  This modifier prevents a
request from being granted; it is for query purposes only.
\end{description}

Format characters for the \method{flags()} method have the following
meanings:

\begin{tableii}{c|l}{samp}{Format}{Meaning}
  \lineii{a}{append only flag}
  \lineii{c}{close on exec flag}
  \lineii{n}{no delay flag (also called non-blocking flag)}
  \lineii{s}{synchronization flag}
\end{tableii}

In addition the following modifiers can be added to the format:

\begin{tableiii}{c|l|c}{samp}{Modifier}{Meaning}{Notes}
  \lineiii{!}{turn the specified flags 'off', instead of the default 'on'}{(1)}
  \lineiii{=}{replace the flags, instead of the default 'OR' operation}{(1)}
  \lineiii{?}{return a string in which the characters represent the flags that
  are set.}{(2)}
\end{tableiii}

\noindent
Notes:

\begin{description}
\item[(1)] The \samp{!} and \samp{=} modifiers are mutually exclusive.

\item[(2)] This string represents the flags after they may have been altered
by the same call.
\end{description}

Examples:

\begin{verbatim}
import posixfile

file = posixfile.open('/tmp/test', 'w')
file.lock('w|')
...
file.lock('u')
file.close()
\end{verbatim}
