linux .i文件,Linux 文件I/0

经过×××年的工作,经常使用的一些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 

{

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 

{

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 

/* 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 

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*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
make for plat=atlas310 cross=aarch64-ascend310-linux-gnu- LDFLAGS=-Wl,--gc-sections -static -L/home/257916/server/test/v1.1/Trunk/build/../src/thirdpart/libs/atlas310 -L/home/257916/server/test/v1.1/Trunk/build/../lib/atlas310 -ldw -lbs -lpthread -lm EXTRA_CFLAGS=-DSVN_VERSION="\"64670"\" -I /net -DOSA_MODULE_NAME=Spectrum-Convert@64670 -DBUILD_DATE="\"Mon, 24 Jul 2023 19:48:54 +0800"\" CFLAGS=-D_GNU_SOURCE -I/home/257916/server/test/v1.1/Trunk/build/../include -I/home/257916/server/test/v1.1/Trunk/build/../src/base/include -I/home/257916/server/test/v1.1/Trunk/build/../src/base/test/include -I/home/257916/server/test/v1.1/Trunk/build/../src/decode/include -I/home/257916/server/test/v1.1/Trunk/build/../src/decode/test/include -I/home/257916/server/test/v1.1/Trunk/build/../src/fourier/include -I/home/257916/server/test/v1.1/Trunk/build/../src/fourier/test/include -I/home/257916/server/test/v1.1/Trunk/build/../src/include -I/home/257916/server/test/v1.1/Trunk/build/../src/service/include -I/home/257916/server/test/v1.1/Trunk/build/../src/service/test/include -I/home/257916/server/test/v1.1/Trunk/build/../src/draw/include -I/home/257916/server/test/v1.1/Trunk/build/../src/draw/test/include -I/home/257916/server/test/v1.1/Trunk/build/../tools/include -fPIC -ffunction-sections -fdata-sections -g -Wall -O1 -c -o ############################################################ mkdir -p /home/257916/server/test/v1.1/Trunk/build/../bin/atlas310 aarch64-ascend310-linux-gnu-g++ -o draw test/src/draw_pic_test.o -Wl,--gc-sections -static -L/home/257916/server/test/v1.1/Trunk/build/../src/thirdpart/libs/atlas310 -L/home/257916/server/test/v1.1/Trunk/build/../lib/atlas310 -ldw -lbs -lpthread -lm /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: Relocations in generic ELF (EM: 62) /opt/Atlas310-ascend/toolkit/toolchain/hcc/bin/../lib64/gcc/aarch64-target-linux-gnu/7.3.0/../../../../aarch64-target-linux-gnu/bin/ld: test/src/draw_pic_test.o: error adding symbols: file in wrong format collect2: error: ld returned 1 exit status make[1]: *** [draw] Error 1 make[1]: Leaving directory `/home/257916/server/test/v1.1/Trunk/src/draw' make: *** [draw] Error 2
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值