APUE Reading Notes------Chapter 4

Chapter 4. Files and Directories

    4.2 stat, fstat, and lstat Functions

    #include <sys/stat.h>

   

    int stat(const char *restrict pathname, struct stat *restrict buf);

    int fstat(int filedes, struct stat *buf);

    int lstat(const char *restrict pathname, struct stat *restrict buf);

    Returns: All three return: 0 if OK, -1 on error.

 

    Given a pathname, the stat function returns a structure of information about the named file. The fstat function obtains information about the file that is already open on the descriptor filedes. The lstat function is similar to stat, but when the named file is a symbolic link, lstat returns information about the symbolic link, not the file referenced by the symbolic link.

 

    The second argument is a pointer to a structure that we must supply. The function fills in the structure pointed to by buf.

    The biggest user of the stat functions is probably the ls –l command, to learn all the information about a file.

    4.3 File Types

    Most files on a UNIX system are either regular files or directories, but there are additional types of files. The types are:

1.  Regular file. S_ISREG()

2.  Directory file. S_ISDIR()

3.  Block special file. S_ISBLK()

4.  Character special file. S_ISCHR()

5.  FIFO. S_ISFIFO()

6.  Socket. S_ISSOCK()

7.  Symbolic link. S_ISLNK()

The type of a file is encoded in the st_mode member of the stat structure.

 

4.4 Set-User-ID and Set-Group-ID

 

User IDs and group IDs associated with each process

real user ID

real group ID

:who we really are

 

effective user ID

effective group ID

supplementary group IDs

:used for file access permission checks

 

saved set-user-ID

saved set-group-ID

:saved by exec functions

 

Every file has an owner and a group owner. The owner is specified by the st_uid member of the stat structure; the group owner, by the st_gid member.

 

4.5 File Access Permissions

    The st_mode value also encodes the access permission bits for the file.

    The nine file access permission bits, from <sys/stat.h>

    st_mode mask      Meaning

    S_IRUSR            user-read

    S_IWUSR            user-write

    S_IXUSR            user-execute

    S_IRGRP            group-read

    S_IWGRP            group-write

    S_IXGRP            group-execute

    S_IROTH            other-read

    S_IWOTH            other-write

    S_IXOTH            other-execute

 

The first rule is that whenever we want to open any type of file by name, we must have execute permission in each directory mentioned in the name, including the current directory, if it is implied. This is why the execute permission bit for a directory is often called the search bit.

 

We cannot create a new file in a directory unless we have write permission and execute permission in the directory.

 

To delete an existing file, we need write permission and execute permission in the directory containing the file. We do not need read permission for the file itself.

 

The file access tests performed by the kernel are as follows:

1.  If the effective user ID of the process is 0, access is allowed.

2.  If the effective user ID of the process equals the owner ID of the file, access is allowed if the appropriate user access permission bit is set. Otherwise, permission is denied.

3.  If the effective group ID of the process or one of the supplementary group IDs of the process equals the group ID of the file, access is allowed if the appropriate group access permission bit is set. Otherwise, permission is denied.

4.  If the appropriate other access permission bit is set, access is allowed. Otherwise, permission is denied.

These four steps are tried in sequence.

 

4.6 Ownership of New Files and Directories

The user ID of a new file is set to the effective user ID of the process. POSIX.1 allows an implementation to choose one of the following options to determine the group ID of a new file./

1.  The group ID of a new file can be the effective group ID of the process.

2.  The group ID of a new file can be the group ID of the directory in which the file is being created.

 

4.7 access Function

 

The access function bases its tests on the real user and group IDs.

#include <unistd.h>

int access(const char *pathname, int mode);

Returns: 0 if OK, -1 on error.

 

The mode:

 

mode             Description

R_OK             test for read permission

W_OK             test for write permission

X_OK             test for execute permission

F_OK             test for existence of file

 

4.8 umask Function

The umask function sets the file mode creation mask for the process and returns the previous value.

#include <sys/stat.h>

 

mode_t umask(mode_t cmask);

Returns: previous file mode creation mask

The cmask argument is formed as the bitwise OR of the nine constant from: S_IRUSR, S_IWUSR, and so on.

 

