STAT(2)                                                   STAT(2)

     NAME
          stat, fstat, wstat, fwstat, dirstat, dirfstat, dirwstat,
          dirfwstat, nulldir - get and put file status

     SYNOPSIS
          #include <u.h>
          #include <libc.h>

          int stat(char *name, uchar *edir, int nedir)

          int fstat(int fd, uchar *edir, int nedir)

          int wstat(char *name, uchar *edir, int nedir)

          int fwstat(int fd, uchar *edir, int nedir)

          Dir* dirstat(char *name)

          Dir* dirfstat(int fd)

          int dirwstat(char *name, Dir *dir)

          int dirfwstat(int fd, Dir *dir)

          void nulldir(Dir *d)

     DESCRIPTION
          Given a file's name, or an open file descriptor fd, these
          routines retrieve or modify file status information.  Stat,
          fstat, wstat, and fwstat are the system calls; they deal
          with machine-independent directory entries. Their format is
          defined by stat(5). Stat and fstat retrieve information
          about name or fd into edir, a buffer of length nedir,
          defined in <libc.h>.  Wstat and fwstat write information
          back, thus changing file attributes according to the con-
          tents of edir. The data returned from the kernel includes
          its leading 16-bit length field as described in intro(5).
          For symmetry, this field must also be present when passing
          data to the kernel in a call to wstat and fwstat, but its
          value is ignored.

          Dirstat, dirfstat, dirwstat, and dirfwstat are similar to
          their counterparts, except that they operate on Dir struc-
          tures:

               typedef
               struct Dir {
                     /* system-modified data */
                     uint  type;    /* server type */
                     uint  dev;     /* server subtype */

     STAT(2)                                                   STAT(2)

                     /* file data */
                     Qid   qid;     /* unique id from server */
                     ulong mode;    /* permissions */
                     ulong atime;   /* last read time */
                     ulong mtime;   /* last write time */
                     vlong length;  /* file length: see <u.h> */
                     char  *name;   /* last element of path */
                     char  *uid;    /* owner name */
                     char  *gid;    /* group name */
                     char  *muid;   /* last modifier name */
               } Dir;

          The returned structure is allocated by malloc(2); freeing it
          also frees the associated strings.

          This structure and the Qid structure are defined in
          <libc.h>.  If the file resides on permanent storage and is
          not a directory, the length returned by stat is the number
          of bytes in the file.  For directories, the length returned
          is zero.  For files that are streams (e.g., pipes and net-
          work connections), the length is the number of bytes that
          can be read without blocking.

          Each file is the responsibility of some server: it could be
          a file server, a kernel device, or a user process.  Type
          identifies the server type, and dev says which of a group of
          servers of the same type is the one responsible for this
          file.  Qid is a structure containing path and vers fields:
          path is guaranteed to be unique among all path names cur-
          rently on the file server, and vers changes each time the
          file is modified.  The path is a long long (64 bits, vlong)
          and the vers is an unsigned long (32 bits, ulong).  Thus, if
          two files have the same type, dev, and qid they are the same
          file.

          The bits in mode are defined by

                0x80000000   directory
                0x40000000   append only
                0x20000000   exclusive use (locked)

                      0400   read permission by owner
                      0200   write permission by owner
                      0100   execute permission (search on directory) by owner
                      0070   read, write, execute (search) by group
                      0007   read, write, execute (search) by others

          There are constants defined in <libc.h> for these bits:
          DMDIR, DMAPPEND, and DMEXCL for the first three; and DMREAD,
          DMWRITE, and DMEXEC for the read, write, and execute bits
          for others.

     STAT(2)                                                   STAT(2)

          The two time fields are measured in seconds since the epoch
          (Jan 1 00:00 1970 GMT).  Mtime is the time of the last
          change of content.  Similarly, atime is set whenever the
          contents are accessed; also, it is set whenever mtime is
          set.

          Uid and gid are the names of the owner and group of the
          file; muid is the name of the user that last modified the
          file (setting mtime).  Groups are also users, but each
          server is free to associate a list of users with any user
          name g, and that list is the set of users in the group g.
          When an initial attachment is made to a server, the user
          string in the process group is communicated to the server.
          Thus, the server knows, for any given file access, whether
          the accessing process is the owner of, or in the group of,
          the file.  This selects which sets of three bits in mode is
          used to check permissions.

          Only some of the fields may be changed with the wstat calls.
          The name can be changed by anyone with write permission in
          the parent directory.  The mode and mtime can be changed by
          the owner or the group leader of the file's current group.
          The gid can be changed: by the owner if also a member of the
          new group; or by the group leader of the file's current
          group if also leader of the new group (see intro(5) for more
          information about permissions and users(6) for users and
          groups).  The length can be changed by anyone with write
          permission, provided the operation is implemented by the
          server.  (See intro(5) for permission information, and
          users(6) for user and group information).

          Special values in the fields of the Dir passed to wstat
          indicate that the field is not intended to be changed by the
          call.  The values are the maximum unsigned integer of appro-
          priate size for integral values (usually ~0, but beware of
          conversions and size mismatches when comparing values) and
          the empty or nil string for string values.  The routine
          nulldir initializes all the elements of d to these ``don't
          care'' values.  Thus one may change the mode, for example,
          by using nulldir to initialize a Dir, then setting the mode,
          and then doing wstat; it is not necessary to use stat to
          retrieve the initial values first.

     SOURCE
          /sys/src/libc/9syscall  for the non-dir routines
          /sys/src/libc/9sys      for the routines prefixed dir

     SEE ALSO
          intro(2), fcall(2), dirread(2), stat(5)

     DIAGNOSTICS
          The dir functions return a pointer to the data for a

     STAT(2)                                                   STAT(2)

          successful call, or nil on error.  The others return the
          number of bytes copied on success, or -1 on error.  All set
          errstr.

          If the buffer for stat or fstat is too short for the
          returned data, the return value will be BIT16SZ (see
          fcall(2)) and the two bytes returned will contain the ini-
          tial count field of the returned data; retrying with nedir
          equal to that value plus BIT16SZ (for the count itself)
          should succeed.