File I/O problems in Linux

Source: Internet
Author: User
Tags flock flock lock

For operating files or devices in Linux, a file descriptor and FD are required for reference. FD is a non-negative integer, which is actually an index value. It points to the file's record table and requires FD for file operations. Default values: stdin_fileno is 0, stdout_fileno is 1, and stderr_fileno is 2. The following describes several file operations related functions: open close read write lseek fcntl

1. Open

# Include <sys/types. h> // provides the pid_t definition # include <sys/STAT. h> # include <fcntl. h> int open (char * filepath, int flag, int perms)/** flags: o_rdonly (read-only) * o_wronly (write only) o_rdwr (read/write) o_creat (created if the file does not exist) o_excl (if the file already exists when o_creat is used, an error is returned to verify whether the file exists) o_trunc (delete the original file content first) o_noctty O + append (opened in append mode, the file Pointer Points to the end of the file) except the first three, the rest can be mutually | combination; perms File Permission; FD is returned successfully, -1 is returned for failure ;*/

2. Close

# Include <unistd. h> int close (int fd)/* return 0 if the request is successful, return-1 */

3. Read

# Include <unistd. h> ssize_t read (int fd, void * Buf, size_t count)/* after reading a row or reading a count byte, return the number of bytes read successfully; return 0 at the end of the file. Return-1 */

4. Write

# Include <unistd. h> ssize_t write (int fd, void * Buf, size_t count)/* The number of written bytes is returned successfully.-1 */

5. lseek

# Include <unistd. h> # include <sys/types. h> off_t lseek (int fd, off_t offset, int whence)/* move the file pointer, whence as the benchmark, value: seek_set: Start of the file; seek_cur: current location; seek_end: end of the file. The actual offset value is offset + whence offset, which can be positive or negative. Returns the current location. Returns-1 */

6. fcntl
One of the functions of the fcntl function is to lock the file. The lock applied to a certain record of the file becomes a record lock. Record locks are divided into read locks and write locks. Read locks are also known as shared locks. They allow multiple processes to create read locks in the same part of the file. Write locks are also known as rejection locks, at any time, only one process can create a write lock on a part of the file. The read and write locks cannot be created for the same part of the file at the same time.

# Include <sys/types. h> # include <unistd. h> # include <fcntl. h> int fcntl (int fd, int cmd, struct flock * Lock)/* cmd: f_dupfd copy FD; f_setfd f_getfd f_getfl indicates the flag f_setfl set when open is obtained. f_getlk determines whether to apply the file lock f_setlk to lock. f_setlkw f_getown indicates that sigio or sigurg signals are received. process No. Or Process Group No. f_setown set process no. Or Process Group No. struct flock {short l_type; off_t l_start; short l_whence; off_t l_len; pid_t l_pid;} l_type can be f_rdlck Read lock; f_wrlck write lock; f_unlck unlock. The locking area is the area starting from l_start + l_whence and starting from l_len length. The method of locking the entire file is usually Rochelle start is 0, l_whence is seek_set, and l_len is 0. Success returns 0, Failure Returns-1 */

File lock instance:

#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <unistd.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>void lock_set(int fd, int type){    struct flock lock;    lock.l_whence = SEEK_SET;    lock.l_start = 0;    lock.l_len = 0;    while(1)    {        lock.l_type = type;        if(fcntl(fd, F_SETLK, &lock)==0)        {//lock set successful            if(lock.l_type==F_RDLCK)                printf("set read lock by pid %d.\n", getpid());//current pid            else            if(lock.l_type==F_WRLCK)                printf("set write lock by pid %d.\n", getpid());            else            if(lock.l_type==F_UNLCK)                printf("release lock by pid %d.\n", getpid());            return;        }        /*set lock failed, print why and wait usr press any key to set lock again*/        fcntl(fd, F_GETLK, &lock);        if(lock.l_type!=F_UNLCK)        {            if(lock.l_type==F_RDLCK)                printf("read lock already set by pid %d.\n", lock.l_pid);            else            if(lock.l_type==F_WRLCK)                printf("write lock already set by pid %d.\n", lock.l_pid);            getchar();        }    }}

Read locks are shared. After a process is locked, other processes can be locked. Write locks are mutually exclusive and only one process can be locked at a time.
 

7. Select

