真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Linux系統(tǒng)函數(shù)open、close、read、writ

系統(tǒng)調(diào)用

系統(tǒng)調(diào)用是操作系統(tǒng)提供給用戶的一組“特殊接口”。系統(tǒng)調(diào)用并非直接和程序員或系統(tǒng)管理員直接打交道,而是通過軟中斷的方式向內(nèi)核提交請求,從而獲取內(nèi)核函數(shù)的服務入口(系統(tǒng)調(diào)用表)。系統(tǒng)調(diào)用讓系統(tǒng)從用戶空間進入內(nèi)核空間內(nèi)運行,運行后將結(jié)果返回給應用程序(內(nèi)核態(tài)->用戶空間)。
Linux 系統(tǒng)函數(shù)open、close、read、writ

成都創(chuàng)新互聯(lián)主要從事成都網(wǎng)站制作、網(wǎng)站建設、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務洛川,10余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:13518219792

系統(tǒng)調(diào)用和系統(tǒng)API等區(qū)別



系統(tǒng)API
主要是通過C庫libc來實現(xiàn),程序員多采用這種方式與內(nèi)核交互,這些API通過系統(tǒng)調(diào)用來實現(xiàn)


系統(tǒng)命令
系統(tǒng)管理員采用系統(tǒng)命令與內(nèi)核交互,是一個可執(zhí)行文件,通過系統(tǒng)API及系統(tǒng)調(diào)用來實現(xiàn)


外殼程序
一系列系統(tǒng)命令和SHELL腳本共同組合成的程序。

函數(shù)庫調(diào)用 與 系統(tǒng)調(diào)用

Linux 系統(tǒng)函數(shù)open、close、read、writ

文件描述符



-每個進程PCB結(jié)構(gòu)中有文件描述符指針,指向files_struct的文件描述符表,記錄每個進程打開的文件列表
-系統(tǒng)內(nèi)核不允許應用程序訪問進程的文件描述符表,只返回這些結(jié)構(gòu)的索引即文件描述符ID(File Description)給應用程序
-Linux系統(tǒng)中,應用程序通過這些文件描述符來實現(xiàn)讓內(nèi)核對文件的訪問
-每個進程能夠訪問的文件描述符是有限制的,通過#ulimit –n可以查看

特殊文件描述符


標準輸入STDIN_FILENO
標準輸出STDOUT_FILENO
標準錯誤STDERR_FILENO


每個進程被加載后,默認打開0,1,2這三個文件描述符


open



-函數(shù)原型
int open(const char *path, int flags,mode_t mode);
-參數(shù)
path :文件的名稱,可以包含(絕對和相對)路徑
flags:文件打開模式
mode: 用來規(guī)定對該文件的所有者,文件的用戶組及系統(tǒng)中其他用戶的訪問權(quán)限,則文件權(quán)限為:mode&(~umask)
-返回值
打開成功,返回文件描述符;
打開失敗,返回-1


打開方式

Linux 系統(tǒng)函數(shù)open、close、read、writ

訪問權(quán)限

Linux 系統(tǒng)函數(shù)open、close、read、writ


O_CREATE會產(chǎn)生特殊權(quán)限,需要設置訪問權(quán)限:
S_IRWXU等價于 S_IRUSR|S_IWUSR|S_IXUSR (文件所有者)
S_IRWXG 等價于 S_IRGRP|S_IWGRP|S_IXGRP (文件用戶組)
S_IRWXO 等價于 S_IROTH|S_IWOTH|S_IXOTH (文件其他用戶)

close

關(guān)閉文件close(將進程中fd對應的文件描述表結(jié)構(gòu)釋放):
函數(shù)原型:int close(int fd); //如果出現(xiàn)錯誤,返回-1;調(diào)用成功返回0

read

-函數(shù)原型:
int read(int fd, void *buf, size_t nbytes);
-參數(shù)
fd :想要讀的文件的文件描述符
buf: 指向內(nèi)存塊的指針,從文件中讀取來的字節(jié)放到這個內(nèi)存塊中
nbytes: 從該文件復制到buf中的字節(jié)個數(shù)
-返回值
如果出現(xiàn)錯誤,返回-1;
返回從該文件復制到規(guī)定的緩沖區(qū)中的字節(jié)數(shù)!

