亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux 文件I/0

發布時間:2020-06-09 20:24:09 來源:網絡 閱讀:342 作者:昵稱真難改 欄目:系統運維

? ? 經過×××年的工作,經常使用的一些I/O(很重要,因為Linu一切皆文件)函數,以后用到可以查看下。這段時間不是很忙,僅僅為了做個筆記整理一下。

????文件I/O和標準I/O庫有的區別:1)文件I/O是系統調用,標準I/O庫是封裝了系統調用的函數庫;2)文件I/O操作的是文件描述符(內核返回,是一個非負整數,其中0,1,2代表標準輸入,標準輸出,標準錯誤),標準I/O操作的是流即就是FILE對象;因此可見標準I/O的移植行更好。說到系統調用,再來說一下,系統調用就是一個中斷值為0x80內核實現的一個中斷。這一篇主要記錄一下對應文件I/O的一些系統調用。

1、打開文件

????int open(const char *pathname, int flag,/*mode_t mode*/)/*成功返回文件描述符*/

????pathname:要打開或創建文件的名字,系統規定了一個最大長度;

????flag:O_RDONLY 只讀打開。O_WRONLY 只寫打開。O_RDWR 讀寫打開。

????O_APPEND 每次寫時追加到文件尾部。

????O_CREAT 若無文件,則創建它。

????O_EXEL 如果同時指定了O_CREAT,文件已經存在,則會出錯。

????O_TRUNC 文件存在,并為只讀或只寫打開,則將長短截取為0。

????O_NOCTTY 如果是終端設備,則不將該設備分配作為此進程的控制終端。

????O_NONBLOCK 將一個FIFO、一個塊特殊文件或一個字符文件設置為非阻塞模式。

????O_DSYNC、O_RSYNC、O_SYNC三個不是很理解,以后用到再深入理解。

????mode:可又可無,意思就是設置用戶權限,組權限,其他用戶權限 ,例如:777:全權限讀、寫、可執行。

2、creat創建文件

????int creat( const char *pathname, mode_t mode);/*成功返回文件描述符*/

????參數說明通open函數;

????此函數等價于:open( pathname,O_WRONLY| O_CREAT|O_TRUNC,mode);

3、close關閉一個打開文件

????int close(int filedes);

????關閉一個文件還會釋放加在此文件上的記錄鎖;當一個進程終止后,自動關閉文件,所以不用顯示的調用close去關閉此文件。

4、設置當前文件偏移量lseek函數

????off_t lseek(int filedes, off_t offset ,int whence);/*成功返回新的文件偏移量*/

????參數offset和whence有關,解釋如下:

????SEEK_SET:將文件的偏移量設置距文件開始處offset個字節。

????SEEK_CUR:將文件的偏移量設置當前值加上offset,offset可正或負。

????SEEK_END:將文件的偏移量設置為文件長度加offset,offset可正可負。

????*可以用lseek(fd,0,SEEK_CUR),如果返回值為-1說明沒有設置偏移量,否則設置了偏移量。

5、從文件中讀數據read函數

????ssize_t read(int filedes,void *buf,size_t nbytes);/*成功返回讀的字節數,如已經到文件結尾返回0,出錯返回-1*/

6、給打開的文件寫數據write

????ssize_t write(int filedes,const void *buf,size_t nbytes);/*成功返回寫的字節數,失敗返回-1*/

????如果open的時候指定了O_APPEND參數,則每次寫之前,將文件偏移量設置到結尾處。在一次成功后,便宜量增加實際寫的字節數。

7、原子操作函數pread和pwrite函數

????其實用open函數中的O_APPEND參數就可以實現原子操作,每次write都是在文件尾部。

????ssize_t pread(int fd,void *buf,size_t count,off_t offset);

????ssize_t pwrite(int fd,const void *buf,size_t count,off_t offset);

????相當于順序調用lseek和read或write

