sigaction 函数,sigemptyset()函数,fcntl()函数,isatty()函数
第一個函數(shù):使用 sigaction函數(shù):
?signal 函數(shù)的使用方法簡單,但并不屬于POSIX標(biāo)準(zhǔn),在各類UNIX平臺上的實現(xiàn)不盡相同,因此其用途受
到了一定的限制。而 POSIX標(biāo)準(zhǔn)定義的信號處理接口是sigaction函數(shù),其接口頭文件及原型如下:
?#include <signal.h>
?int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
?◆ signum:要操作的信號。
?◆ act:要設(shè)置的對信號的新處理方式。
?◆ oldact:原來對信號的處理方式。
?◆ 返回值:0表示成功,-1表示有錯誤發(fā)生。
?struct sigaction 類型用來描述對信號的處理,定義如下:
struct sigaction{void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);};?在這個結(jié)構(gòu)體中,成員 sa_handler是一個函數(shù)指針,其含義與signal函數(shù)中的信號處理函數(shù)類似。成員
sa_sigaction 則是另一個信號處理函數(shù),它有三個參數(shù),可以獲得關(guān)于信號的更詳細的信息。當(dāng)sa_flags成員的值
包含了 SA_SIGINFO標(biāo)志時,系統(tǒng)將使用sa_sigaction函數(shù)作為信號處理函數(shù),否則使用sa_handler作為信號處理
函數(shù)。在某些系統(tǒng)中,成員 sa_handler與sa_sigaction被放在聯(lián)合體中,因此使用時不要同時設(shè)置。
sa_mask 成員用來指定在信號處理函數(shù)執(zhí)行期間需要被屏蔽的信號,特別是當(dāng)某個信號被處理時,它自身會被
自動放入進程的信號掩碼,因此在信號處理函數(shù)執(zhí)行期間這個信號不會再度發(fā)生。
?sa_flags 成員用于指定信號處理的行為,它可以是一下值的“按位或”組合。
?◆ SA_RESTART:使被信號打斷的系統(tǒng)調(diào)用自動重新發(fā)起。
?◆ SA_NOCLDSTOP:使父進程在它的子進程暫停或繼續(xù)運行時不會收到SIGCHLD信號。
?◆ SA_NOCLDWAIT:使父進程在它的子進程退出時不會收到SIGCHLD信號,這時子進程如果退出也不會成為僵
尸進程。
?◆ SA_NODEFER:使對信號的屏蔽無效,即在信號處理函數(shù)執(zhí)行期間仍能發(fā)出這個信號。
?◆ SA_RESETHAND:信號處理之后重新設(shè)置為默認(rèn)的處理方式。
?◆ SA_SIGINFO:使用sa_sigaction成員而不是sa_handler作為信號處理函數(shù)。
?re_restorer 成員則是一個已經(jīng)廢棄的數(shù)據(jù)域,不要使用。
?下面用一個例程來說明 sigaction函數(shù)的使用,代碼如下:
第二個函數(shù):sigemptyset()函數(shù):初始化信號集?
相關(guān)函數(shù):sigaddset, sigfillset, sigdelset, sigismember
頭文件:#include <signal.h>
定義函數(shù):int sigemptyset(sigset_t *set);
函數(shù)說明:sigemptyset()用來將參數(shù)set信號集初始化并清空.
返回值:執(zhí)行成功則返回0,如果有錯誤則返回-1.
錯誤代碼:EFAULT參數(shù)set指針地址無法存取。
?
第三個函數(shù):fcntl()函數(shù)
功能描述:根據(jù)文件描述詞來操作文件的特性。
用法: ??
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
參數(shù): ??
fd:文件描述詞。
cmd:操作命令。
arg:供命令使用的參數(shù)。
lock:同上??
F_SETFL的使用:fcntl(fd, F_SETFL, 0)
1、獲取文件的flags,即open函數(shù)的第二個參數(shù):
? ? ? ?flags = fcntl(fd,F_GETFL,0);
2、設(shè)置文件的flags:
? ? ? fcntl(fd,F_SETFL,flags);
3、增加文件的某個flags,比如文件是阻塞的,想設(shè)置成非阻塞:
? ? ? ?flags = fcntl(fd,F_GETFL,0);
? ? ? ?flags |= O_NONBLOCK;
? ? ? fcntl(fd,F_SETFL,flags);
4、取消文件的某個flags,比如文件是非阻塞的,想設(shè)置成為阻塞:
? ? ? flags = fcntl(fd,F_GETFL,0);
? ? ? flags &= ~O_NONBLOCK;
? ? ? fcntl(fd,F_SETFL,flags);
有以下操作命令可供使用
一. ?F_DUPFD:復(fù)制文件描述詞 。
二. ?FD_CLOEXEC:設(shè)置close-on-exec標(biāo)志。如果FD_CLOEXEC位是0,執(zhí)行execve的過程中,文件保持打開。反之則關(guān)閉。
三. ??F_GETFD:讀取文件描述詞標(biāo)志。
四. ??F_SETFD:設(shè)置文件描述詞標(biāo)志。
五. ?F_GETFL:讀取文件狀態(tài)標(biāo)志。
六. ??F_SETFL:設(shè)置文件狀態(tài)標(biāo)志。
其中O_RDONLY,O_WRONLY,O_RDWR,O_CREAT, ?O_EXCL,O_NOCTTY和O_TRUNC不受影響,可以更改的標(biāo)志有O_APPEND,O_ASYNC,O_DIRECT,O_NOATIME和O_NONBLOCK。
七. ?F_GETLK, F_SETLK和F_SETLKW:獲取,釋放或測試記錄鎖,使用到的參數(shù)是以下結(jié)構(gòu)體指針:
F_SETLK:在指定的字節(jié)范圍獲取鎖(F_RDLCK, F_WRLCK)或者釋放鎖(F_UNLCK)。如果與另一個進程的鎖操作發(fā)生沖突,返回-1并將errno設(shè)置為EACCES或EAGAIN。 ????????
F_SETLKW:行為如同F_SETLK,除了不能獲取鎖時會睡眠等待外。如果在等待的過程中接收到信號,會立即返回并將errno置為EINTR。
F_GETLK:獲取文件鎖信息。 F_UNLCK:釋放文件鎖。
為了設(shè)置讀鎖,文件必須以讀的方式打開。為了設(shè)置寫鎖,文件必須以寫的方式打開。為了設(shè)置讀寫鎖,文件必須以讀寫的方式打開。
八. 信號管理
F_GETOWN, F_SETOWN, F_GETSIG 和 F_SETSIG被用于IO可獲取的信號。
F_GETOWN:獲取當(dāng)前在文件描述詞fd上接收到SIGIO或SIGURG事件信號的進程或進程組標(biāo)識 。
F_SETOWN:設(shè)置將要在文件描述詞fd上接收SIGIO或SIGURG事件信號的進程或進程組標(biāo)識 。
F_GETSIG:獲取標(biāo)識輸入輸出可進行的信號。
F_SETSIG:設(shè)置標(biāo)識輸入輸出可進行的信號。
使用以上命令,大部分時間程序無須使用select()或poll()即可實現(xiàn)完整的異步I/O。?
九. 租約( Leases)
F_SETLEASE 和 F_GETLEASE被用于當(dāng)前進程在文件上的租約。文件租約提供當(dāng)一個進程試圖打開或折斷文件內(nèi)容時,擁有文件租約的進程將會被通告的機制。
F_SETLEASE:根據(jù)以下符號值設(shè)置或者刪除文件租約
1.F_RDLCK設(shè)置讀租約,當(dāng)文件由另一個進程以寫的方式打開或折斷內(nèi)容時,擁有租約的當(dāng)前進程會被通告。
2.F_WRLCK設(shè)置寫租約,當(dāng)文件由另一個進程以讀或以寫的方式打開或折斷內(nèi)容時,擁有租約的當(dāng)前進程會被通告。
3.F_UNLCK刪除文件租約。
F_GETLEASE:獲取租約類型。
十.文件或目錄改變通告
(linux 2.4以上)當(dāng)fd索引的目錄或目錄中所包含的某一文件發(fā)生變化時,將會向進程發(fā)出通告。arg參數(shù)指定的通告事件有以下,兩個或多個值可以通過或運算組合。
1.DN_ACCESS 文件被訪問 (read, pread, readv)
2.DN_MODIFY 文件被修改(write, pwrite,writev, truncate, ftruncate)
3.DN_CREATE 文件被建立(open, creat, mknod, mkdir, link, symlink, rename)
4.DN_DELETE 文件被刪除(unlink, rmdir)
5.DN_RENAME 文件被重命名(rename)
6.DN_ATTRIB 文件屬性被改變(chown, chmod, utime[s])
返回說明: ??
成功執(zhí)行時,對于不同的操作,有不同的返回值
F_DUPFD: 新文件描述詞
F_GETFD: ?標(biāo)志值
F_GETFL: ?標(biāo)志值
F_GETOWN: 文件描述詞屬主
F_GETSIG: 讀寫變得可行時將要發(fā)送的通告信號,或者0對于傳統(tǒng)的SIGIO行為
對于其它命令返回0。失敗返回-1,errno被設(shè)為以下的某個值 。 ?
EACCES/EAGAIN: 操作不被允許,尚未可行
EBADF: 文件描述詞無效
EDEADLK: 探測到可能會發(fā)生死鎖
EFAULT: 鎖操作發(fā)生在可訪問的地址空間外
EINTR: 操作被信號中斷
EINVAL: 參數(shù)無效
EMFILE: 進程已超出文件的最大可使用范圍
ENOLCK: 鎖已被用盡
EPERM:權(quán)能不允許
struct flock {
?????????????short l_type; /* 鎖類型: F_RDLCK, F_WRLCK, F_UNLCK */
?????????????short l_whence; /* l_start字段參照點:SEEK_SET(文件頭), SEEK_CUR(文件當(dāng)前位置), SEEK_END(文件尾) */
?????????????off_t l_start; /* 相對于l_whence字段的偏移量*/
?????????????off_t l_len; /* 需要鎖定的長度 */
?????????????pid_t l_pid; /* 當(dāng)前獲得文件鎖的進程標(biāo)識(F_GETLK)*/
};?
linux文件設(shè)備與I/O:fcntl函數(shù)
2009年05月07日 星期四14:24
可以用fcntl 函數(shù)改變一個已打開的文件的屬性,可以重新設(shè)置讀、寫、追加、非阻塞等標(biāo)志(這些標(biāo)志稱為File StatusFlag),而不必重新open文件。
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
這個函數(shù)和open 一樣,也是用可變參數(shù)實現(xiàn)的,可變參數(shù)的類型和個數(shù)取決于前面的cmd參數(shù)。
針對第2個參數(shù),int cmd fcntl函數(shù)有五種功能:
? 復(fù)制一個現(xiàn)存的描述符(cmd=F_DUPFD) ???。
? 獲得/設(shè)置文件描述符標(biāo)記(cmd=F_GETFD或F_SETFD) ??。
? 獲得/設(shè)置文件狀態(tài)標(biāo)志(cmd=F_GETFL或F_SETFL)。
? 獲得/設(shè)置異步I/O有權(quán)(cmd=F_GETOWN或F_SETOWN)。
? 獲得/設(shè)置記錄鎖(cmd=F_GETLK,F_SETLK或F_SETLKW)。
?
我們將涉及與進程表項中各文件描述符相關(guān)聯(lián)的文件描述符標(biāo)志,以及每個文件表項中的文件狀態(tài)標(biāo)志,
一~復(fù)制文件描述符
? F_DUPFD 復(fù)制文件描述符filedes,新文件描述符作為函數(shù)值返回。它是尚未打開的各
描述符中大于或等于第三個參數(shù)值(取為整型值)中各值的最小值。新描述符與filedes共享同
一文件表項。但是,新描述符有它自己的一套文件描述符標(biāo)志,其F D _ C L O E X E C
文件描述符標(biāo)志則被清除。
? F_GETFD 對應(yīng)于filedes的文件描述符標(biāo)志作為函數(shù)值返回。當(dāng)前只定義了一個文件描
述符標(biāo)志FD_CLOEXEC。
? F_SETFD 對于filedes設(shè)置文件描述符標(biāo)志。新標(biāo)志值按第三個參數(shù)(取為整型值)設(shè)置。
應(yīng)當(dāng)了解很多現(xiàn)存的涉及文件描述符標(biāo)志的程序并不使用常數(shù) F D _ C L O E X E C,而是將此
標(biāo)志設(shè)置為0(系統(tǒng)默認(rèn),在exec時不關(guān)閉)或1(在exec時關(guān)閉)。
?
二~文件描述符號,套接口屬性相關(guān)
? F_GETFL 對應(yīng)于filedes的文件狀態(tài)標(biāo)志作為函數(shù)值返回。在說明open函數(shù)時,已說明
了文件狀態(tài)標(biāo)志 ??不幸的是,三個存取方式標(biāo)志(O_RDONLY,O_WRONLY,以及O_RDWR)并不各占1位。(正
如前述,這三種標(biāo)志的值各是0、1和2,由于歷史原因。這三種值互斥 — 一個文件只能有這
三種值之一。 )因此首先必須用屏蔽字O_ACCMODE相與 取得存取方式位,然后將結(jié)果與這三種值
相比較。
? F_SETFL 將文件狀態(tài)標(biāo)志設(shè)置為第三個參數(shù)的值(取為整型值)。 可以更改的幾個標(biāo)志是:
O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC。
fcntl的文件狀態(tài)標(biāo)志共有7個,O_RDONLY,O_WRONLY,O_RDWR,O_APPEND,O_NONBLOCK,O_SYNC和O_ASYNC
三~信號驅(qū)動I/O ,帶外數(shù)據(jù),設(shè)置套接口接受信號的屬主
SIGIO,跟信號驅(qū)動I/O有關(guān)
SIGURG, 和接受帶外數(shù)據(jù)有關(guān)
? F_GETOWN 取當(dāng)前接收SIGIO和SIGURG信號的進程ID或進程組ID。12.6.2節(jié)將論述這
兩種4.3+BSD異步I/O信號。
? F_SETOWN 設(shè)置接收SIGIO和SIGURG信號的進程ID或進程組ID。正的arg指定一個進
程ID,負的arg表示等于arg絕對值的一個進程組ID。
?
下面的例子使用F_GETFL和F_SETFL這兩種fcntl命令改變STDIN_FILENO的屬性,上O_NONBLOCK選項,實現(xiàn)非阻塞讀終端的功能。
用fcntl改變File Status Flag
#include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #define MSG_TRY "try again\n" int main(void) { char buf[10]; int n; int flags; flags = fcntl(STDIN_FILENO, F_GETFL); flags |= O_NONBLOCK; if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1){ perror("fcntl"); exit(1); } tryagain: n = read(STDIN_FILENO, buf, 10); if (n < 0) { if (errno == EAGAIN) { sleep(1); write(STDOUT_FILENO, MSG_TRY,strlen(MSG_TRY)); goto tryagain;} perror("read stdin"); exit(1);} write(STDOUT_FILENO, buf, n); return 0; }第四個函數(shù):int isatty(int desc);
(1)主要功能:是檢查設(shè)備類型 , 判斷文件描述詞是否是為終端機。
? ? ?返回值:如果參數(shù)desc所代表的文件描述詞為一終端機則返回1,否則返回0。
(2)isatty(STDIN_FILENO)
STDIN_FILENO的作用及與stdin 的作用和區(qū)別:
1.STDIN_FILENO的作用
? STDIN_FILENO屬于系統(tǒng)API接口庫,其聲明為 int 型,是一個打開文件句柄,對應(yīng)的函數(shù)主要包括 open/read/write/close 等系統(tǒng)級調(diào)用。
? 操作系統(tǒng)一級提供的文件API都是以文件描述符來表示文件。STDIN_FILENO就是標(biāo)準(zhǔn)輸入設(shè)備(一般是鍵盤)的文件描述符。
2.區(qū)別
1)數(shù)據(jù)類型不一致:
stdin類型為 FILE*
STDIN_FILENO類型為 int
使用stdin的函數(shù)主要有:fread、fwrite、fclose等,基本上都以f開頭
使用STDIN_FILENO的函數(shù)有:read、write、close等
2)stdin等是FILE *類型,屬于標(biāo)準(zhǔn)I/O,高級的輸入輸出函數(shù)。在<stdio.h>。
STDIN_FILENO等是文件描述符,是非負整數(shù),一般定義為0, 1, 2,屬于沒有buffer的I/O,直接調(diào)用系統(tǒng)調(diào)用,在<unistd.h>。
3)STDIN_FILENO 是標(biāo)準(zhǔn)輸入的文件描述符
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
4)層次不一樣。STDIN 屬于標(biāo)準(zhǔn)庫處理的輸入流,其聲明為 FILE 型的,對應(yīng)的函數(shù)前面都有f開頭,如fopen/fread/fwrite/fclose 標(biāo)準(zhǔn)庫調(diào)用等
STDIN_FILENO屬于系統(tǒng)API接口庫,其聲明為 int 型,是一個打開文件句柄,對應(yīng)的函數(shù)主要包括 open/read/write/close 等系統(tǒng)級調(diào)用。
標(biāo)準(zhǔn)庫內(nèi)封裝了系統(tǒng) API 調(diào)用,如 fread 內(nèi)部實現(xiàn)調(diào)用 read。
5)操作系統(tǒng)一級提供的文件API都是以文件描述符來表示文件。STDIN_FILENO就是標(biāo)準(zhǔn)輸入設(shè)備(一般是鍵盤)的文件描述符。
6)曾經(jīng)很納悶,為什么一個整形fd(STDIN_FILENO=0)就可以代表一個打開的文件呢?
后來明白了,和我們的手機號是類似的,手機號只是一個9位數(shù)的整形,但是在移動通話網(wǎng)絡(luò)里,它就可以用來區(qū)分不同的手機終端。
標(biāo)準(zhǔn)C++一級提供的文件操作函數(shù)庫都是用FILE*來表示文件,stdin就是指向標(biāo)準(zhǔn)輸入設(shè)備文件的FILE*。?
總結(jié)
以上是生活随笔為你收集整理的sigaction 函数,sigemptyset()函数,fcntl()函数,isatty()函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux线程-互斥锁pthread_
- 下一篇: UART0串口编程(一):通信协议设计;