Io multi-channel transfer model, used for Io multiplexing.

# Include <sys/types. h> # include <sys/time. h> # include <unistd. h> int select (INT numfds, fd_set * readfds, fd_set * writefds, fd_set * exeptfds, struct timeval * timeout) numfds: Maximum monitored file descriptor + 1; readfds: set of monitored read file descriptors; writefds: Set of monitored write file descriptors; exepetfds: Set of monitored exception handling file descriptors; Timeout: NULL indicates waiting forever until the signal is captured, 0 indicates that the system never waits and returns immediately. The prepared file descriptor is returned successfully. If the file descriptor fails,-1 is returned.

Related operation macros:

Fd_zero (fd_set * FDs) // clear the file descriptor set fd_set (int fd, fd_set * FDs) // Add FD to FDS fd_clr (int fd, fd_set * FDs) // clear fd_isset (int fd, fd_set * FDs) from FDS // determine whether the FD in FDS is changed

 

Struct timeval

struct timeval{    long tv_sec;    long tv_unsec;//microsecond 1/1000000 s}

One select instance for Io multi-channel transfer:

#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <unistd.h>int select_test(){    int fd_read, fd_write;    int ret;    fd_set readfds, writefds;    struct timeval tv;    if((fd_read = open("xxx.c", O_RDWR|O_CREAT, 0666))<0)        perror("open read.\n");    if((fd_write = open("ooo.c", O_RDWR|O_CREAT, 0666))<0)        perror("open write.\n");    lseek(fd_read, 0, SEEK_SET);    FD_ZERO(&readfds);    FD_ZERO(&writefds);    FD_SET(fd_read, &readfds);    FD_SET(fd_write, &writefds);    tv.tv_usec = 0;    tv.tv_sec = 2;    while(FD_ISSET(fd_read, &readfds)||FD_ISSET(fd_write, &writefds))    {        ret = select(fd_write+1, &readfds, &writefds, NULL, &tv);        if(ret < 0)            perror("select");        else        {            if(FD_ISSET(fd_read, &readfds))            {                //read fd_read            }            if(FD_ISSET(fd_write, &writefds))            {                //write fd_write            }        }    }    return 0;}

 

The above file operations are the basic Io Control Based on file descriptors, without caching, and belong to the POSIX standard. The following describes the ansi c standard I/O processing, which is based on stream buffering. The ansic c Standard provides three types of Buffer Storage: Full buffer (actual Io operations are performed only after the cache is filled up) and row buffer (actual Io operations are performed only when line breaks occur ); without buffering (stderr is usually not circulating with buffering ). The following describes the related operation functions:

1. fopen fdopen freopen

If the call succeeds, a file pointer is returned. If the call fails, null is returned. Parameters are different.

Mode value:

R or RB: open a read-only file, which must exist;

W or WB: open a readable or writable file, which must exist;

W + or W + B: open a readable or writable file. If the file exists, the file length is 0. If the file does not exist, the file is created;

A or AB: open and write-only files as an attachment. If the file does not exist, create the file first. Otherwise, add the data to the end of the original file;

A + or a + B: open a read/write file as an attachment. If the file does not exist, create the file. Otherwise, add the data to the end of the original file;

B indicates that the opened file is a binary file.

2. fclose

0 is returned for success, and EOF is returned for failure.

3. fread

# Include <stdio. h> size_t fread (void * PTR, size_t size, size_t nmemb, file * stream)/* return the number of successful reads, and EOF */

4. fwrite

# Include <stdio. h> size_t fwrite (const void * PTR, size_t size, size_t nmemb, file * stream)/* returns the number of actually written data, and EOF */

5. Several input/output functions

# Include <stdio. h> int GETC (File * stream) int fgetc (File * stream) int getchar (void)/* success return character failure return EOF */INT putc (int c, file * stream) int fputc (int c, file * stream) int putchar (int c)/* returns C if the operation succeeds, and returns EOF * If the operation fails */
Char * fgets (char * s, int size, file * stream) char * gets (char * s) /* If S is returned successfully, null */INT puts (const char * s) int fput (const char * s, file * stream) is returned)

 

Next we will study serial port application development in Linux.