8、復制一個現有的文件描述符dup和dup2

????int dup(int filedes);

????int dup2(int filedes,int filedes2 );

????dup返回當前可用的最小文件描述符的值:dup(1)返回3,3共享1

????dup2如果兩個參數相等返回filedes2,否則,filedes共享filedes2并關閉filedes2。

????舉一個前段時間開發串口進zebra命令行的例子:

int?config_console_para(int?iConsoleFd);/*modified?by?zhaoxiaohu*/
/*added?by?zhaoxiaohu?for?console?to?vty*/
struct?vty?*vty_console_create(?char?*dev?)
{
????int?fd;
????int?iRet;
????struct?vty?*vty;
????fd?=?open(?dev,?O_RDWR,?0644?);
????if(?fd?<?0?)
????{
???????printf(?"error:?open?console?%s?error.\r\n",?dev?);
???????return?NULL;
????}
????iRet?=?config_console_para(fd);
????if(0?!=?iRet)
????{
????????printf("console?para?set?error.\r\n");
????}
????vty?=?vty_get_new();

????if(?vty?==?NULL?)?return?NULL;
????vty->fd?=?fd;
????vty->type?=?VTY_CONSOLE;
????strcpy(?vty->address,?"Console"?);
????vty->node?=?LOGIN_NODE;
????vty->fail?=?0;
????vty_clear_buf(?vty?);
????vty->status?=?VTY_NORMAL;
????vty_hello(?vty?);
????vty_prompt(?vty?);
????buffer_flush_all(?vty->obuf,?vty->fd?);
????/*?Add?read/write?thead?*/
????vty_event(?VTY_WRITE,?vty?);
????vty_event(?VTY_READ,?vty?);
????return?vty;
}
/*b-console?config?added?by?zhaoxiaohu,2018-12-19*/
/*配置串口參數*/
int?config_console_para(int?iConsoleFd)
{
????struct?termios?tConsolePara;

????if?(iConsoleFd?<?3?)
????{
????????printf("fd?is?error.\r\n");
????????return?-1;
????}
????
????if(tcgetattr(iConsoleFd,&tConsolePara)?!=?0)
????{
????????printf("get?console?para?error.\r\n");
????????return?-1;
????}
????tConsolePara.c_lflag?&=?~?(ICANON?|?ECHO?|?ECHOE?|?ISIG);
????tConsolePara.c_cc[VERASE]?=?1;
????if(tcsetattr(iConsoleFd,TCSANOW,&tConsolePara)?!=?0)
????{
????????printf("config?console?para?error.\r\n");
????????return?-1;
????}
????if(?cfsetispeed(&tConsolePara,B115200)?!=?0?)/*設置為115200Bps*/
????{
????????printf("config?console?para?error.\r\n");
????????return?-1;
????}
????if(?cfsetospeed(&tConsolePara,B115200)?!=?0?)/*設置為115200Bps*/
????{
????????printf("config?console?para?error.\r\n");
????????return?-1;
????}
????return?0;
}
/*e-console?config?added?by?zhaoxiaohu,2018-12-19*/

