C Programming/POSIX Reference/sys/stat.h

From Wikibooks, open books for an open world
Jump to navigation Jump to search

<sys/stat.h> is the header in the C POSIX library for the C programming language that contains constructs that facilitate getting information about files attributes.

Member functions[edit | edit source]

Name Notes
int stat (const char *filename, struct stat *buf) The stat function returns information about the attributes of the file named by filename in the structure pointed to by buf. If filename is the name of a symbolic link, the attributes you get describe the file that the link points to. If the link points to a nonexistent file name, then stat fails reporting a nonexistent file. The return value is 0 if the operation is successful, or -1 on failure. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is in fact stat64 since the LFS interface transparently replaces the normal implementation.

errno Errors: ENOENT means the file named by filename doesn't exist.

int stat64 (const char *filename, struct stat64 *buf) This function is similar to stat but it is also able to work on files larger than 2^31 bytes on 32-bit systems. To be able to do this the result is stored in a variable of type struct stat64 to which buf must point. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is available under the name stat and so transparently replaces the interface for small files on 32-bit machines.

errno Errors: ENOENT means the file named by filename doesn't exist.

int fstat (int filedes, struct stat *buf) The fstat function is like stat, except that it takes an open file descriptor (filedes)as an argument instead of a file name. Like stat, fstat returns 0 on success and -1 on failure. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is in fact fstat64 since the LFS interface transparently replaces the normal implementation.

errno Errors: EBADF means the filedes argument is not a valid file descriptor.

int fstat64 (int filedes, struct stat64 *buf) This function is similar to fstat but is able to work on large files on 32-bit platforms. For large files the file descriptor filedes should be obtained by open64 or creat64. The buf pointer points to a variable of type struct stat64 which is able to represent the larger values. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is available under the name fstat and so transparently replaces the interface for small files on 32-bit machines.

errno Errors: EBADF means the filedes argument is not a valid file descriptor.

int lstat (const char *filename, struct stat *buf) The lstat function is like stat, except that it does not follow symbolic links. If filename is the name of a symbolic link, lstat returns information about the link itself; otherwise lstat works like stat. See Symbolic Links. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is in fact lstat64 since the LFS interface transparently replaces the normal implementation.
int lstat64 (const char *filename, struct stat64 *buf) The lstat function is like stat, except that it does not follow symbolic links. If filename is the name of a symbolic link, lstat returns information about the link itself; otherwise lstat works like stat. See Symbolic Links. When the sources are compiled with _FILE_OFFSET_BITS == 64 this function is in fact lstat64 since the LFS interface transparently replaces the normal implementation.

Member constants[edit | edit source]

The following POSIX macros are defined to check the file type using the st_mode field:

Name Notes
S_ISREG(m) is it a regular file?
S_ISDIR(m) is it a directory?
S_ISCHR(m) is it a character device?
S_ISBLK(m) is it a block device?
S_ISFIFO(m) is it a FIFO (named pipe)?
S_ISLNK(m) is it a symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) is it a socket? (Not in POSIX.1-1996.)

The following flags are defined for the st_mode field:

Name Value Notes
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission

The set-group-ID bit (S_ISGID) has several special uses. For a directory it indicates that BSD semantics is to be used for that directory: files created there inherit their group ID from the directory, not from the effective group ID of the creating process, and directories created there will also get the S_ISGID bit set. For a file that does not have the group execution bit (S_IXGRP) set, the set-group-ID bit indicates mandatory file/record locking. The sticky bit (S_ISVTX) on a directory means that a file in that directory can be renamed or deleted only by the owner of the file, by the owner of the directory, and by a privileged process.

POSIX does not describe the S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX bits, but instead demands the use of the macros S_ISDIR(), etc. The S_ISLNK() and S_ISSOCK() macros are not in POSIX.1-1996, but both are present in POSIX.1-2001; the former is from SVID 4, the latter from SUSv2.

Other Systems - Values that have been (or are) in use on various systems:

hex name ls octal description
f000 S_IFMT 170000 mask for file type
0000 000000 SCO out-of-service inode; BSD unknown type; SVID-v2 and XPG2 have both 0 and 0100000 for ordinary file
1000 S_IFIFO p| 010000 FIFO (named pipe)
2000 S_IFCHR c 020000 character special (V7)
3000 S_IFMPC 030000 multiplexed character special (V7)
4000 S_IFDIR d/ 040000 directory (V7)
5000 S_IFNAM 050000 XENIX named special file with two subtypes, distinguished by st_rdev values 1, 2
0001 S_INSEM s 000001 XENIX semaphore subtype of IFNAM
0002 S_INSHD m 000002 XENIX shared data subtype of IFNAM
6000 S_IFBLK b 060000 block special (V7)
7000 S_IFMPB 070000 multiplexed block special (V7)
8000 S_IFREG - 100000 regular (V7)
9000 S_IFCMP 110000 VxFS compressed
9000 S_IFNWK n 110000 network special (HP-UX)
a000 S_IFLNK l@ 120000 symbolic link (BSD)
b000 S_IFSHAD 130000 Solaris shadow inode for ACL (not seen by userspace)
c000 S_IFSOCK s= 140000 socket (BSD; also "S_IFSOC" on VxFS)
d000 S_IFDOOR D> 150000 Solaris door
e000 S_IFWHT w% 160000 BSD whiteout (not used for inode)
0200 S_ISVTX 001000 sticky bit: save swapped text even after use (V7) reserved (SVID-v2). On non-directories: don’t cache this file (SunOS). On directories: restricted deletion flag (SVID-v4.2)
0400 S_ISGID 002000 set-group-ID on execution (V7) for directories: use BSD semantics for propagation of GID
0400 S_ENFMT 002000 SysV file locking enforcement (shared with S_ISGID)
0800 S_ISUID 004000 set-user-ID on execution (V7)
0800 S_CDF 004000 directory is a context dependent file (HP-UX)

A sticky command appeared in Version 32V AT&T UNIX.

Member types[edit | edit source]

Data types defined in the <sys/stat.h> header include:

struct stat {
  dev_t     st_dev;     /* ID of device containing file */
  ino_t     st_ino;     /* inode number */
  mode_t    st_mode;    /* protection */
  nlink_t   st_nlink;   /* number of hard links */
  uid_t     st_uid;     /* user ID of owner */
  gid_t     st_gid;     /* group ID of owner */
  dev_t     st_rdev;    /* device ID (if special file) */
  off_t     st_size;    /* total size, in bytes */
  blksize_t st_blksize; /* blocksize for file system I/O */
  blkcnt_t  st_blocks;  /* number of blocks allocated */
  time_t    st_atime;   /* time of last access */
  time_t    st_mtime;   /* time of last modification */
  time_t    st_ctime;   /* time of last status change */
};

Example[edit | edit source]

A short example of <sys/stat.h> usage is:

/**************************************************************
 abstract ls meaning
 **************************************************************/
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
  struct stat  file_stat;

  while (argc-- > 1)
    {
      if (lstat(argv[argc], &file_stat) == -1)
        fprintf(stderr, "%s\n", strerror(errno));
      else
        {
          fprintf(stdout, "Links\tUid\tGid\tSize\tName\n");
          fprintf(stdout, "%u\t%u\t%u\t%u\t%s\n", file_stat.st_nlink,
                  file_stat.st_uid, file_stat.st_gid, file_stat.st_size,
                  argv[argc]);
        }
    }
  return 0;
}

Put the source in a file (main.c) and compile this:

 gcc main.c -o test

Now, to run type:

 ./test main.c
 ./test *

References[edit | edit source]