我們在這篇博客中主要討論三個知識點:分別是atexit(),Linux中的粘滯位和FILE結構體。
一、驗證連續註冊三個函數,看輸出順序(atexit)
源碼:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
void fun()
{
printf("hello fun\n");
return;
}
void fun1()
{
printf("hello fun1\n");
return;
}
void fun2()
{
printf("hello fun2\n");
return;
}
int main()
{
atexit(fun);
atexit(fun1);
atexit(fun2);
printf("hello main\n");
sleep(5);
return 0;
}
輸出結果:
從上面的結果可以看出, 進程退出時,系統會自動調用atexit初始回調函數(參數函數),但多次調用時的輸出順序是逆序的。
二、粘滯位
粘滯位(Sticky bit),或粘着位,是Unix文件系統權限的一個旗標。最常見的用法在目錄上設置粘滯位,如此以來,只有目錄內文件的所有者或者root纔可以刪除或移動該文件。如果不爲目錄設置粘滯位,任何具有該目錄寫和執行權限的用戶都可以刪除和移動其中的文件。實際應用中,粘滯位一般用於/tmp目錄,以防止普通用戶刪除或移動其他用戶的文件。
三、FILE結構體
struct file結構體定義在include/Linux/fs.h中定義。文件結構體代表一個打開的文件,系統中的每個打開的文件在內核空間都有一個關聯的 struct file。它由內核在打開文件時創建,並傳遞給在文件上進行操作的任何函數。在文件的所有實例都關閉後,內核釋放這個數據結構。在內核創建和驅動源碼中,struct file的指針通常被命名爲file或filp。如下所示:
struct file {
union {
struct list_head fu_list; //文件對象鏈表指針linux/include/linux/list.h
struct rcu_head fu_rcuhead; //RCU(Read-Copy Update)是Linux 2.6內核中新的鎖機制(詳細瞭解http://www.ibm.com/developerworks/cn/linux/l-rcu/)
} f_u;
struct path f_path; //包含dentry和mnt兩個成員,用於確定文件路徑
#define f_dentry f_path.dentry //f_path的成員之一,當前文件的dentry結構
#define f_vfsmnt f_path.mnt //表示當前文件所在文件系統的掛載根目錄
const struct file_operations *f_op; //與該文件相關聯的操作函數
atomic_t f_count; //文件的引用計數(有多少進程打開該文件)
unsigned int f_flags; //對應於open時指定的flag
mode_t f_mode; //讀寫模式:open的mod_t mode參數
loff_t f_pos;//當前文件指針位置
off_t f_pos; //該文件在當前進程中的文件偏移量
struct fown_struct f_owner; //該結構的作用是通過信號進行I/O時間通知的數據。
unsigned int f_uid, f_gid;// 文件所有者id,所有者組id
struct file_ra_state f_ra; //在linux/include/linux/fs.h中定義,文件預讀相關
unsigned long f_version;//記錄文件的版本號,每次使用之後遞增
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* needed for tty driver, and maybe others */
void *private_data;//使用這個成員來指向分配的數據
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links;
spinlock_t f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
};