/*b-added?by?zhaoxiaohu?for?console?to?connect?vty?shell*/
void?console_connect_vty(void?)
{
????struct?vty?*vty;
????int?iConsoleFd,?iRet;
????vty?=?vty_console_create("/dev/console");???
????g_pVty?=?vty;
????g_iConsoleFd?=?vty->fd;
????iConsoleFd?=?vty->fd;
????dup2(iConsoleFd,0);/*close?0,1,2,共享到串口*/
????dup2(iConsoleFd,1);/**/
????dup2(iConsoleFd,2);/**/
????setvbuf(stdout,NULL,_IONBF,0);/*set?stdout?no?buffer,printf?to?console?.added?by?zhaoxiaohu-2019.4.10*/
????struct?timeval?time_now;
????struct?timeval?*time_wait;
????while(1)
????{
????????#if?1
????????time_now.tv_sec?=?vty->v_timeout;
????????time_now.tv_usec?=?0;

????????if(?time_now.tv_sec?>?0?)
????????????time_wait?=?&time_now;
????????else
????????????time_wait?=?NULL;
????????
????????iRet?=?select(?iConsoleFd?+?1,?&vty->read_set,?&vty->write_set,?NULL,?time_wait?);

????????if(?iRet?<=?0?)
????????{
????????????/*?error:?close?vty?*/
????????????if(?iRet?<?0?)?break;

????????????/*?rc?==?0,?timeout?!?console?timeout?*/
????????????if(?vty->type?==?VTY_CONSOLE?)
????????????{
????????????????vty_timeout(?vty?);
????????????????continue;
????????????}
????????????else
????????????{
????????????????vty_timeout(?vty?);
????????????????break;
????????????}
????????}
????????#endif
????????if(?FD_ISSET(?iConsoleFd,?&vty->read_set?)?)
????????????vty_read(?vty?);

????????if(?FD_ISSET(?iConsoleFd,?&vty->write_set?)?)
????????????vty_flush(?vty?);

????????/*?console?can't?close?*/
????????if(?vty->type?==?VTY_CONSOLE?)?continue;

????????if(?vty->status?==?VTY_CLOSE?)?break;
????}
????return;
}
/*e-added?by?zhaoxiaohu?for?console?to?connect?vty?shell*/


9、改變打開文件的性質函數fcntl

????int fcntl(int filedes,int cmd,/*int arg*/,/*flock記錄鎖*/)

????函數有五種功能通過設置cmd:

????1)復制一個現存的描述符(F_DUPFD);

dup(filed);/*等效于*/
fcntl(filed,F_DUPFD,0);
dup2(filed,filed2);?/*等效于*/
close(filed2);
fcntl(filed,F_DUPFD,filed2);
/*dup2?和close+fcntl區別是:前者是原子操作,后者不是*/

????2)獲取或設置文件描述符標記(F_GETFD或F_SETFD);

????3) 獲取或設置文件描述符標志(F_GETFL或F_SETFL),可以改變的幾個標志:O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC、O_ASYNC;

????4) 獲取或設置文件異步I/O所有權(F_GETOWN或F_SETOWN),獲取或設置接收SIGIO、SIGURG信號的進程ID或進程組ID;

????5)獲取或設置記錄鎖(F_GETLK、F_SETLK或F_SETLKW),通過結構體flock。

10、I/0操作的雜貨鋪ioctl函數

????不能用上面函數操作的文件都可以用ioctl操作

????int ioctl(int filedes,int request ,/*void *arg*/)

????功能很多,大致分為:1)套接口2)文件操作3)接口操作4)arp高速緩存操作5)路由表操作6)流系統。

????舉一個前段時間工作中用開發靜態路由,查詢arp緩存表的例子:

/*b-added?by?zhaoxiaohu?to?serch?ip?at?arp?cache*/
/*定義結構體*/
typedef?struct?tArpTable{
???????struct?tArpTable?*pNext;
???????unsigned?char?data[0];
}*ptVlanIpDev;