I don't want to talk about the serial port itself. In Linux, the device corresponding to the serial port is/dev/ttys0,/dev/ttys1... Corresponding to serial 1, Serial 2 .... In Linux, the device operation method is the same as the file operation method. Therefore, reading and writing to the serial port is read and write, and other parameters of the serial port need to be configured separately. This is different.

In Linux, the serial port settings are mainly to set struct termios

# Include <termios. h> struct termios {unsigned short c_iflag; // input mode flag unsigned short c_oflag; // output mode flag unsigned short c_cflag; // control mode flag unsigned short c_lflag; // unsigned char c_line in local mode; // line discipline unsigned char c_cc [NCC]; // control Char}

This is usually the case:

Int set_opt (int fd, int nspeed, int nbits, char nevent, int nstop) {struct termios newtio, oldtio; If (tcgetattr (FD, & oldtio )! = 0) {perror ("set serial. "); Return-1;} bzero (& newtio, sizeof (newtio);/* Set serial * // * Step 1: Set the character size */newtio. c_cflag | = clocal | cread; newtio. c_cflag & = ~ Csize;/* Step 2: Set the stop bit */switch (nbits) {Case 7: newtio. c_cflag | = cs7; break; case 8: newtio. c_cflag | = cs8; break;}/* Step 3: Set the parity bit */switch (nevent) {Case 'O':/* odd check */newtio. c_cflag | = parenb; newtio. c_cflag | = parodd; newtio. c_cflag | = inpck | istrip; break; Case 'E':/* even check */newtio. c_cflag | = inpck | istrip; newtio. c_cflag | = parenb; newtio. c_cflag & = ~ Parodd; break; Case 'N':/* no verification */newtio. c_cflag & = ~ Parenb; break;}/* step4: Set the baud rate */switch (nspeed) {/* You cannot directly operate c_cflag using a specific function */case 2400: cfsetispeed (& newtio, b2400); // receives the baud rate cfsetospeed (& newtio, b2400); // sends the baud rate break; Case 4800: cfsetispeed (& newtio, b4800); cfsetospeed (& newtio, b4800 ); break; Case 9600: cfsetispeed (& newtio, b9600); cfsetospeed (& newtio, b9600); break; Case 115200: cfsetispeed (& newtio, b115200); cfsetospeed (& newtio, b115200); break; c ASE 460800: cfsetispeed (& newtio, b460800); cfsetospeed (& newtio, b460800); break; default: cfsetispeed (& newtio, b9600); cfsetospeed (& newtio, b9600 ); break;}/* step5: Set the stop bit */If (nstop = 1) newtio. c_cflag & = ~ Cstopb; else if (nstop = 2) newtio. c_cfalg | = cstopb;/* stcp6: Set the waiting time and the minimum receiving character */newtio. c_cc [vtime] = 0; newtio. c_cc [Vmin] = 0;/* handle unreceived characters */tcflush (FD, tciflush);/* activate new configuration */If (tcsetattr (FD, tcsanow, & newtio ))! = 0) {perror ("set serial"); Return-1;} return 0 ;}

Open the serial port is usually like this:

Int open_port (INT comport) {char * Dev [] = {"/dev/ttys0", "/dev/ttys1", "/dev/ttys2"}; long vdisable; int FD; char * comdev = NULL; If (comport = 1)/* Serial Port 1 */comdev = "/dev/ttys0"; if (comport = 2) comdev = "/dev/ttys1"; if (comport = 3) comdev = "/dev/ttys2"; if (comdev = NULL) Return-1; if (FD = open (comdev, o_rdwr | o_noctty | o_ndelay) <0) Return-1;/* restore the serial port blocking status */If (fcntl (FD, f_setfl, 0) <0) printf ("fcntl failed. \ n ");/* test whether it is a terminal device */If (isatty (stdin_fileno) = 0) printf (" standard input is not a terminal device. \ n "); else printf (" isatty success. \ n "); Return FD ;}

Test:

#include <stdio.h>#include <string.h>#include <sys/types.h>#include <errno.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <termios.h>#include <stdlib.h>int com_test(){    int fd;    int nread, i;    if((fd = open_port(1))<0)    {        perror("open port failed.");        return -1;    }    if((i = set_opt(fd, 115200, 8, 'N', 1))<0)    {        perror("set port failed.");        return -1;    }    //read(fd, buf, 8);    close(fd);    return 0;}

 

Well, let's do it first.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.