write

-函數(shù)原型:int write(int fd,void *buf,size_t nbytes);
-函數(shù)參數(shù):
fd :要寫入的文件的文件描述符
buf: 指向內(nèi)存塊的指針,從這個內(nèi)存塊中讀取數(shù)據(jù)寫入 到文件中
nbytes: 要寫入文件的字節(jié)個數(shù)
-返回值
如果出現(xiàn)錯誤,返回-1
如果寫入成功,則返回寫入到文件中的字節(jié)個數(shù)


練習:采用文件系統(tǒng)調(diào)用的方式,完成串口通訊配置文件的讀寫


配置文件serial.cfg如下:
Linux 系統(tǒng)函數(shù)open、close、read、writ


要求:1、程序運行命令格式:
serialchat [-options];
[options]:
p-輸出打印serial.cfg各個配置項信息,格式:參數(shù)-----參數(shù)值;
s-進行菜單(有保存和退出)讓用戶設置;
f-指定配配置項設置,輸出各選項置文件名,并輸出各配置項信息
其他選項提示該程序用法幫助。
2、不支持serialchat運行兩次
3、如果無法找到配置文件,則提示運行失敗,原因:配置文件無法找到


代碼如下:

#include   < stdio.h>
#include   < string.h>
#include   < sys/types.h>
#include   < sys/stat.h>
#include   < unistd.h>
#include    < fcntl.h>

int icount = 0;

//去空格 '\0'
void rm_space(char *pStr)
{
    char *pos = pStr;
    pos = strchr(pStr,' ');
    while(pos != NULL)
    {
        strcpy(pos,pos+1);
        pos = strchr(pos,' ');
    }
}

//去注釋 '#' '\n#'和中文,留下\n ... \r之間的數(shù)據(jù)
void rm_annotation(char *pStr)
{
    icount++;
    char *pos = pStr;
    char *end = NULL;
    if(icount == 1) //第一行有可能頂格
    {
        pos = strchr(pStr,'#');
    }
    else
    {
        pos = strstr(pStr,"\n#");
    }

    while(pos != NULL)
    {
        end = strchr(pos+1,'\n');
        strcpy(pos,end);
        pos = strstr(pStr,"\n#");
    }   

}

//輸出配置項信息
void printMsg(char *buf)
{
    char key[20] = " ";
    char value[20] = " ";
    char line[50] = " ";
    char *pos = buf;
    char *end = NULL;
    int flag = 0;

    printf("配置項信息如下:\n");

    pos = strchr(buf,'\n');
    end = strchr(pos,'=');

    while(end != NULL)
    {
        memset(key,0,sizeof(key));
        memset(value,0,sizeof(value));
        memcpy(key,pos+1,end - (pos + 1));

        pos = end;
        end = strchr(pos,'\r');
        if(end == NULL) //if the final data
        {
            flag = 1;
            break;
        }
        memcpy(value,pos+1,end - (pos + 1));

        sprintf(line,"%s-----%s",key,value);
        printf("%s\n",line);

        pos = end + 1;
        end = strchr(pos,'=');  
    }

    if(flag)    
    {
        end = strchr(pos,'\0');
        memcpy(value,pos+1,end - (pos + 1));
        sprintf(line,"%s-----%s",key,value);
        printf("%s\n",line);
    }
}

//修改配置文件 (傳入的buf是未經(jīng)處理的)
void updateFile(int fd,char *buf)
{
    char *pos = buf;
    char *end = NULL;
    char key[20] = "";
    char newvalue[20] = "";
    int lse;
    int count;

    printf("請輸入配置參數(shù): ");
    scanf("%s",key);
    printf("請輸入配置參數(shù)的值: ");
    scanf("%s",newvalue);
    strcat(key,"=");
    pos = strstr(buf,key);
    if(pos == NULL)
    {
        printf("輸入?yún)?shù)不存在!");
        return;
    }
    pos = pos + strlen(key);
    while(*pos == ' ')  //處理'='后面有空格的情況
    {
        pos = pos + 1;
    }
    end = strchr(pos,'\r');
    if(end == NULL) //if the final data
    {
        end = strchr(pos,'\0');
    }
    //修改文件
    lse = lseek(fd,pos-buf,SEEK_SET);
    write(fd,newvalue,end-pos); //注意新舊值的長度
    printf("修改成功!\n");
}

