linux/unix编程手册-16_20
生活随笔
收集整理的這篇文章主要介紹了
linux/unix编程手册-16_20
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
title: linux/unix編程手冊-16_20 date: 2018-06-06 11:53:07 categories: programming tags: tips
linux/unix編程手冊-16(擴展屬性EA)
EA的命名空間
- user EA 只適用于文件或目錄 (ext2~4上創建時需要:mount -o user_xattr device dir)
- trusted
- system
- security 略
linux/unix編程手冊-17(訪問控制表)
ACL
- 文件系統支持ACL需要 mount -o acl
- 簡單來說ACL是對原有文件系統權限的擴展
- 原有文件系統只針對owner,group和other, ACL支持對單獨用戶進行權限設置
- ACL由一系列ACE組成,ACE由三部分組成
- 標記類型
- 標記限定符(可選,一般為用戶ID或組ID,下圖帶-表示不可選,同時只存在一條此類型)
- 權限集合
- 示例
- 最小ACL:和普通文件權限集合一樣只包含ACL_XX_OBJ, ACL_OTHER
ACL檢查算法
- 進程具有特權,執行權限需要至少一條ACL匹配才有,其他同普通文件權限
- 進程的有效用戶ID(準確是文件ID下面略)匹配文件的屬主,授予ACL_USER_OBJ的ACE指定權限
- 進程的有效用戶ID匹配了一條ACL_USER,授予權限為ACL_MASK & ACE指定
- 進程組匹配類似(有效組ID和輔助組任意一匹配,只是匹配了ACL_GROUP_ACE后權限需要& ACL_MASK)
- ACL_OTHER 授予的權限
chmod之后ACL_MASK的作用及其他api調用 略太雜了之后有使用再記吧
linux/unix編程手冊-18(目錄和(硬)鏈接)
目錄和硬鏈
目錄的inode示例
- inode可能會有多個文件名(多個硬鏈接),無法通過描述符找到文件名
- inode僅在同一文件系統中唯一,硬鏈得在同一文件系統
- inode目錄無法硬鏈
軟連接(符號鏈接)
- _POSIX_SYMLOOP_MAX_ 解引用操作限制<limits.h>
- 軟鏈存儲的優化,路徑名小于60時可以直接存在存data指針的位置
- l開頭的系統調用往往操作的符號鏈接文件本身(但是文件的目錄如果是軟鏈,則都會解引用)
- 除了sticky設置的目錄下的軟鏈文件(/tmp)進行刪除和重命名的情況外,文件的操作的權限為解引用之后的文件權限。
- 硬鏈了一個軟鏈,linux不會解引用,MAC會。
文件的刪除
即使所有指向這個inode的硬鏈都解除了,但是又進程持有改文件的描述符(因為可以通過打開文件的表找到對應的inode),在關閉描述符之前,系統實際不會刪除改文件
- tmpfile 的實現大致應該類似
目錄的操作略
進程目錄的操作略
linux/unix編程手冊-19(監控文件事件)
inotify API
// return inotify fd int inotify_init(void);// return wd; need read privellege on pathname int inotify_add_watch(int fd, const char *pathname, uint32_t mask);// 刪除fd里面的wd int inotify_rm_watch(int fd, uint32_t wd);復制代碼-
fd,wd一對多
-
每次調用read 讀取fd ,如果不傳O_NONBLOCK會阻塞,傳參的話read會立刻失敗并報錯EAGAIN
- 在事件隊列末尾追加一個新事件會和當前對尾比較,如果struct一致,則合并,忽略多次。
- /proc/sys/fs/inotify/保存inotify的各種限制
- max_queue_events
- max_user_instances
- max_user_watches
linux/unix編程手冊-20(信號:基本概念)
信號是事件發生時對進程的通知機制:也叫軟件中斷
信號通常源于內核
- 硬件發生異常:被0除,內存訪問錯誤等
- 用戶鍵入產生異常特殊字符:Ctrl+c,Ctrl+z
- 軟件事件:CPU時間超時等等
信號的分類
- 標準信號(內核像進程通知事件,通常是1-31)
- 實時信號
進程對信號的反饋
- 忽略信號
- 殺死進程(非調用exit終止)
- 產生核心轉儲文件并終止
- 停止進程
- 恢復停止
- 采取默認(用于恢復對默認的修改)
- 忽略默認終止信號
- 執行編寫的信號處理程序(如Ctrl+c, 無法直接設置處理程序殺死進程或產生核心轉儲文件,可以通過間接調用abort來產生新的信號)
信號類型和默認行為
- SIGABRT: 調用abort()會產生,會殺死進程并產生核心轉儲文件供調試
- SIGALARM: 調用alarm()或setitimer()設置定時器到時間,內核會產生該信號
- SIGBUS: 內存訪問錯誤
- SICHLD|SIGCLD: 子進程終止時發給父進程
- SIGCONT: 恢復停止進程
- .......
- SIGTERM:標準殺死進程信號kill|killall 會發起
- SIGKILL: 必殺信號,處理程序無法將其阻塞,忽略或 捕獲(測試下);kill -9|kill -KILL會調用
改變信號
void ( *signal(int sig, void (*handler)(int))) (int);//成功返回之前的調用函數地址或者SIG_DFL(設為默認值)或SIF_IGN(忽略),失敗時返回SIG_ERR //正常開發不要使用signal,兼容性不好 復制代碼 static void sigHandler(int sig){printf("Ouch\n"); }int main(void){if (signal(SIGINT, sigHandler)==SIG_ERR){printf("error");exit(-1);}for (;;){printf("*****************************");sleep(3);} }復制代碼發送信號
int kill(pid_t pid, int sig); 復制代碼- pid>0, 發送給pid進程
- pid=0, 發送給同組所有進程
- pid<-1, 發送給pid絕對值進程組內所有進程
- pid=-1 發送給除了init進程和自身之外的所有有權進程
發送的權限
- 特權進程可以發給所有
- root用戶和組運行的init進程,僅接受安裝了處理器函數的信號
- 非特權進程
- SIGCONT信號忽視用戶ID檢測,非特權進程可以向會話內任意進程發送這一信號
sig=0,僅報告進程是否存在
其他發送信號調用
int raise(int sig); //單線程下等于 kill(getpid(), sig) //支持線程系統下 pthread_kill(pthread_self(),sig)int killgp(pid_t pgrp, int sig); //等同于 kill(-pgrp, sig) 復制代碼信號集
// 初始化空的set int sigemptyset(sigset_t *set);// 初始化包含所有信號(包括實時信號)的set int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int sig);int sigdelset(sigset_t *set, int sig);int sigismember(const sigset_t *set, int sig); 復制代碼 int sigandset(sigset_t *dest, sigset_t *left, sigset_t *right);int sigorset(sigset_t *dest, sigset_t *left, sigset_t *right);int sigisemptyset(const sigset_t *set);復制代碼信號掩碼
內核會為每個進程維護一個信號掩碼,即一組信號,并阻塞這些信號對進程的傳遞,一直延遲直至解除(每個線程可單獨控制)
int sigprocmask(int how, const sigset_t *set, sigset_t *old_set);// how=SIG_BLOCK, 當前進程和set取并集 // how=SIG_UNBLOCK, 移除set內信號 // how=SIG_SETMASK, 賦值為set內信號 // oldset不為空則指向之前的信號掩碼 // set為空不做改動復制代碼 int main(void){sigset_t blockSet, prevMask;sigemptyset(&blockSet);sigaddset(&blockSet, SIGINT);if (sigprocmask(SIG_BLOCK, &blockSet, &prevMask)==-1){exit(-1);}if (sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1){exit(-1);}retunn 0; } 復制代碼獲取等待信號
int sigpending(sigset_t *set);// 標準信號同一信號只會記錄一次,實時信號之后會有排隊處理見22章 復制代碼改變信號二
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);//act 新處置的數據結構,為NULL則忽略,oldact置位將當前處置struct sigaction{void (*sa_handler)(int); // 調用函數地址或者SIG_DFL,SIF_IGN, 為函數地址時sa_mask和sa_flags才有效sigset_t sa_mask; //調用函數時可額外阻塞一組信號int sa_flags; //略....太多標記了void (*sa_restorer)(void); //系統內部使用,供恢復上下文 } 復制代碼- 執行處理器程序時,同一信號第二次到達,如果沒有設為阻塞會忽略,設為阻塞的話會保留一次
總結
以上是生活随笔為你收集整理的linux/unix编程手册-16_20的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单表操作
- 下一篇: linux初始化root密码