ptVlanIpDev?g_ptVlanIpDevTable?=?NULL;
/*顯示交換芯片添加的虛接口,vlan?ip*/
void?vlanIpDevTableDisplayAll()
{
????ptVlanIpDev?pTemp?=?g_ptVlanIpDevTable;
????while(pTemp)
????{
????????printf("%s\r\n",pTemp->data);
????????pTemp?=?pTemp->pNext;
????}
????????
}
/*清除虛接口表*/
void?arpTableClear()
{
????ptVlanIpDev?pTemp?=?NULL;
????while(g_ptVlanIpDevTable)
????{
????????pTemp?=?g_ptVlanIpDevTable;
????????g_ptVlanIpDevTable?=?pTemp->pNext;
????????free(pTemp);
????????pTemp?=?NULL;??
????}
}
/*獲取虛接口*/
int?get_vlan_ip_dev()
{
???????unsigned?char?ucBuf[256]?=?{0};
???????FILE?*fp;
???????fp?=?popen("find?/sys/class/net/?-name?sw.*",?"r");
???????if(?NULL?==?fp?)
???????{
???????????return?-1;
???????}
???????arpTableClear();
???????while(?fgets(?ucBuf,?sizeof(ucBuf),?fp?)?)
???????{
????????????
????????????ptVlanIpDev?pTemp?=?NULL;
????????????if(?NULL?==?(pTemp?=?(ptVlanIpDev)calloc(1,sizeof(struct?tArpTable)?+?sizeof(ucBuf)?))?)
????????????????continue;
????????????memcpy(?pTemp->data,ucBuf,strlen(ucBuf)?);
????????????pTemp->pNext?=?g_ptVlanIpDevTable;
????????????g_ptVlanIpDevTable?=?pTemp;
????????????memset(?ucBuf,0,sizeof(ucBuf)?);
???????}
???????pclose(fp);
???????return?OK;
}
int?ipnet_arp_for_cache(??)
{
????
????int?sfd,ret;
????unsigned?char?*ucMac;
????unsigned?char?ucIpAddrStr[32]?=?{0};
????struct?arpreq?arp_req;
????struct?sockaddr_in?*sin;
????get_vlan_ip_dev();
????ptVlanIpDev?pTemp?=?g_ptVlanIpDevTable;
????ip2Str(?g_ArpFindIpAddr,?ucIpAddrStr?);/*要查詢的ip*/
????while(pTemp)?/*遍歷所有的虛接口*/
????{
????????sin?=?(?struct?sockaddr_in?*?)&(?arp_req.arp_pa?);
????????memset(?&arp_req,?0,?sizeof(arp_req)?);
????????sin->sin_family?=?AF_INET;
????????inet_pton(?AF_INET,?ucIpAddrStr,?&(sin->sin_addr)?);
????????
????????strncpy(?arp_req.arp_dev,?pTemp->data+15,strlen(pTemp->data+15)-1?);
????????sfd?=?socket(?AF_INET,?SOCK_DGRAM,?0?);

????????ret?=?ioctl(?sfd,?SIOCGARP,?&arp_req?);
????????if?(ret?<?0)?{
????????????goto?nextNode;
????????}
????????if?(?arp_req.arp_flags?&?ATF_COM?)?/*找到ip對應的mac地址*/
????????{
????????????
????????????ucMac?=?(unsigned?char?*)arp_req.arp_ha.sa_data;
????//????????printf("MAC:?%02x:%02x:%02x:%02x:%02x:%02x\n",
??????//??????????????ucMac[0],?ucMac[1],?ucMac[2],?ucMac[3],?ucMac[4],?ucMac[5]);
????????????memcpy(?gArpFindMac,?ucMac,?6?);
????????}?
????????else?
????????{
???//?????????printf("MAC:?Not?in?the?ARP?cache.\n");
????????}
????????nextNode:
????????pTemp?=?pTemp->pNext;
????}
????
????return?OK;
}


/*e-added?by?zhaoxiaohu?to?serch?ip?at?arp?cache*/



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新和县| 石林| 凭祥市| 密云县| 正镶白旗| 吴江市| 瑞安市| 抚远县| 桦甸市| 子洲县| 怀来县| 神农架林区| 黑河市| 灵山县| 吉水县| 宾川县| 彰化市| 漠河县| 陆河县| 东莞市| 岢岚县| 景洪市| 宣城市| 巩义市| 惠安县| 大丰市| 卓资县| 云林县| 南宁市| 资源县| 云和县| 敦化市| 隆林| 蓝田县| 武穴市| 华坪县| 沂南县| 文化| 衡东县| 称多县| 高安市|