In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail the trial analysis of the file input / output port under Linux. The editor thinks it is very practical, so I share it with you for reference. I hope you can get something after reading this article.
File descriptor (File Descriptor)
A small, nonnegative integer for use in subsequent system calls (read (2), write (2), lseek (2), fcntl (2), etc. ($man 2 open). When a program starts running, there are usually three file descriptors that are already open:
0: STDIN_FIFLENO, standard input stdin
1: STDOUT_FILENO, standard output stdout
2: STDERR_FILENO, standard error stderror
Fd principle
Starting from 0, fd looks for the smallest unused descriptor and corresponds the file table pointer to the file table descriptor (VS pid keeps going up, come back when it's full)
A file descriptor is an int that represents an open file, but the management information of the file cannot be stored in the file descriptor. When a file is opened using the open () function, OS will load the relevant information of the file into the file table and other data structures, but for the sake of security and efficiency, the file table and other data structures are not suitable for direct operation. Instead, you assign a number to the structure and use the number to operate, which is the file descriptor
OS maintains a summary table of file descriptors for each process. When a new file descriptor is required, it will go to the summary table to find the smallest unused descriptor to return. Although the file descriptor is of int type, it is actually a non-negative integer, that is, 0~OPEN_MAX (1024 in the current system), in which 01mem2 has been occupied by the system, representing stdin and stdout,stderror, respectively.
When you close fd with close (), the correspondence between fd and the file table structure is removed from the summary table, but the file table structure is not necessarily deleted. Only when the file table does not correspond to any other fd (that is, a file table can correspond to multiple fd at the same time) will the file table be deleted, and close () will not change the integer value of the file descriptor itself. It only prevents the file descriptor from representing a file.
Duplicate fdVS copy fd:dup copies the file table pointer corresponding to old_fd to new_fd, not int new_fd=old_fd
UNIX uses three data structures to describe open files: the file descriptor table used in each process to describe the file opened by the current process, the file status identification table that represents the current file status, and the V node table used to find the file I node (index node). This Vnode structure is not used in Linux and is replaced by a general inode structure, but there is no difference in essence. Inode is the location of the file that is imported from disk through the file system when reading the file
File descriptor flag (File Descriptor Flag)
The current system only has a file descriptor flag close-on-exec, which is only a flag, which is used when the process fork a child process when the exec function is called in the child process. The meaning is whether to close the file descriptor before executing exec.
Usually we will call exec to execute another program, and at this time we will replace the body, data, stack and stack of the child process with a brand new program. At this point, the variable that holds the file descriptor certainly does not exist, and we cannot close the useless file descriptor. So usually we will close the child process directly in the child process to turn off the useless file descriptor, and then execute the exec. But in complex systems, sometimes we don't know how many file descriptors (including socket handles, etc.) are open when we fork child processes, so it's really difficult to clean up one by one. What we expect is to be able to specify a file handle when it is opened before the exec child process: this handle is closed when I execute the file handle after the exec child process.
Each file descriptor has a close-on-exec flag. By default, this flag is set to 0. This flag is turned off. Then when the child process calls the exec function, the child process will not close the file descriptor. At this point, the parent and child processes will share the file, and they have the same file table entry, the same file offset, and so on.
The FD_CLOEXEC of fcntl () and the O_CLOEXEC of open () are used to set the close-on-exec of the file. When the close-on-exec flag is set to 1, this flag is turned on. At this time, the system has asked the child process to close the file descriptor before the child process calls the exec function.
Note: although the new version supports setting CLOEXEC at open, it still prompts an error at compile time-error: 'Olympus CLOEXEC' undeclared (first use in this function). This function needs to be opened by setting the macro (_ GNU_SOURCE).
# define _ GNU_SOURCE / / add-D_GNU_SOURCE / / in the source code to the compilation parameters
File status flag (File Status Flag)
File status flags is used to indicate the properties of an open file. File status flag can share the status of the same open file through a duplicate file descriptor, while file descrptor flag cannot.
Access Modes: indicates the access mode of the file: read-only, write-only,read-write. Returned via open () setting, returned via fcntl (), but cannot be changed
Open-time Flags: indicates the operation when open () executes. After open () executes, the flag will not be saved.
Operating Modes: affects read,write operations, set through open (), but can be read or changed with fcntl ()
Open ()
/ / given a file path name, open the file according to the corresponding options, that is, connect a fd to the file, and successfully return the file descriptor Failed return-1 set errno # include int open (const char * pathname, int flags) int open (const char * pathname, int flags, mode_t mode) / / is not a function overload, there is no overload in C Is a variable length parameter list / / pathname: file or device path / / flags: file status flags=Access mode+Open-time flags+Operating Modes, / * Access Mode (required): O_RDONLY:0 O_WRONLY:1 O_RDWR:2 * / * Open-time Flags (Bitwise Or): O_CLOEXEC: enable close-on-exec for the newly opened file descriptor. You can prevent the program from using the F_SETFD of fcntl () to set FD_CLOEXEC O_CREAT: create a file if the file does not exist and return its file descriptor, ignore this option if the file exists and must be used in protected mode, eg:0664 O_DIRECTORY: this option avoids denial-of-service problems if opendir () is called in a FIFO or tape, if the path points to a directory It will open and fail. O_EXCL: make sure that open () can pass through a file, and if the file already exists, it will cause the opening to fail and is always used with O_CREAT. O_NOCTTY: if the path points to a terminal device, then the device will not become the control terminal of the process, even if the process does not have a control terminal O_NOFOLLOW: if the path is a symbolic link, open its linked file / / If pathname is a symbolic link, then the open fails. O_TMPFILE: create an unnamed temporary file, and an unnamed inode will be created in the file system. When * a file descriptor is turned off, all writes to the file will be lost unless you give it the name O_TRUNC: clear the file O_TTY_INIT * / * Operating Modes (Bitwise Or) O_APPEND: open the file as an append, and write to the end by default In current Unix/Linux systems, this option has been defined as an atomic operation O_ASYNC: enable signal-driven signal-driven O O_DIRECT: an attempt to minimize the cache effect//Try to minimize cache effects of the I Unix/Linux O to and from this file from this file. O_DSYNC: each write operation waits for the completion of the Icano operation, but if the update of the file attribute does not affect the reading of the data just written, it does not wait for the update of the file attribute. O_LARGEFILE: allows you to open a file whose size exceeds the range indicated by off_t (but not more than off64_t) O_NOATIME: do not change the file's st_time (last access time) O_NONBLOCK / O_NDELAY: if possible, open the file in nonblock mode O_SYNC: each write operation waits for the completion of the write O operation, including updates to the file properties caused by write (). O_PATH: get a file descriptor # include # include int fd=open ("b.txt", O_RDWR | O_CREAT | 0664) that represents the location of the file in the file system; if (- 1==fd) perror ("open"), exit (- 1)
FA: the conjecture has the following model: an option is represented by a string in which one bit is 1 and the others are all zeros. If the options do "bitwise and", they will get the string "0 flags 1", which represents the state of the whole flags. Note: the lower three bits represent the Access Mode.
Creat ()
Equivalent to calling open () with the flag of O_WRONLY | O_TRUNC | O_CREAT
# include int creat (const char * pathname, mode_t mode)
Dup (), dup2 (), dup3 ()
/ copy the direction of a file descriptor, the new file descriptor's flags is the same as the original, successfully return new_file_descriptor, fail to return-1 and set errno # include int dup (int oldfd); / / use the lowest unoccupied file descriptor number as the new file descriptor int dup2 (int oldfd, int newfd); # include # include int dup3 (int oldfd, int newfd, int flags) # include # include int res=dup2 (fd,fd2); if (- 1==res) {perror ("dup2"), exit (- 1);}
Read ()
/ / read the data of count byte from the file corresponding to fd to the buffer starting with buf, and successfully return the number of byte successfully read. If failed,-1 set errno # include ssize_t read (int fd, void * buf, size_t count); # include # include int res=read (fd,buf,6); if (- 1==fd) perror ("read"), exit (- 1)
Write ()
/ / read the data of count byte from the buffer pointed to by buf and write it to the file corresponding to fd, and successfully return the number of byte successfully written. The location pointer of the file will move forward by this number. Failure returns-1 set errno # include ssize_t write (int fd, const void * buf, size_t count). / / No operation on buf is required, so there is const, VS read () does not have const#include # include int res=write (fd, "hello", sizeof ("hello")); if (- 1==res) perror ("write"), exit (- 1)
Note: in the above example, write "A" even if there is only one character'A', because "A" is the address and'A'is just an int.
Lseek ()
L stands for long int, historical reasons
/ / relocate the location pointer of the file according to the moving benchmark whence and the moving distance offset, and return the distance between the moved location pointer and the beginning of the file. If failed, return-1 set errno # include # include off_t lseek (int fd, off_t offset, int whence) / * whence: SEEK_SET: offset based on the beginning of the file. 0 generally cannot be offset forward. SEEK_CUR: offset based on the position of the current position pointer, 1 can be offset forward and backward SEEK_END: offset based on the end of the file, 2 forward and backward can to form a "file hole" # include # include int len=lseek (fd,-3,SEEK_SET) If (- 1==len) {perror ("lseek"), exit (- 1);}
Fcntl ()
/ / A pair of fd performs various operations and returns 0 for success and-1 for failure. Set errno # include # include int fcntl (int fd, int cmd,...); / /. Indicates the variable length parameter / * cmd: Adversory record locking: F_SETLK (struct flock*) / / sets the recommended lock F_SETLKW (struct flock*) / / sets the recommended lock. If there is a conflicting lock on the file and a signal is captured while waiting, the call is interrupted and an error is returned immediately after the signal is captured. If there is no signal during the wait, wait for F_GETLK (struct flock*) / / to try to release the lock. If you can put a lock, it will not put the lock, but will return a l_type type that contains F_UNLCK but other invariants. If it cannot, then fcntl () will add the new type of lock to the file and leave the current PID on the lock Duplicating a file descriptor: F_DUPFD (int) / / find the smallest file descriptor that can be used > = arg And use this file descriptor as a copy of fd F_DUPFD_CLOEXEC (int) / / just like F_DUPFD, except that close-on-execF_GETFD (void) / / reads fd's flag on the new file descriptor, ignores the value of arg F_SETFD (int) / / sets fd's flags to the value of arg. F_GETFL (void) / / read Access Mode and other file status flags of fd Ignore arg F_SETFL (long) / / set file status flags to arg F_GETOWN (void) / / return PID or process group ID F_SETOWN (int) on fd that accepts SIGIO and SIGURG / / sets PID on fd that accepts SIGIO and SIGURG or process group ID as arg F_GETOWN_EX (struct frankownergroup ex*) / / returns the file description of the current file defined by previous F_SETOWN_EX operations The symbol R F_SETOWN_EX (struct fanciownerkeeper ex*) / / is similar to F_SETOWN. Allows the calling program to hand over the fd's F_GETSIG O signal processing authority directly to a thread, process or process group F_GETSIG (void) / / return a signal F_SETSIG (int) / / send the signal specified by arg when the input and output of the file is available. : optional parameter, it depends on cmd. If it is locked, it should be struct flock* struct flock {short lock type; / /% d Type of lock: F_RDLCK (read lock), F_WRLCK (write lock), F_UNLCK (unlock) short lump where; / /% d How to interpret l_start, lock position reference standard: SEEK_SET, SEEK_CUR, SEEK_END off_t l_start / /% ld Starting offset for lock, the starting position of the lock off_t lags; / /% ld Number of bytes to lock, the number of bytes locked pid_t the number of bytes locked; / / PID of process blocking our lock, (F_GETLK only) the locked process number, default to-1}; * /
Recommended lock (Adversory Lock)
Restrict locking, but not read and write, so it is only valid for programs that read and write successfully. It is used to resolve conflicts caused by different processes writing to the same location of the same file at the same time.
Read lock is a shared lock (S lock): shared lock + shared lock
A write lock is an exclusive lock (X lock): always alone.
The method of releasing the lock (step by step):
Change the lock type to: F_UNLCK, and then reset it using the fcntl () function
When close () closes the fd, all locks imposed by the calling process on the fd are automatically released.
All file locks added by the process are automatically released at the end of the process.
Q: why can gedit or vim write with a write lock?
A: you can write. The lock can only control whether the lock is successful, not the reading and writing of the file, so it's called a "suggestion" lock. I added a lock because I don't want you to write. I can't help it if you have to write. Vim/gedit does not decide whether to read or write by whether the lock is successful or not, so it can go directly to
Q: how does So realize the read and write operation of file lock control file?
A: you can try to add a read lock before a read operation and a write lock before a write operation, and determine whether the read and write operation can be performed according to the success of the lock.
Int fd=open (". / a.txt", O_RDWR); / / get fd if (- 1==fd) perror ("open"), exit (- 1); struct flock lock= {FairRDLCK ("open"); struct flock lock= {FairRDLCKGH SEEKLEKSEEKLKGONE SEEKLKSETLING 2LING Lock 5LING Lock 1}; / / set the lock / / here start with the third byte (including the third) lock 5byte int res=fcntl (fd,F_SETLK,&lock) / / Lock fd if (- 1==res) perror ("fcntl"), exit (- 1)
Ioct1 ()
This function can perform functions that other file manipulation functions do not have. In most cases, it is used in device drivers. Each device driver can define its own set of ioctl commands, and the system provides general ioctl commands for different types of devices.
/ / manipulate the device parameters of special files. Return 0 for success and-1 for failure. Set errno # include int ioctl (int d, int request,...); / / d:an open file descriptor.//request: a device-dependent request code
Close ()
/ / close fd so that the fd can be used to connect to other files again. 0 is returned for success and-1 for failure is set to errno # include int close (int fd); # include # include int res=close (fd); if (- 1==res) perror ("close"), exit (- 1) This is the end of this article on "trial Analysis of File input / output Port under Linux". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it out for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.