The file node creation mask is used whenever the process creates a new file or a new directory. We describe how to create a new directory. Any bits that are on in the file mode creation mask are turned off in the file’s mode.

 

4.9 chmod and fchmod Functions

These two functions allow us to change the file access permission for an existing file.

#include <sys/stat.h>

 

int chmod(const char *pathname, mode_t mode);

int fchmod(int filedes, mode_t mode);

Both return: o if OK, -1 on error.

 

The chmod function operates on the specified file, whereas the fchmod function operates on a file that has already been opened.

 

To change the permission bits of a file, the effective user ID of the process must be equal to the owner ID of the file, or the process must have superuser permission.

 

4.10 Sticky Bit

On contemporary systems, the use of the sticky bit has been extended. The Single UNIX Specification allows the sticky bit to be set for a directory. If the bit is set for a directory, a file in the directory can be removed or renamed only if the user has write permission for the directory and one of the following:

Owns the file

Owns the directory

Is the superuser

 

4.11 chown, fchown, and lchown Functions

The chown functions allow us to change the user ID of a file and the group ID of a file.

#include <unistd.h>

 

int chown(const char *pathname, uis_t owner, gid_t group);

int fchown(int filedes, uid_t owner, gid_t group);

int lchown(const char *pathname, uid_t owner, gid_t group);

All three return: 0 if OK, - 1on error.

 

These three functions operate similarly unless the referenced file is a symbolic link. In that case, lchown changes the owners of the symbolic link itself, not the file pointed to by the symbolic link.

 

If either of the arguments owner or group is -1, the corresponding ID is left unchanged.

 

When _POSIX_CHOWN_RESTRICTED is in effect, you can’t change the user ID of other users’ files. You can change the group ID of files that you own, but only to groups that you belong to.

 

4.12 File Size

The st_size member of the stat structure contains the size of the file in bytes. This is meaningful only for regular files, directories, and symbolic links.

 

Holes in a File

Holes are created by seeking past the current end of file and writing some data.

 

4.13 File Truncation

#include <unistd.h>

 

int truncate(const char *pathname, off_t length);

int ftruncate(int filedes, off_t length);

Both return: 0 if OK, -1 on error.

 

These two functions truncate an existing file to length bytes.

If the previous size was led than length, the effect is system dependent.

 

4.14 File Systems

Disk drive, partitions, and a file system


The i-nodes are fixed-length entries that contain most of the information about a file.

 

 //img

Cylinder group’s i-nodes and data blocks in more detail

 //img

More Info: http://blog.csdn.net/wanpengcoder/archive/2010/12/08/6063076.aspx

 

4.15 link, unlink, remove, and rename Functions

The way we create a link to an existing file is with the link function.

#include <unistd.h>

 

int link(const char *existingpath, const char *newpath);

Returns: 0 if OK, -1 on error.

 

The creation of the new directory entry and the increment of the link count must be atomic operation.

 

To remove an existing directory entry, we call the unlink function.

#include <unistd.h>

 

int unlink(const char *pathname);

Returns: 0 if OK, -1 on error.

 

We’ve mentioned before that to unlink a file, we must have write permission and execute permission in the directory containing the directory entry, as it is the directory entry that we will be removing. If the sticky bit is set in this directory we must have write permission for the directory and one of the following:

Own the file.

Own the directory.

Have superuser privileges.

 

Only when the link count reaches 0 can the contents of file be deleted.

 

The process creates a file using either open or creat and then immediately calls unlink. The file is not deleted, however, because it is still open.

 

If pathname is a symbolic link, unlink removes the symbolic link, not the file referenced by the link. There is no function to remove the file referenced by a symbolic link given the name of the link.

 

We can also unlink a file or a directory with the remove function. For a file, remove is identical to unlink. For a directory, remove is identical to rmdir.

#include <stdio.h>

 

int remove(const char *pathname);

Returns: 0 if OK, -1 on error.

 

A file or a directory id renamed with the rename function.

#include <stdio.h>

 

int rename(const char *oldname, const char *newname);

Returns: 0 if OK, -1 on error.

 

If newname already exists, we need permissions as if we were deleting it. Also, because we’re removing the directory entry for oldname and possibly creating a directory entry for newname, we need write permission and execute permission in the directory containing oldname and in the directory containing newname.

 

