Unix Environment Advanced Programming Chapter 3 File IO

xiaoxiao2021-03-05  51

Chapter 3 Document I / O3.1 Introduction This chapter begins to discuss U N i x system, first explain the available file I / O functions - open files, read files, write files, and more. Most U N i x files I / O require only 5 functions: O P e n, R E A D, W R I t e, Lseek, and C L O S E. Then explain the effect of different buffers on the length of R e a d and the W R I t E function. The functions described in this chapter are often referred to as I / O without cache (U N B U Ffered I / O, which is compared with the standard I / O function described in Chapter 5). The term - without cache means that each R e A D and W R I t e are all invoked in the core. These non-cached I / O functions are not part of ANSI C, but is part of P O S i x. 1 and X P G 3. As long as it involves sharing resources between multiple processes, the concept of atomic operations is very important. We will discuss this concept through file I / O and Parameters transmitted to the o P e n function. And further discuss how to share files between multiple processes and involve the relevant data structure of the kernel. After discussing these features, the D u p, f c n t l and the I O c t L function will be described. 3.2 File Descriptor For the kernel, all open files are referenced by the file descriptor. The file descriptor is a non-negative integer. When an existing file is opened or a new file is created, the kernel returns a file descriptor to the process. When reading, write a file, using the file descriptor returned by O P e n or C R e a t, transmitting it as a parameter to R E A D or W R I t e. According to conventions, UNIX shell combines file descriptor 0 with the standard input of the process, and the file descriptor 1 is combined with the standard output, and the file descriptor 2 is combined with the standard error output. This is a unix shell and a lot of applications used by the application, and independent of the kernel. Despite this, if this practice is not followed, then many U N i x applications cannot work. In P O S i x. 1 application, the number of magic numbers 0, 1, 2 should be converted into a symbol constant S t D i n_ f i l E N O, S T D O U T _f i l E N O and S T D E R R _ f i l E N O These constants are defined in the header file . The scope of the file descriptor is 0 ~ o p e n_ m a x (see Table 2 - 7). The upper limit of the early U N i x version is 1 9 (allowing each process to open 2 0 files), and now many systems add to 6 3. SVR 4 and 4. 3 BSD The variation range of the file descriptor does not specify, it is only subject to the total amount of memory, the word length of the whole word, and the soft or hard restrictions configured by the system administrator. . 3.3 Open function calls O P e n function You can open or create a file. #include #include #include int open (const char * pathname, int OFLAG, ... / *, MODE_T MODE * /); return: If success is a file descriptor, if we mistake it - 1 We will write the third parameter as... This is ANSI C to indicate the number and type of the remaining parameters. Method can vary. For the O P e n function, the third parameter is used only when the new file is created. (We will explain this later.) This parameter is placed in the comment in the function prototype. P a T H n a m e is the name of the file to be opened or created. o f L A g parameters can be used to illustrate multiple selection items of this function. Make or operate with one or more constants or operations (these constants are defined in the header file): • o_rdonly is read-only open.

• O_WRONLY is only written. • O_RDWR read, write open. Many implementations are defined as 0, o _ W R o n ion defined as 1, o _ R D W R is defined as 2 to compatibility with early systems. You should specify only one in these three constants. The following constants are optional: • O_APpend is added to the end of the file at a time. 3. Section 11 will be described in detail. • O_CREAT Creates it if this file does not exist. When using this selection, the third parameter M O D E is simultaneously described, and the access license of the new file is described. (4. 5 Section will explain the permission bit of the file, then you can understand how Mode, and how to modify it with the UMASK value of the process.) • O_EXCL If the O_EXCL is specified in O_ CRE AT, the file already exists, Error. This can test if a file exists, if there is no existence, create this file into an atomic operation. 3. Section 11 will explain the atomic operation in more detail. • o_trunc If this file exists, and for only read or only written successfully, it is truncated to 0. • o_nOctty If the P A T H N A M e refers to a terminal device, this device does not assign the device as a control terminal for this process. 9.6 will explain the control terminal. • O_nonblock If P A T H N A M e refers to a F I f O, a block special file or a character special file, this selection is a non-blocking method for this file for this file and subsequent I / O operations. 1 2. 2 will explain this mode of work. The earlier system V version introduces the O _ N D E L AY flag, which is similar to the O _ N O N B L O C K (not blocked) select item, but has errors in the return value of the read operation. If the data cannot be read from the pipe, F I f O or device, the selection is not delayed to return R E A D to 0, which conflicts with the return value 0 indicating that the end of the file is read. S VR 4 still supports this semantic non-delayed selection, but new applications should be used instead of using non-blocking selection. • o_sync enables each W R I t e to wait until physical I / O operation is completed. 3. This selection will be used. O _ S Y N c selection is not an integral part of P O S i x. 1, but S vr 4 supports this selection. The file descriptor returned by O P e n must be the minimum unused descriptor number. This is used by many applications to open a new file on standard input, standard output, or standard error output. For example, an application can turn off the standard output first (usually the file descriptor 1), then open another file, you can understand that the file will be opened on the file descriptor 1 in advance. When the D u P 2 function is described in 3. 1 2, it can be understood that a better method is guaranteed to open a file on a given descriptor. File name and path name truncation If Name _ max is 1 4, and we try to create a new 3 6 UNIX environment with 1 5 characters in the current directory, what happens? According to the traditional, early system V versions, this method is allowed to use, but always cut the file name is from 1 4 characters, while the system of the BSD class returns an error ENAME to OLONG. This issue is not only related to creating new files. If n a m e _ m a x is 1 4, there is a file that has a file name exactly 1 4 characters, then this problem is encountered by any function (O P e n, s t a t, etc.) of its parameters (O P e n, s t a t, etc.). In P O S i x. 1, constant _ p o s i x _ n o _ T R u N c determines whether the file name or path name is to be truncated, or returns an error. Chapter 1 2 will illustrate this value to be changed for each different file system.

