After years of work ×××, often using some of the I / O (very important, because everything is a file Linu) function can be used later to view the next. This time not very busy, just to make a note of tidy.
File I / O standard and I / O library, some differences: 1) the file I / O system call, standard I / O package library is a library of system calls; 2) file I / O operations is the file descriptor (the kernel returns, is a non-negative integer, wherein 0, 1 represents the standard input, standard output and standard error), standard I / O operations is a flow i.e. FILE object; thus be seen that the standard I / O line transplant more it is good. When it comes to system calls, and then look at it, it is a system call interrupt is an interrupt 0x80 kernel implementation. This is a look at some of the major recording system corresponding to the file I / O calls.
1, open the file
int open (const char * pathname, int flag, / * mode_t mode * /) / * successful returns a file descriptor * /
pathname: To open or create a file name, the system provides for a maximum length;
flag: O_RDONLY open read-only. O_WRONLY write-only open. O_RDWR Open to read and write.
O_APPEND each appended to the end of the file write.
O_CREAT If no file is created.
O_EXEL If both O_CREAT, the file already exists, an error occurs.
O_TRUNC file exists and is read-only or write-only open, will be truncated to 0 length.
If O_NOCTTY terminal device, the device is not assigned as the control terminal of this process.
O_NONBLOCK a FIFO, a file or a block special character file to a non-blocking mode.
O_DSYNC, O_RSYNC, O_SYNC three not very understanding, later used further in-depth understanding.
mode: can not turn, means that setting user permissions, group permissions, other user rights, for example: 777: full rights to read, write, execute.
2, creat create a file
int creat (const char * pathname, mode_t mode); / * successful returns a file descriptor * /
Parameter Description through open function;
This function is equivalent to: open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
3, close Closes an open file
int close(int filedes);
Close a file will be added to the release of this file record locks; When a process terminates, automatically closes the file, so no need to explicitly call close to close this file.
4, current file offset setting function lseek
off_t lseek (int filedes, off_t offset, int whence); / * successful returns a new file offsets * /
Parameters offset and whence relevant, explained as follows:
SEEK_SET: setting the offset file from the file, starting at offset bytes.
SEEK_CUR: the offset of the file to the current value plus the offset, offset may be positive or negative.
SEEK_END: the offset of the file to file length plus offset, offset can be positive or negative.
* Can lseek (fd, 0, SEEK_CUR), if the return value of -1 is not described offset is set, otherwise an offset is provided.
5, the read data read from the file function
ssize_t read (int filedes, void * buf, size_t nbytes); / * Returns the number of bytes successfully read, such as the end of the file has been returned to the 0, -1 error * /
6, open the file to write data write
ssize_t write (int filedes, const void * buf, size_t nbytes); / * Returns the number of bytes successfully written, failed -1 * /
If the open time specified O_APPEND parameter, before each write, the file offset is set to the end. After a successful, inexpensive volume increase in the number of bytes actually written.
7, atomic function operation function and pwrite pread
In fact, with open O_APPEND parameter function operation can be achieved atoms, each end of the file is 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);
Equivalent to the order to call lseek and read or write
8, copy an existing file descriptor dup and dup2
int dup(int filedes);
int dup2(int filedes,int filedes2 );
dup returns the minimum value of file descriptors currently available: dup (1) returns a shared 3,3
If the parameters are equal dup2 return filedes2, otherwise, filedes share filedes2 and close filedes2.
For some time ago to develop a zebra into the serial command line examples:
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) / * * set 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, changing the nature of the fcntl open files
int fcntl (int filedes, int cmd, / * int arg * /, / * flock record locking * /)
There are five functions are enabled by setting cmd:
1) an existing copy descriptor (F_DUPFD);
dup (filed); / * equivalent * / the fcntl (Filed, F_DUPFD, 0); dup2 (Filed, filed2); / * equivalent * / Close (filed2); the fcntl (Filed, F_DUPFD, filed2); / * dup2 close + fcntl and the difference is: the former is an atomic operation, the latter is not * /
2) Gets or sets the file descriptor tag (for F_GETFD or F_SETFD);
3) Gets or sets the file descriptor flags (F_GETFL or F_SETFL), several flags can be changed: O_APPEND, O_NONBLOCK, O_SYNC, O_DSYNC, O_RSYNC, O_FSYNC, O_ASYNC;
4) Gets or sets the file asynchronous I / O ownership (F_GETOWN, or F_SETOWN), get or set receiving SIGIO, process ID SIGURG signals or process group ID;
5) Gets or sets the record locks (F_GETLK, F_SETLK or F_SETLKW), by the structure flock.
10, I / 0 ioctl function operation grocery
The above function can not be operated with the document can be operated with ioctl
int ioctl(int filedes,int request ,/*void *arg*/)
Many functions are roughly classified into: 1) socket 2) file operation 3) interface operation 4) arp cache operation 5) a routing table operation 6) flow system.
For example, a job some time ago with the development of static routing, arp cache query table:
/ * B-added by zhaoxiaohu to serch IP AT ARP Cache * / / * definition of the structure * / typedef struct tArpTable { struct tArpTable * pNext; unsigned char Data [0]; } * ptVlanIpDev; ptVlanIpDev g_ptVlanIpDevTable = NULL; / * Display switching chip added virtual interface, VLAN IP * / void vlanIpDevTableDisplayAll () { ptVlanIpDev PTEMP = g_ptVlanIpDevTable; the while (PTEMP) { the printf ( "% S \ R & lt \ n-", pTemp-> Data); PTEMP = pTemp-> pNext; } } / * Clear virtual interface table * / void arpTableClear () { ptVlanIpDev PTEMP = NULL; the 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*/