apue讀書筆記-Ch04(2)

# 4.9 `chmod, fchmod fchmodat` Functions
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int fd, const char *pathname, mode_t mode, int flag);
JunrdeMacBook-Pro:ch04 junr$ ls -l foo bar
-rw-r--r--  1 junr  staff  0  8 14 16:10 bar
-rw-r--r--  1 junr  staff  0  8 14 16:10 foo
#include "apue.h"
int main(void)
{
    struct stat statbuf;

    if(stat("foo", &statbuf) < 0)
        err_sys("stat error for foo");
    // execute by group
    // set-group-ID on execution
    if(chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
        err_sys("chmod error for foo");

    if(chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
        err_sys("chmod error for bar");

    exit(0);
}
編譯運行後:
JunrdeMacBook-Pro:ch04 junr$ ./a.out
JunrdeMacBook-Pro:ch04 junr$ ls -l foo bar
-rw-r--r--  1 junr  staff  0  8 14 16:10 bar
-rw-r-Sr--  1 junr  staff  0  8 14 16:10 foo
Note that the ls command lists the group-execute permission as S to signify that the set-group-ID bit is set without the group-execute bit being set.
set-user-ID: SUID 當文件的該位有設置時,表示當該文件被執行時,程序具有文件所有者的權限而不是執行者的權限。 這樣說有點繞,舉個例子就是說passwd這個命令,它的所有者是root,並且它的set-user-id有設置,所以執行passwd命令後,passwd進程具有root權限,也才能改密碼,畢竟普通用戶沒有修改/etc/passwd文件的權限。然而,並不能該別人的密碼,因爲st_uid還是我,並不是root。 當文件的set-user-ID位被設置時,通過ls -l命令查看,在許可權限部分,用戶的x被替換成s ls -l /usr/include/passwd -rwsr-xr-x 1 root root 41284 9月 13 2012 /usr/bin/passwd set-group-ID: SGID 和set-user-id同理,不過具有的是所有組的權限. 當文件的set-group-ID位被設置時,在許可權限部分,組用戶的x被替換成s sticky: sticky位對於文件和目錄有不同的用途。 對於文件而言,sticky位告訴內核即使沒有人在使用這個程序,也要把它放在交換空間中,放在交換空間裏的文件被內存調用的時候要比放在磁盤上快。不過有虛擬技術後,這個用的很少了。 對於目錄而言,sticky位使得存放在這個目錄下的文件只能被創建者刪除,別人不能夠刪除。 當文件的sticky位被設置時,通過ls -l命令查看,在許可權限部分,其他用戶的x被替換成t 設置方法類似 : chmod 4777 filename 4 代表SUID 2 代表SGID 1 代表sticky

We’ll see in Section 4.19 that the chmod function updates only the time that the i-node was last changed. By default, the ls -l lists the time when the contents of the file were last modified.

4.10 Sticky Bit

4.11 chown, fchown, fchownat, lchown Functions

#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int fchownat(int fd, const char *pathname, uid_t owner, gid_t group, int flag);
int lchown(const char *pathname, uid_t owner, gid_t group);

4.12 File Size

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

Most contemporary UNIX systems provide the fields st_blksize and st_blocks. The first is the preferred block size for I/O for the file, and the latter is the actual number of 512-byte blocks that are allocated. Recall from Section 3.9 that we encountered the minimum amount of time required to read a file when we used st_blksize for the read operations. The standard I/O library, which we describe in Chapter 5, also tries to read or write st_blksize bytes at a time, for efficiency.

Holes in a File

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

NAME
     du -- display disk usage statistics
-a或-all 顯示目錄中個別文件的大小。 
-b或-bytes 顯示目錄或文件大小時,以byte爲單位。 
-c或--total 除了顯示個別目錄或文件的大小外,同時也顯示所有目錄或文件的總和。
-k或--kilobytes 以KB(1024bytes)爲單位輸出。 
-m或--megabytes 以MB爲單位輸出。 
-s或--summarize 僅顯示總計,只列出最後加總的值。 
-h或--human-readable 以KMG爲單位,提高信息的可讀性。 
-x或--one-file-xystem 以一開始處理時的文件系統爲準,若遇上其它不同的文件系統目錄則略過。 
-L<符號鏈接>或--dereference<符號鏈接> 顯示選項中所指定符號鏈接的源文件大小。 
-S或--separate-dirs 顯示個別目錄的大小時,並不含其子目錄的大小。 
-X<文件>或--exclude-from=<文件> 在<文件>指定目錄或文件。 
--exclude=<目錄或文件> 略過指定的目錄或文件。 
-D或--dereference-args 顯示指定符號鏈接的源文件大小。 
-H或--si 與-h參數相同,但是KMG是以1000爲換算單位。 
-l或--count-links 重複計算硬件鏈接的文件。

來自: http://man.linuxde.net/du
wc命令用來計算數字。利用wc指令我們可以計算文件的Byte數、字數或是列數,若不指定文件名稱,或是所給予的文件名爲“-”,則wc指令會從標準輸入設備讀取數據。

wc(選項)(參數)

-c或--bytes或——chars:只顯示Bytes數; 
-l或——lines:只顯示列數; 
-w或——words:只顯示字數。

來自: http://man.linuxde.net/wc

4.13 File Truncation

#include <unistd.h>
int truncate(const char *pathname, off_t length); 
int ftruncate(int fd, off_t length);

4.14 File Systems

To appreciate the concept of links to a file, we need a conceptual understanding of the structure of the UNIX file system. Understanding the difference between an i-node and a directory entry that points to an i-node is also useful.

我們可以將一個disk drive分爲多個區塊,每個區塊包含一個文件系統。 i-nodes是一個固定長度的entries,它包含了大多數關於文件的信息。
這裏寫圖片描述

If we examine the i-node and data block portion of a cylinder group in more detail, we could have the arrangement shown in Figure 4.14.
這裏寫圖片描述

  • 有兩個directory entries指向了同一個i-node entry。每個i-node有個link count,它記錄了指向它的directory entries的個數。只有link count等於0,文件才被刪除。This is why the function that removes a directory entry is called unlink, not delete.
  • 另一種link:symnbolic link 文件的內容–data blocks–存儲了symbolic link指向的文件文件名。
    In the following example, the filename in the directory entry is the three-character string lib and the 7 bytes of data in the file are usr/lib:

    lrwxrwxrwx 1 root 7 Sep 25 07:14 lib -> usr/lib

    The file type in the i-node would be S_IFLNK so that the system knows that this is a symbolic link.

  • i-node 包含了關於文件的所有信息。而directory entry包含了兩個信息:filename,i-node number。

  • 當重命名一個文件時(不改變文件系統),只需要add a new directory entry that points to the existing i-node and then unlink the old directory entry

Assume that we make a new directory in the working directory, as in

mkdir testdir

這裏寫圖片描述

4.15 link, linkat, unlink, unlinkat, remove Functions

As we saw in the previous section, a file can have multiple directory entries pointing to its i-node. We can use either the link function or the linkat function to create a link to an existing file.

#include <unistd.h>
int link(const char *existingpath, const char *newpath);
int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag);
#include <unistd.h>
int unlink(const char *pathname);
int unlinkat(int fd, const char *pathname, int flag);

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

4.16

#include <stdio.h>
int rename(const char *oldname, const char *newname);
int renameat(int oldfd, const char *oldname, int newfd, const char *newname);
  • If oldname specifies a file that is not a directory, then we are renaming a file or a symbolic link. In this case, if newname exists, it cannot refer to a directory. If newname exists and is not a directory, it is removed, and oldname is renamed to newname.
  • If oldname specifies a directory, then we are renaming a directory. If newname exists, it must refer to a directory, and that directory must be empty. (When we say that a directory is empty, we mean that the only entries in the directory are dot and dot-dot.)

4.17 Symbolic Links

http://wzgl08.blog.51cto.com/668144/308987

4.19 File Times

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章