FIPS 151-1 requires returning an error. SVR 4 pairs of traditional system V file systems (S 5) do not guarantee return errors (see Table 2 - 6), but for the BSD style file system (UFS), SVR 4 guarantee return error, 4. 3 BSD always Returns an error. If _ p O s i x _ n o _ t r is valid, then the entire path name exceeds PAT H _ M A X, or the path name in the path name exceeds N a m e _ m a x, return E N a M e to O L o N G. 3.4 CREAT functions can also create a new file with the C R e A T function. #include #include #include int Creat (const char * pathname, mode_t mode); return: If successful, you only write file descriptor, If the error is - 1 Note that this function is equivalent to: Open (Pathname, O_Wronly | O _ Creat | O_TRUNC, MODE); in the early UNIX version, the second parameter of the Open can only be 0, 1 or 2. There is no way to open a file that has not yet existed, so another system is required to call C R e a t to create a new file. Now, the O P e n function provides the selection option O _ C R E AT and O _ T R u N c, so the C R E A T function is no longer needed. In the 4. 5, we will detail the file access permissions and explain how to specify M O D E. One deficiencies of C R e a t are it to open the created file with just write. Before providing a new version of O P e n, if you want to create a temporary file, write the file, then read the file, you must call C R E A T, C L O S E, and then call O P e n. Now use the following method to call Open: Open (Pathname, O_RDWR | O _ Creat | O_RUNC, MODE); 3.5 Close functions can be used to turn off an open file with the Close function: #include int close (int filedes); return: If success is 0, if the error is - 1 Chapter 3 File I / O 3 7 Download all record locks on this file when it is closed. 1 2. 3 will discuss this. When a process is terminated, all of its open files are automatically turned off by the kernel. Many programs use this feature without explicitly closing the open files with C L O S e. Example See Program 1 - 2.3.6 Lseek Functions Each open file has a "current file bitmill" associated with it. It is a non-negative integer that measures the number of bytes calculated from the beginning of the file. (Some exceptions for "non-negative" modifiers will be described later.) Usually, read, write operations start from the current file displacement, and increase the bitmap to the byte read or written number. According to the system, when a file is opened, the displacement is set to 0 unless the O _ a pp e n d is specified. You can call L S E E K Explicitly locate an open file.

#include #include off_t lseek (int filedes, OFF_T OFFSET, INT imclud); return: If success is a new file displacement, if the error is - 1 pair of parameter OFFSET explanation The value of the parameter imince is related. • If W HE N C E is S e e k _ S e t, the displacement amount of the file is set to the OFFSET by the file. • If W H E N C E is S e e k _ C U r, the displacement amount of the file is set to its current value plus OFFSET, and OFFSET can be positive or negative. • If W H E N C E is S e e k _ e n d, set the displacement amount of the file to the file length plus OFFSET, and OFFSET can be positive or negative. If LSEEK is successfully executed, return new file bitmutation, to determine the current displacement of an open file with the following manner: OFF_T CURRPOS; currpos = lseek (fd, 0, seek_cur); this method can also be used to determine The file involved can set the displacement. If the file descriptor references a pipe or F i f O, then L S e e k returns -1 and sets E R R N o to e p i p E. Three symbol constant S e e k _ s e t, s e e k _ c ur and s e e k _ e n D is introduced by the system V. Before the system V, W H E N C E was designated as 0 (absolute displacement amount), 1 (displacement amount relative to the current position) or 2 (the relative file tail end). Many software still uses these numbers directly to encode. Character L in L S e e k represents long integer. Before introducing the O FF_T data type, the O f F s e t parameter and the return value are long integer. L S e e k is introduced by V 7, and the C language increases long. (In V 6, a similar function is provided with functions S e e k and t e l1.) Instance program 3 - 1 is used to test whether its standard input can be set. Procedure 3-1 Test Standard Enter Can Be Set Displacement 3 8 Unix Environment Advanced Programming Download If this program is called with interactive mode, you can get: $ a.out