4.16 Symbolic Links

Symbolic links were introduced to get around the limitations of hard links.

Hard links normally require that the link and the file reside in the same file system

Only the superuser can create a hard link to a directory.

 

There are no file system limitations on a symbolic link and what it points to, and anyone can create a symbolic link to a directory.

//img

 

4.17 symlink and readlink Functions

A symbolic link is created with the symlink function.

 

#include <unistd.h>

 

int symlink(const char *actualpath, const char *sympath);

Returns: 0 if OK, -1 on error.

 

Because the open function follows a symbolic link, we need a way to open the link itself and read the name in the link. The readlink function does this.

#include <unistd.h>

 

ssize_t readlink(const char *restrict pathname, char *restrict buf, size_t bufsize);

Returns: number of bytes read if OK, -1 on error.

 

4.18 File Times

//img

Note the different between the modification time and the changed-status time. The modification time is when the contents of the file were last modified. The changed-status time is when the i-node of the file was last modified.

 

    4.19 utime Function

    The access time and the modification time of a file can be changed with the utime function.

    #include <utime.h>

   

    int utime(const char *pathname, const struct utimbuf *times);

    Returns: 0 if OK, -1 on error.

    struct utimbuf{

    time_t actime;

    time_t modtime;

};

 

The operation of this function, and the privileges required to execute it, depend on whether the times argument is NULL.

If times is a null pointer, the access time and modification time are both set to the current time.

If times is a non-null pointer, the access time and the modification time are set to the values in the structure pointed to by times.

Note that we are unable to specify a value for the changed-status time, st_ctime the time the i-node was last changed as this field automatically updated when the utime function is called.

 

4.20 mkdir and rmdir Functions

Directories are created with the mkdir function and deleted with the rmdir function.

#include <sys/stat.h>

 

int mkdir(const char *pathname, mode_t mode);

Returns: 0 if OK, -1 on error.

 

A common mistake is to specify the same mode as for a file: read and write permissions only. But for a directory, we normally want at least one of the execute bits enabled, to allow access to filenames within the directory.

 

An empty directory is deleted with the rmdir function.

#include <unistd.h>

 

int rmdir(const char *pathnem);

Returns: 0 if OK, -1 on error.

 

4.21 Reading Directories

Directoried can be read by anyone who has access permission to read the directory. But only the kernel can write to a directory, to preserve file system sanity.

 

#include <dirent.h>

 

DIR *opendir(const char *pathname);

Returns: pointer if OK, NULL on error.

 

struct dirent *readdir(DIR *dp);

Returns: pointer if OK, NULL at end of directory or error.

 

void rewinddir(DIR *dp);

int closedir(DIR *dp);

Returns: 0 if OK, -1 on error.

 

long telldir(DIR *dp);

Returns: current location in directory associated with dp

 

void seekdir(DIR *dp, long loc);

 

 

dirent structure:

 

struct dirent{

    ino_t d_ino; /* i-node number */

    char d_name[NAME_MAX + 1]; /* null-terminated filename */

};

 

The pointer to a DIR structure that is returned by opendir is then used with the other five functions. The opendir function initializes things so that the first readdir reads the first entry in the directory. The ordering of entries within the directory is implementation dependent and is usually not alphabetical.

 

4.22 chdir, fchdir, and getcwd Functions

The current working directory is an attribute of a process; the home directory is an attribute of a login name.

 

We can change the current working directory of the calling process by calling the chdir or fchdir functions.

#include <unistd.h>

 

int chdir(const char *pathname);

int fchdir(int filedes);

Both return: 0 if OK, -1 on error.

 

Get absolute pathname of the current working directory.

#include <unistd.h>

 

char *getcwd(char *buf, size_t size);

Returns: buf if OK, NULL on error.

 

4.23 Device Special Files

Every file system is known by its major and minor device numbers, which are encoded in the primitive system data type dev_t.

 

We can usually access the major and minor device numbers through two macros defined by most implementations: major and minor.

 

The st_dev value for every filename on a system is the device number of the file system containing that filename and its corresponding i-node.

Only character special files and block special files have an st_rdev value.

 

4.24 Summary of File Access Permission Bits

//img

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值