\section{\module{stat} ---
         Interpreting \function{stat()} results}

\declaremodule{standard}{stat}
\modulesynopsis{Utilities for interpreting the results of
  \function{os.stat()}, \function{os.lstat()} and \function{os.fstat()}.}
\sectionauthor{Skip Montanaro}{skip@automatrix.com}


The \module{stat} module defines constants and functions for
interpreting the results of \function{os.stat()},
\function{os.fstat()} and \function{os.lstat()} (if they exist).  For
complete details about the \cfunction{stat()}, \cfunction{fstat()} and
\cfunction{lstat()} calls, consult the documentation for your system.

The \module{stat} module defines the following functions to test for
specific file types:


\begin{funcdesc}{S_ISDIR}{mode}
Return non-zero if the mode is from a directory.
\end{funcdesc}

\begin{funcdesc}{S_ISCHR}{mode}
Return non-zero if the mode is from a character special device file.
\end{funcdesc}

\begin{funcdesc}{S_ISBLK}{mode}
Return non-zero if the mode is from a block special device file.
\end{funcdesc}

\begin{funcdesc}{S_ISREG}{mode}
Return non-zero if the mode is from a regular file.
\end{funcdesc}

\begin{funcdesc}{S_ISFIFO}{mode}
Return non-zero if the mode is from a FIFO (named pipe).
\end{funcdesc}

\begin{funcdesc}{S_ISLNK}{mode}
Return non-zero if the mode is from a symbolic link.
\end{funcdesc}

\begin{funcdesc}{S_ISSOCK}{mode}
Return non-zero if the mode is from a socket.
\end{funcdesc}

Two additional functions are defined for more general manipulation of
the file's mode:

\begin{funcdesc}{S_IMODE}{mode}
Return the portion of the file's mode that can be set by
\function{os.chmod()}---that is, the file's permission bits, plus the
sticky bit, set-group-id, and set-user-id bits (on systems that support
them).
\end{funcdesc}

\begin{funcdesc}{S_IFMT}{mode}
Return the portion of the file's mode that describes the file type (used
by the \function{S_IS*()} functions above).
\end{funcdesc}

Normally, you would use the \function{os.path.is*()} functions for
testing the type of a file; the functions here are useful when you are
doing multiple tests of the same file and wish to avoid the overhead of
the \cfunction{stat()} system call for each test.  These are also
useful when checking for information about a file that isn't handled
by \refmodule{os.path}, like the tests for block and character
devices.

All the variables below are simply symbolic indexes into the 10-tuple
returned by \function{os.stat()}, \function{os.fstat()} or
\function{os.lstat()}.

\begin{datadesc}{ST_MODE}
Inode protection mode.
\end{datadesc}

\begin{datadesc}{ST_INO}
Inode number.
\end{datadesc}

\begin{datadesc}{ST_DEV}
Device inode resides on.
\end{datadesc}

\begin{datadesc}{ST_NLINK}
Number of links to the inode.
\end{datadesc}

\begin{datadesc}{ST_UID}
User id of the owner.
\end{datadesc}

\begin{datadesc}{ST_GID}
Group id of the owner.
\end{datadesc}

\begin{datadesc}{ST_SIZE}
Size in bytes of a plain file; amount of data waiting on some special
files.
\end{datadesc}

\begin{datadesc}{ST_ATIME}
Time of last access.
\end{datadesc}

\begin{datadesc}{ST_MTIME}
Time of last modification.
\end{datadesc}

\begin{datadesc}{ST_CTIME}
Time of last status change (see manual pages for details).
\end{datadesc}

The interpretation of ``file size'' changes according to the file
type.  For plain files this is the size of the file in bytes.  For
FIFOs and sockets under most flavors of \UNIX{} (including Linux in
particular), the ``size'' is the number of bytes waiting to be read at
the time of the call to \function{os.stat()}, \function{os.fstat()},
or \function{os.lstat()}; this can sometimes be useful, especially for
polling one of these special files after a non-blocking open.  The
meaning of the size field for other character and block devices varies
more, depending on the implementation of the underlying system call.

Example:

\begin{verbatim}
import os, sys
from stat import *

def walktree(dir, callback):
    '''recursively descend the directory rooted at dir,
       calling the callback function for each regular file'''

    for f in os.listdir(dir):
        pathname = '%s/%s' % (dir, f)
        mode = os.stat(pathname)[ST_MODE]
        if S_ISDIR(mode):
            # It's a directory, recurse into it
            walktree(pathname, callback)
        elif S_ISREG(mode):
            # It's a file, call the callback function
            callback(pathname)
        else:
            # Unknown file type, print a message
            print 'Skipping %s' % pathname

def visitfile(file):
    print 'visiting', file

if __name__ == '__main__':
    walktree(sys.argv[1], visitfile)
\end{verbatim}