Program 3-2 Create a void file Chapter 3 file I / O 3 9 Download Running the program Get: $ a. OUT $ ls -1 file.hole Check its size - RW-R - R - 1 Stevens 50 Jul 31 05:50 File.hole $ od -c file.hole observed actual content 0000000 Abcdefghij / 0/0/0/0/0/0000020/0/0/0/0/0/0/0/0 / 0/0/0/0/0/0/0/0000040/0/0/0/0/0/0/0/0 Abcdefg H0000060 I J0 0 0 0 0 6 2 Use the OD (1) command to observe the file The actual content. The - C flag in the command line indicates that the file content is printed in a character. It can be seen from it, 3 0 unwritten bytes in the middle of the file are read into zero. A seven-digit starting at each row is the byte displacement represented in an octave. This example calls the W R I t E function described in Section 3.8. 4. 1 2 Sections will be more explained for files with holes. 3.7 The READ function reads data from the Open file with the R e a d function. #include SSIZE_T READ (int filedes, void * buff, size_t nbytes); return: read the number of bytes, if you have arrived at the end of the file, if the error is - 1, if you succeed, return to read The number of bytes arrived. Returns 0 if the end of the file is reached. There are many situations that can make the number of bytes actually read less than the number of read bytes: • When reading a normal file, the file end is reached before reading the required byte number. For example, if there is 3 0 bytes before arriving at the end of the file, then require reading 1 0 bytes, R E A D returns 3 0, and when R E a D is called next time, it will return 0 (file tail end). • When reading from terminal devices, you usually read up to one go to a line (Chapter 11 will introduce how to change this). • When read from the network, the buffer mechanism in the network may cause the return value less than the number of bytes required. • Some recordable devices, such as tape, return up to one record at a time. The read operation starts from the current displacement amount of the file, which before the successful returns, increase the number of bytes that actually read. P O s i x. 1 Changes the prototype of this function in several aspects. Its classic definition is: int READ (INT F I l E d e s, char * b u f, unsigned n b y t e s); first, in order to match ANSI C, the second parameter is changed to VOID *. In ANSI C, type VOID * is used to represent class pointers. Second, its return value must be a symbolic integer (S I z e _ T) to return to the number of positive bytes, 0 (indicating the file end) or - 1 (error). Finally, the third parameter is in history is a no sign integer to allow a 1 6-bit implementation to be read or written to 6 5 5 3 4 bytes. In the 1990 POSIX.1 standard, the new basic system data type 4 0 UNIX Environment Advanced programming download SSIZE_T to provide a return value of the symbol, Size _ T is used for the third parameter (see Table 2 - 7 SSIZE _ MAX constant). 3.8 WRITE functions write data to the open file with the W R I t E function.

#include SSIZE_T WRITE (INT FILEDES, Const Void * Buff, Size_t Nbytes); Return: If success is written by the number of bytes, if the error is - 1 its return value is usually different from the value of the parameter Nbytes, Otherwise it means an error. A common reason for W R I TE E error is that the disk has been written, or more than a file length limit for a given process (see 7. 11 and exercises 1 0. 11). For normal files, the write operation starts from the current displacement of the file. If the file is specified when the file is opened, the file bit shift is set at the current end of the file before each write operation. After a successful written, the file displacement increases the number of bytes that actually written. 3.9 I / O Efficiency Program 3 - 3 Use only RE A D and W R I T EF to copy a file. About this procedure should pay attention to the following points: • It is read from the standard and writes to the standard output, which is assumed to be arranged by S H E L before executing this program. Indeed, all commonly used UNIX shells provide a way that opens a file on a standard input to read, create (or rewritten) a file on the standard output. • Many applications assume that the standard input is file descriptor 0, and the standard output is a file descriptor 1. In this example, two names S t D i N _ f i l e n o and S t D O U t _ f i l e N O are used in . • When considering the termination of the process, U N i x closes all open file descriptors, so this program does not turn off the input and output files. • This program works for text files and binary code files because the two files are not different from the U N i X core. Program 3-3 Copy standard input to standard output Chapter 3 file I / O 4 1 Download We didn't answer one question how to choose B u f F s i z E value. Before answering this question, let's run this program with a variety of different B u f F s i z. Table 3 - 1 shows the results obtained by reading 1 468 802 byte file with 1 8 different cache lengths.