/*--------------------主函數(shù)---------------------*/
int main(int argc,char *argv[])
{
    int fd;
    int readByte = 0;
    char buf[512] = "";
    char option[3] = "";
    char filename[20] = "";
    int  index;
    int s_flag = 0;
    int f_flag = 0;
    struct flock lock = {0};

    //判斷參數(shù)個數(shù)
    if(argc !=2 && argc != 3)
    {
        printf("輸入格式有誤!\n");
        return 1;
    }

    //打開配置文件
    strcpy(option,argv[1]);
    if(strcmp(option,"-f") == 0)    //打開指定文件
    {
        if(argc != 3)
        {
            printf("輸入格式有誤!\n");
            return 1;
        }
        f_flag = 1;
        strcpy(filename,argv[2]);
        fd = open(filename,O_RDWR,S_IRWXU|S_IRGRP);
    }
    else
    {
        fd = open("serial.cfg",O_RDWR,S_IRWXU|S_IRGRP);
    }

    if(fd == -1)
    {
        printf("運行失敗,無法找到配置文件!\n");
        return 1;
    }

    //讀取配置文件
    readByte = read(fd,buf,512);
    if(readByte <= 0)
    {
        printf("讀文件失敗!\n");
        return 1;
    }

    //判斷是否已經(jīng)加鎖
    fcntl(fd,F_GETLK,&lock);
    if(lock.l_type != F_UNLCK)
    {
        printf("文件已經(jīng)被上鎖!執(zhí)行錯誤\n");
        return 1;
    }
    //上鎖
    memset(&lock,0,sizeof(struct flock));
    lock.l_whence   = SEEK_SET;
    lock.l_start        = 0;
    lock.l_len      = sizeof(buf);
    lock.l_type     =F_WRLCK;
    if((fcntl(fd,F_SETLK,&lock)) == -1)
    {
        printf("設置寫鎖失??!\n");
        return 1;
    }

    //操作
    if(f_flag || strcmp(option,"-p") == 0)  //打印配置信息
    {
        rm_space(buf);
        rm_annotation(buf);
        printMsg(buf);
    }
    else if(strcmp(option,"-s") == 0)   //進行菜單
    {
        while(!s_flag)
        {
            printf("1.修改配置項\n2.退出\n請輸入選擇: ");
            scanf("%d",&index);
            switch(index)
            {
                case 1:
                    updateFile(fd,buf);
                    break;
                case 2:
                    s_flag = 1;
                    break;
            }
        }

    }
    else
    {
        printf("serialchat用法:\n");
        printf("\t命令格式:serialchat [-options]\n ");
        printf("\t   [options]: p-輸出打印serial.cfg各個配置項信息\n ");
        printf("\t   [options]: s-進行菜單\n ");
        printf("\t   [options]: f-指定配置文件\n ");
        printf("\t   [options]: 其他-查看幫助\n ");
    }

    //關(guān)閉文件
    close(fd);

    //釋放鎖
    lock.l_type     =F_UNLCK;
    fcntl(fd,F_SETLK,&lock);

    return 0;
}

運行結(jié)果:
1、 serialchat –p
Linux 系統(tǒng)函數(shù)open、close、read、writ
2、 serialchat-s
Linux 系統(tǒng)函數(shù)open、close、read、writ

3、 serialchat-f
Linux 系統(tǒng)函數(shù)open、close、read、writ
4、 異常處理
Linux 系統(tǒng)函數(shù)open、close、read、writ
5、 上鎖
終端1:
Linux 系統(tǒng)函數(shù)open、close、read、writ
終端2:
Linux 系統(tǒng)函數(shù)open、close、read、writ


網(wǎng)頁題目:Linux系統(tǒng)函數(shù)open、close、read、writ
網(wǎng)站鏈接:http://weahome.cn/article/gdcsig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部