Table 3-1 Time results for reading operation with different cache lengths BUFFSIZE user CPU system CPU clock time cycle number (seconds) (second) 1 2 3. 8 3 9 7. 9 4 2 3. 4 1 468 8022 1 2. 3 2 0 2 734 4014 6. 1 1 0 0. 6 1 0 7. 2 367 2018 3. 0 5 0. 7 5 4. 0 183 6011 6 1. 5 2 5 3 2 7.8 1 3. 7 45 9016 4 0. 3 6. 6 7. 0 22 9511 2 8 0. 2 3. 3. 6 11 4762 5 6 0 1 1. 8 1. 9 5 7.01. 1 2 8691 024 0. 0. 6 0. 6 1 4352 048 0. 0 0. 4 0. 4 7 1 84 096 0 0. 4 98 192 0. 0. 3 0. 3 1 8 016 384 0. 0 0. 3 0. 3 9 032 768 0. 0 0. 3 0. 3 4 565 536 0 . 0 0. 3 0. 3 2 3131 072 0. 0 0. 3 0. 3 1 2 Program 3 - 3 Read the file, the standard output is reordered to / dev / NULL. The file system used in this test is a Berkeley Fast File System, with a block length of 8 1 92 bytes. (The block length is represented by S T _ B L K S I z E, in 4. 1 2: 8 1 9 2). The minimum value of the system C P U time begins to appear at B u f f s i z e to 8 1 92, continue to increase the cache length and there is no effect on this time. We will return to this example later. 3. 1 3 Section will use this to explain the effect of synchronous writing, 5. 3.10 File Sharing U N i x Supports sharing open files between different processes. This sharing is required between the introducing the D u P function. To this end, the kernel is used for the data structure for all I / O. The kernel uses three data structures, and the relationship between them determines a process that may generate another process in file sharing. (1) Each process has a record item in the process table, and one opens the file descriptor in each record, it can treat it as a vector, each descriptor takes an item. Associated with each file descriptor is: (a) File Descriptor Sign. (b) pointing to a pointer to a file entry. (2) The kernel maintains a file table for all open files. Each file table item contains: (a) file status flag (read, write, addiction, synchronization, non-blocking, etc.). (b) Current file displacement. 4 2 U N i X Environment Advanced Programming Download (c) Pointers to the Venus entry of this file. (3) Each open file (or device) has a V node structure. The V node contains a file type and a pointer information for functions for various operations for this file. For most files, the V node also contains the I node (index node) of the file. This information is read from the disk when the file is opened, so all information about the file is fast and available. For example, the i node contains the owner of the file, the device where the file is located, which points to the pointer of the actual data block used on the disk (4. 1 4, detailing the UNIX file system, will More introduction to I nodes.) We ignore some of the details that do not affect our discussion. For example, open a file descriptor table is usually in the user area without in the process table. In S V R 4, this data structure is a link table structure. The file table can be implemented in a variety of ways - not necessarily the file form item array.

In 4.3 b S D, the V node contains the actual I node (see Figure 3 - 1). S V R 4 stores the V node in the i node for most file system types. These implementations do not affect our discussion of file sharing. Figure 3 - 1 shows the relationship between the three tables of the process. This process has two different open files - a file opens to standard input (file descriptor 0), and the other open is the standard output (file descriptor is 1). Figure 3-1 Opening the kernel data structure of the file From the early version of U N i X, the basic relationship between these three tables has been maintained so far. This arrangement is very important for sharing files between different processes. When you are in the next chapter and other file sharing methods will return to this picture. The V node structure has recently added. When supporting multiple file system types on a given system, this work is required, which is independently completed by Peter Weinbe RG ER (Bell Lab) and Bill Joy (S Un Company) of. S u n call this file system as a virtual file system (Virtual Files Y S t e m), called the I node portion of the file system type as a V node [Kleiman 1986]. When various manufacturers have added support for the network file system (N f S) of S U N, they have widely used V node structures. In S V R 4, the V node changes the I node structure that is independent of the file system type in S V R 3. If the two independent processes each open the same file, there is a arrangement shown in Figure 3 - 2. We assume the first one to enter the third chapter file I / O 4 3 download FD logo file table V node table V node information I node information Current file length V node information I node information Current file length file status flag Current file bit shift V node Pointer file status flag The current file bitmode V node pointer processes The file is turned on on the file descriptor 3, while the other process turns this file on the file descriptor 4. Open each process of this file get a file entry, but only one V node entry for a given file. One reason for each process has its own file entry is that this arrangement makes each process have its own current displacement of the file. Figure 3-2 After the two independent processes have opened the same file, they will now be further illustrated for the operations described above. • After completing each W R I TE, the current file bitmills in the file entry increases the number of bytes written. If this makes the current file displacement exceeds the current file length, the current file length in the i node entry is set to the current file bit shift (that is, the file is extended). • If a file is opened with an O _ a P P e n d, the corresponding flag is also set to the file status flag of the file entry. Each time you write a write action for this file with the add-on flag, the current file bitmill in the file entry is first set to the length of the file in the i-node entry. This makes each write data to the current tail of the file. • The LSeek function only modifies the current file bitmill in the file entry, and does not perform any I / O operations. • If a file is positioned to L S e e k, the current file bitmill in the file entry is set to the current file length in the I node entry. There may be multiple file descriptors to point to the same file entry. When you discuss the D u p function in the 3. 1 2 section, we can see this. The same situation also occurred after F o R k, at which time the parent, the child process shares the same file entry for each open file descriptor. Note that the file descriptor flag and file status flag are different from the scope of action, and the former is only used for a descriptor of a process, while the latter applies to all descriptors in any process to the given file entry. At 3. 1 3: When the F c n t l function, we will learn how to access and modify the file descriptor flag and file status flag. Everything above can work correctly for multiple processes.

Each process has its own file entry, its 4 4 Unix Environment Advanced Programming Download Procedure Item File File Status Flag Current File Bit Show V Node Pointer File Status Sign Current File Bit Shift V Node Pointer V Node V Node Information I Node Information Current File Length FD Flag Process Item FD flag has its own current file bitmid. However, when multiple processes are written as a file, it may generate unexpected results. To illustrate how to avoid this, you need to understand the concept of atomic operations. 3. 11 Atom operation 3. 11.1 Add to a file to consider a process, it is to add data to a file end. Early UNIX version does not support Open's O _ Append selection, so the program is written into the following form: IF (Lseek (FD, 0L, 2) <0) / * position to eof * / err_sys ("Lseek Error") ; if (Write (FD, BUFF, 100)! = 100) / * and write * / err_sys ("Write Error"); for a single process, this program can work normally, but if there are multiple processes, There will be a problem. (If this program is executed simultaneously by multiple processes, this will be added to a journal file, which is assumed that there are two independent processes A and B, all of which add operations for the same file. Each process has been opened, but the O _ a pp e n d is not used. The relationship between each data structure is as shown in Figure 3-2. Every process has its own file entry, but shares a V node entry. Assume that the process A calls L S E E K, which sets the current displacement amount of the file of the process A to 1 5 0 0 bytes (at the end of the current file). The kernel switching process then runs the process B. Process B performs L S E E K, which is also set to 1 5 0 byte of the current displacement amount of the file (at the end of the current file). Then B call W R i T E, which increases the current file bitmill of this file to 1 6 0 0. Because the length of the file has increased, the kernel is updated to 1 6 0 0 in the current file length in the V node. Then, the kernel performs process switches to restore the process A to run. When a call W R i TE E, the data is written to the file from its current file bitmodes (1 5 0 0). This also transforms the process B just written to the data in the file. The problem here is in the logical operation "positioning file to the end of the file, then writes" using two separate function calls. The method of solving the problem is to make these two operations into one atomic operation for other processes. Any operation requiring more than 1 function call cannot be an atomic operation, because between two function calls, the kernel may temporarily suspend the process (as we assume before we have assumed). U N i x provides a method to make this operation a atomic operation, which is to set the O _ a pp e n d when the file is opened. As mentioned in the previous section, this will set the current displacement amount of the process to the end of the file before writing this file, so it no longer needs to call LSeek before each write. . 3. 11.2 Creating a file When describing the O _ C R e AT and O _ E x Cl of the o P e n function, we have seen another example of the atomic operation. When these two selection items are specified, the file has existed, O P e n will fail. We have mentioned whether the file is existed and the file is created. The two operations are performed as an atomic operation.

If there is no such an atomic operation, then the following block is written: IF ((fd = open (panave, o_wronly) <0) if (errno == Enoent) {IF ((fd = Creat (Pathname, Mode)) <0) Err_sys ("Creat Error");} elseerr_sys ("Open Error"); Chapter 3 File I / O 4 5 Download If another process creates this file, then there will happen problem. If there is between the two function calls, another process creates this file, and it is written to the file into some data, then the data just written will be wiped when the C R E A t in this program is executed. Bring both in one atomic operation, this problem will not be generated. In general, atomic operations refers to an operation consisting of multiple steps. If the operating atom is executed, or it is performed, or if it is not executed, it is impossible to implement a subset of all steps. At 4. 1 5: Atomic operations will also be discussed when the L i n k functions and the locks are included in 1 2. 3. 3.12 DUP and DUP 2 Functions The following two functions can be used to copy an existing file descriptor: #include int DUP (int filedes); int filedes, int filedes 2; two functions return : If success is a new file descriptor, if the error is the new file descriptor returned by the DUP, it must be the minimum value in the currently available file descriptor. Use D u p 2 to specify the value of the new descriptor with the f i l e d e s 2 parameter. If F i l e d e s 2 has been opened, it will be closed first. If f i l e d e s is equal to F I l E d E S 2, D u P 2 returns F I L E D E S 2 without closing it. The new file descriptors returned by these functions share the same file entry with the parameter f i l e d e s. Figure 3 - 3 shows this situation. Figure 3-3 DUP (1) After the kernel data structure In this figure, we assume that the process executes: newfd = dup (1); When this function starts execution, it is assumed that the next available descriptor is 3 (this is very It is possible because 0, 1 and 2 are opened by the shell). Because two descriptors point to the same file entry, they share the same file status flag (read, write, add, etc.) and the same current file bitmid. Each file descriptor has its own set of file descriptor flags. As we will explain in the next section, the implementation of the new descriptor is closed (C L O S E - O N - E X E C) File Descriptor Sign is always cleared by the D u P function. Another way to replicate a descriptor is to use the F C n t L function, the next section will explain the function. In fact, call: DUP (Filedes); equivalent: 4 6 Unix Environment Advanced programming download process entry file table file status flag Current file bit shift V Node pointer V node table V Node information I node information Current file length fd flag FCNTL (FileDes, F_DuPFD, 0); call: DUP2 (FileDes, FileDes2); Isometric: Close (Filedes 2); Fcntl (FileDes, F_DuPFD, FileDes2); In the last case, DUP 2 is not complete Also in Close plus FCNTL.

The difference between them is: (1) DUP2 is an atomic operation, and C L O S E and F C N T L include two function calls. It is possible to insert a signal capture function between C L O S E and F C N T L, which may modify the file descriptor. (Chapter 1 0 will explain the signal.) (2) There are some different E R R N o between D u p 2 and f c n t1. D u p 2 system call originated from V7 and then propagated to all B S D versions. The F C N T L method for replication file descriptor is first used by the system I i i, and the system V continues to be employed. S V R 3. 2 The D u P 2 function is selected, 4. 2 B S D selects the F C N t L function and the F _ D u P F function. P O S i x. 1 requires that the F _ D u p f d function of D u p 2 and f C N t L has both. 3.13 FCNTL Function F C N T L function can change the nature of the file already opened. #include #include #include int FCNTL (int filedes, int cmd, ... / * int A rg * /); return: If successful, dependent In CMD (see below), if the error is - 1 in various instances of this section, the third parameter is always an integer, corresponds to the comment portion in the prototype shown above. But 1 2. 3 Section Description Record Lock, the third parameter is a pointer to a structure. FF functions in F c n t l: • Copy an existing descriptor (C M D = F _ D u P f D). • Get / set file descriptor mark (C m D = f _ g e t f D or F _ S e t f d). • Get / set file status flag (C m D = f_ g e t f L or F _ S e t f L). • Get / set asynchronous I / O is right (C m D = f _ g e to w n or f _ s e to w n). • Get / set record lock (C m D = f _ g e t l k, f _ s e t l k, or f _ s e t l k w). Let's first describe the top seven of these ten command values ​​(three of the three species, they are related to the record lock) We will involve the file descriptor sign associated with each file descriptor in the process entry. And the file status flag in each file entry is shown in Figure 3 - 1. • f_dupfd replicates file descriptor F i l e d e s, the new file descriptor returns as a function value. It is the minimum value of each value that has not been opened in each descriptor (taken as an integer value) in each descriptor. The new descriptor shares the same file entry with FileDes (see Figure 3 - 3). However, the new descriptor has its own set of file descriptor signs, and its FD _ CloExec file descriptor flag is cleared (this means that the descriptor remains open during EXEC, we will discuss this in Chapter 8 ). Chapter 3 File I / O 4 7 Download • F_GETFD The file descriptor flag corresponding to FileDes returns as a function value. Currently defined a file descriptor flag f D _ C L o e x e C. • f_setfd Sets the file descriptor flag for Filedes. The new flag value is set according to the third parameter (taken as an integer value). It should be understood that many existing procedures related to file descriptor flags do not use constant F D_ C L O E X E C, but to set this flag to 0 (the system default, it is not closed when e x e c) or 1 (turned off at E X E C). • F_GETFL The file status flag corresponding to FileDes is returned as a function value.

When describing the o p e n function, the file status flag has been described. They are listed in Table 3 - 2. Table 3-2 For FCNTL file status flag file status flag Description o _ rdonly read-only open o _ WRONLY only write O _ RDWR Read / write open o _ appended write to file tail O _ Nonblock Non-blocking method O _ SYNC Waiting to complete o _ async asynchronous I / O (4. 3 BSD) Unfortunately, three access mode flags (O _ RDON LY, O _ Wron LY, and O _ RDWR) does not 1 person. (As mentioned above, the value of these three signs is 0, 1 and 2, due to historical reasons. These three values ​​mutually exclusive - one file can only have one of these three values.) So the first must use shielded word o _ Accmode acquires the access mode and then compares the results with these three values. • f_setfl Sets the file status flag to the value of the third parameter (taken as an integer value). Several markers that can be changed are: O _ a p p e n d, o _ n o n c l o c k, o _ s y n c and o _ a s y n C. • F_Getown Takes the process I d or process group I D of the current receiving S i g I O and S I g U R g signal. 1 2. 6. 2 will discuss these two 4. 3 b S D asynchronous I / O signal. • F_SETOWN Sets Process I D or Process Group I D for receiving S i g i o and s i g u r g signals. Positive A rg specifies a process I d, a negative A RG represents a process group I D equal to A rg absolute value. The return value of F c n t L is related to the command. If an error, all commands returns - 1, if success, returns some other value. The following three commands have a specific return value: f_dupfd, f_getfd, f_getfl, and f _ g e to w N. The first returns a new file descriptor, the second returns the corresponding flag, the last one returns a positive process I D or negative process group i D. Example Program 3 - 4 Take the command line parameters of a file descriptor and print its file flag for this descriptor. Program 3-4 Print file flag 4 8 U N i x Environment Advanced programming download Note, we use functional test macros _ P O S i x _ S O U R C E, and the condition is compiled with the file access flags defined in P O S i x. 1. Several conditions when calling the program from KORN S Hell: $ a.out 0 Temp.foo $ cat temp.fooWrite Only $ a.out 2 2> > Temp.fooWrite Only, Append $ A.out 5 5 5 <> Temp.fooreAd Writek ORN S Hell clause 5 <> Temp. foo Indicates the file temp. foo on the file descriptor 5 for reading, write. Examples must be cautious when modifying the file descriptor flag or file status flag, first get the current flag value, then follow the wish to modify it, and finalize the new flag value. Can't just perform F _ S e t f d or f_, which closes the previously set flag. Program 3 - 5 is a function that sets one or more file status flags for a file descriptor.

Program 3-5 Opens one or more file status flags on a file descriptor Chapter 3 File I / O 4 9 Download If a statement in the middle is changed to: VAL & = ~flags; / * Turn flags off * / It constitutes another function, we call it CLR _ FL and will be used in some examples later. This statement makes the current file status flag value V A L and F L A g s's back code logic and operation. If you are at the beginning of the program 3 - 3, add the following line to call S e t _ f L, turn on the synchronous write flag. Set_fl (stdout_fileno, o_sync); this causes each W R I t e to wait until the data is written to the disk back. In U N i x, typically W R i TE is only discharged into queues, and the actual I / O operation may be performed at some time later. The database system is likely to use O _ S Y N C, so that when the system crashes, it will know that the data is indeed written on the disk. When the program is running, the setting O _ S Y N c flag will increase clock time. To test this, run the program 3 - 3, which will be copied from one file on the disk to another file. Then, set the O _ S Y N C flag in this program to complete the same work described above, compare the results of the two, see Table 3 - 3. Table 3-3 Operation User CPU (Seconds) System CPU (Second) Clock Time (Second) Clock Time (Second) Clock Time (Second) Clock Time (2) is taken from Table 3-1 BUFFSIZE = 8192. 0. 3 0 . 3 disk files WRITE 0. 0 1. 0 2. 3o _ SYNC set the disk file write 0. 0 1. 4 1 3. 4 Table 3 - 3 3 rows in buffsize 8 1 9 2 The measurement was measured. The result of the results in Table 3 - 1 is the case where the disk file is read, and then written to / D E V / N U L, so there is no disk output. The second line in Table 3 - 3 corresponds to the read one disk file, and then writes to another disk file. That's why there is a difference in the first and 2 lines in Table 3 - 3. When writing disk files, the system time is increased because the kernel needs to copy data from the process and discharge the data into the queue by the disk drive to disk. When writing to disk files, clock time has also increased. When synchronous is written, the system time is slightly increased, and the clock time is increased by 6 times. From this example, we see the necessity of F C N T L. Our program operates on a descriptor (standard output), but does not know the file name of the corresponding file opened by S H E L L. Because this is S H E L L, it cannot be set by our request when it is open, so it cannot be set. f C N T L allows it to modify its nature as a descriptor that opens the file. When describing the non-blocking pipe (1 4. 2), we will also understand that since the identification of the P i P e is just its descriptor, the function of F C N T L is also required. 3.14 IOCTL Function IOCTL Function is an I / O operation of a glove box. I / O operations that cannot be represented by other functions in this chapter can usually be represented by I O C TI. Terminal I / O is the maximum use of IOCTL (Chapter 11 will introduce P O S i x. 1 has been used instead of the terminal I / O operation in I O C T L).

#include / * svr4 * / # include / * 4.3 bsd * / int ioctl (int filedes, int re ath,.....); Return: If the wrong is- 1. If success, the other value 5 0 UNIX Environment Advanced programming download IOCTL function is not part of POSIX. 1, but SVR 4 and 4. 3 BSD use it for many miscellaneous equipment operations. The prototypes we have shown are S V R 4 and 4. 3 B S D, while the earlier Berkeley system describes the second parameter as unsigned long. Because the second parameter is always a # d e f i n e name in a header file, this detail has no impact. For the ANSI C prototype, it indicates the remaining parameters with the omitted number. However, there is usually only one parameter, which is often pointing to a pointer to a variable or structure. In this prototype, we represent the header file required by the I O C T L function itself. Typically, additional equipment dedicated headers are also required. For example, in addition to the basic operations described in P O S i x. 1, terminal I O C T L requires header file . At present, what is the main use of I O C T L? We will be 4.3 b S D I O C TI operation classification is shown in Table 3 - 4. Table 3-4 4.3 BSD IOCTL Operation Type constant name file IOCTL digital disk label DIO XXX 1 0 file I / Ofio XXX 7 Tape I / OMTIO XXX 4 sets Interface I / OSIO XXX 2 5 Terminal I / OTIO XXX 3 5 Tape Operation allows us to write a file end sign on the tape, rebound around the tape, cross the specified number of files or records Wait, use other functions in this chapter to represent these operations, so use IOCTL is the easiest way to operate these devices. Access and set up the terminal window in 11.1 2, 1 2. 4, when the flow system is explained, and the advanced function of the first and pseudo terminals will be used in the first and pseudo terminals. 3.15 / dev / fd Compare new systems provide directory named / D e v / f d, and its directory item is file named 0, 1, 2, etc. Open file / d e v / f d / n equivalent to copying descriptor N (assuming that the descriptor N is open). This feature is developed by Tom Duff, which first appears in the 8th edition of the Research Unix System, supports this feature of S V R 4 and 4. 3 B S D. It is not an integral part of P O S i x. 1. Call in the function: fd = open ("/ dev / fd / 0", mode); Most systems ignore the specified mode, and others require MODE to be the files involved (here is the standard input) original The subset of the MODE used when opening. Because the above open isometric: fd = dup (0); descriptors 0 and F D share the same file entry (see Figure 3 - 3). For example, if the descriptor 0 is read-only, then we only read the F d.

Even if the system is ignored, and the following calls are successful: fd = open ("/ dev / fd / 0", o_rdwr); we still do not write F D. Chapter 3 Document I / O 5 1 Download We can also call C R e a t as the path name parameter with / d e v / f D, or call OP E n, and specify O _ C R e AT. This allows the program to call C R E A T, if the path name parameter is / d E v / f D / 1, etc. can still work. Some systems provide pathname / d E V / S T D I n, / d E V / S T D O U T and / D E V / S T D e R. These equivalents / D E V / F D / 0, / D E V / F D / 1 and / D E V / F D / 2. / D e v / f d file is mainly used by S H E L1, which allows the program to use path name parameters to treat standard inputs and standard outputs in a way to other path names. For example, the C A T (1) program explains a single-particularly interpretation of the command line as an input file name, which is the standard input. For example: Filter file2 | cat file1 - file3 | LPR First CAT read File 1, then read its standard input (the output of the filter file2 command), then read file 3, if you support / dev / fd, you can delete CAT pairs - Special treatment, so we can type the following command line: filter file2 | cat file1 / dev / fd / 0 file3 | LPR in the command line - As a parameter specification, the input or standard output is used by many programs. But this will bring some questions, such as if you use - specify the first file, then it seems like starting the selection of another command line. / d e v / f d increases the consistency of file name parameters and clearer. 3.16 Summary This chapter describes the traditional UNIX I / O function. Because each read, Write enters the kernel due to calling system calls, so these functions are called unacceptable I / O functions. In the case of only R e A D and W R I t, we observed the effects of different I / O lengths to read files. This chapter describes atomic operations when the same file is added to the same file and multiple processes. The kernel is also introduced to share the data structure of the open file information. These data structures will also be involved in the later part of this book. We also introduce I O C T L and F C N t L function. Chapter 1 will use these two functions to use I O C T L for stream I / O systems, and F C N T L is used to record locks. Exercise 3. 1 When reading / writing disk files, does the function described in this chapter have a cache mechanism? Please explain the reason. 3. 2 Write the same function as the D u P 2 function in the same 3. 1 2, requires no f C n t l function and has the correct error handling. 3. 3 In assumed a process to perform the following three function calls: fd1 = open (pathname, OFLAGS); FD2 = DUP (FD1); FD3 = Open (Pathname, Oflags); draw results map (see Figure 3 - 3 ).

转载请注明原文地址:https://www.9cbs.com/read-32917.html

New Post(0)