system calls and device drivers (system calls are calls to device drivers)
To provide a consistent interface to the user, the device driver encapsulates all hardware-related features.
Open: Opening a file or device
READ: Reading data from an open ask price or device
Wirte: Writing data to a file or device
Close: Closes a file or device
IOCTL: Passing control information to device drivers
Library Functions
One problem with using the underlying system calls directly for input and output operations is that they are very inefficient
1) using system calls can affect the performance of the system. System calls are much more expensive than function calls because Linux must switch from running user code to kernel code when executing system calls. Then return the user code. One way to reduce this overhead is to minimize the number of system calls in the program and make every system call do as much work as possible, such as reading and writing large amounts of data each time instead of reading and writing one character at a time
2) hardware restricts the amount of data blocks that the underlying system calls can read and write at a time
The library function only arranges the execution of the underlying system call when the data satisfies the length of the block, which greatly reduces the overhead of the system call.
Underlying file access:
Each running program is called a process, and it has some file descriptors associated with it. Here are some small-value integers. You can access open files or devices through them. The number of file descriptors available depends on the configuration of the system.
Whenever a program starts running: It typically has 3 open file descriptors
0: Standard input
1: Standard output
2: Standard error
Open system call:
The call successfully returns a file descriptor (unique) that can be used by read and write and other system calls. If two programs open the same file at the same time, they will get two different file descriptors respectively. If they are all writing to the file. Then they will write each of them. The call failed to return one-1 and set the global variable errno to indicate the reason for the failure
#include <fcntl.h> #include <sys/types.h> # Include<sys/stat.h> int open (const char *path,int oflags); int open (const char * Path,int oflags,mode_t mode);
Path: The filename of the file. If the file path is omitted, it is in the current directory
Oflags: The action taken to specify the open file
O_rdonly Open as read-only
O_wronly open as write-only
O_rdwr open these three required and read-only options
O_append: Append data to the end of the file
O_trunc: Dad file length is set to 0, discard existing content
O_creat: If there is this option, use the second function, enable the mode parameter
O_excl: with O_ Creat is used together to ensure that the caller creates the file. Use this optional mode to prevent two programs from creating the same file at the same time, and the open call fails if the file already exists.
Initial value of access (mode)
S_irusr: Read permission. The file belongs to the primary
S_iwusr: Write permission. File owner
S_ixusr: Execute permission file owner
S_irgrp: Read permissions file group
S_iwgrp: Execute permissions file group
S_ixgrp: Execute permissions file group
S_iroth: Read permission other user
S_iw OTH: Execute permissions other users
S_ixoth: Execute permissions other users
out=open("/root/test/aaa.out",O_WRONLY|O_CREAT|O_EXCL,S_IRUSR|S_IWUSR);[root@localhost mytest]# ls /root/test/aaa.out101322:38 /root/test/aaa.out
Umask: System variable, which is a three-bit octal number consisting of three-bit octal integers
Three-bit from high to the end with this is the user, group, other user.
0 means that any appropriate permission is allowed
4 Disable the appropriate Read permission
2 Disable the corresponding Write permission
1 Disable the appropriate execution permissions
If one of the umask is set, the arguments in open are invalidated.
600out=open("/root/test/aaa.out",O_WRONLY|O_CREAT|O_EXCL,S_IRUSR|S_IWUSR);[root@localhost mytest]# ls /root/test/aaa.out 101322:57 /root/test/aaa.out
You can see that the created file is not a master readable and is a master writable permission
Write system call
#include<unistd,h>size_t write(int filds,constvoid *buf ,sizeof bnytes)
The function of the system call write is to write the first nbytes bytes of the buffer buf to the file associated with the file descriptor Fildes. It returns the actual number of bytes. A return of 0 means that no data is written, and 1 indicates that an error occurred while calling Wrrite, and the error code is stored in the global variable errno
Read system call
#include<unistd.h>size_t read(int fildes,void *buf,size_t bnytes);
Reads nbytes bytes of data from the file descriptor Fildes related files and stores it in the data area buf, returns the number of bytes actually read, returns 0 indicating that no data has been read, has reached the end of the file, and 1 indicates that the call to read has an error,
Close System call
Terminates the file descriptor Fildes associated with its corresponding file, the file descriptor is freed and can be reused, returns 0 successfully, returns 1 on Error
#include<unistd.h>int close(int fildes);
A file copy test
#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>intMain () {CharCint inch, out;inch=open ("File.In", o_rdonly);if(inch!=-1) Write (1,"File.In is opened success!\n", -); out=open ("/root/test/mytest/file.out", o_rdwr| o_creat,s_irusr| S_IWUSR)if( out!=-1) Write (1,"File.out is created success!\n", in); while(Read (inch, &c,1)==1) Write ( out, &c,1);return 0;}
[email protected] mytest]# Cat file.in file.out Total 40-rwxrwxrwx 1 root root 5370 Apr : a.out -rw-r--r-- 1 root root 308 Apr :24 COPY_SYSTEM.C-rw-r--r-- 1 root root 0 Apr : si file. inch -rw------- 1 root root , APR:54 File.out-rw-r--r-- 1 root root 388 Apr : write.cTotal 40-rwxrwxrwx 1 root root 5370 Apr :54 a.out-rw-r--r-- 1 root root 308 Apr :24 COPY_SYSTEM.C-rw-r--r-- 1 root root 0 Apr : si file. inch -rw------- 1 root root , APR:54 File.out-rw-r--r-- 1 root root 388 Apr : write.c
Lseek system Call
The Lseek system invokes a read-write pointer to the file descriptor Fildes, which means that it can be used to set up a code slice here.
The next read-write location for the file.
#include<unistd.h>#include<sys/types.h>off_t lseek(int fildes, off_t ,int whence)
Fildes: File descriptor
Offset: Specify location
Whence: Take the following values
Seek_set: Indicates that offset is an absolute position
Seek_cur: Indicates that offset is a relative position relative to the current position
Seek_end: Indicates that offset is a relative position relative to the end of the file
standard I/O library
corresponding to the underlying file descriptor is the stream, which is implemented as a pointer to the structure file
There are three file streams that are automatically opened when you start the program, Stdin,stdout,stderr. Represents standard input, standard output, standard error output, respectively. They are all defined in the Stdio.h header file.
fopen function
Mainly used for file and terminal input and output, if the device needs to be explicitly controlled, it is best to use the underlying system call.
Return a non-null file* pointer on successful call, failed to return null
Fread function:
#include<stdio.h>siez_t fread(void *ptr ,size_t size,size_t nitems,FILE *stream)
The data is read from the file stream Strean to the data buffer that PTR points to, both Fread and fwrite operate on the data record, the size parameter specifies the length of each data record, and the counter Nitems gives the number of records to be transferred. The return value is the number of records that were successfully read into the data buffer rather than the number of bytes.
fwrite function
#include<stdio.h>size_t fwrite(constvoid *ptr,size_t size,size_t nitems,FILE *stream)
Reads the data record from the specified data buffer and writes it to the output stream, where the return value is the number of records that were successfully written
Fclose
#include<stdio.h>int fclose(FILE *stream);
Closes the specified file stream stream
fseek function
#include<stdio.h>int fseek(FILE *stream,longint offset,int whence);
The parameter usage is the same as the previous Lseek, Fseek returns an integer: 0 success-1 failure and setting errno to indicate an error
#include <stdio.h> Span class= "Hljs-keyword" >int fgetc (FILE *stream ); // encountered end of file return EOF pointer int getc (FILE *stream ); int GetChar (); // reads one character from standard input int FPUTC ( int c,file *stream ) int putc (int c,file *stream ) int putchar (int c)
Note that both Putchar and GetChar use characters as int instead of char type, which allows the end of the file (EOF) to represent 1.
Char *fgets (char *s, int n,file *stream);
Char *gets (CHR *s);
Fgets encounters a newline character, has transmitted n-1 characters (the last is a null character to end the string), and reaches the tail of the file, terminating the function call. If an error occurs, return a null pointer and set errno to indicate the wrong type
Gets reads from the standard input and discards the encountered newline character, plus a null byte at the end of the received string.
file Error stream:
To indicate errors many stdio.h library functions return an out-of-range value, such as a null pointer or EOF constant. At this point the error is errno by the external variable
#include<errno.h>extern inr errno;
maintenance of files and directories:
chmod
#include <sys/stat.h>intchmod (ComstChar*path,mode_t mode); mode is the same as the mode value in open S_IRUSR: Read access. The file belongs to the main s_iwusr: Write permission. File belongs to main s_ixusr: Execute permission file belongs to main s_irgrp: Read permission file belongs to group s_iwgrp: Execute permission file belongs to group s_ixgrp: Execute permission file belong to group S_iroth: Read permission Other user s_iwoth: Execute permission other user S_ixot H: Execute permissions for other users#include <sys/types.h>#include <sys/stat.h>intmkdirConst Char*path,mode_t mode); The mode parameter in the mode and open functions is the same value and is affected by umask#include <unistd.h>intmkdir (Const Char*path); The empty directory is deleted#include <unistd.h>intChDirConst Char*path) is the same as a CDChar*GETCWD (Char*buf,size_t size), writes the current directory to BUF, returns null if it exceeds size, and returns the pointer if successful BUF
Scan Directory
opendir function;
Opens a directory and creates a directory stream, and if successful returns a pointer to the DIR structure that is used to read the catalog data item. Failure returns a null pointer.
#include<sys/types.h>#include<dirent.h>DIR *opendir(constchar *name);
Readir function
The function returns a pointer to a structure that holds information about the next directory entry in the directory stream DIRP, and returns null if an error occurs or the end of the directory is reached.
#include<sys/types.h>#include<dirent.h>struct dirent *readdir(DIR *dirp);
Telldir function
The return value records the current location in a directory stream, and you can use this value in subsequent Seekdir calls to reset the directory scan to its current location
#include<sys/types.h>#include<dirent.h>longint telldir(DIR *dirp);
Seekdir function
The role of the Seekdir function is to set the directory entry pointer for the directory stream DIRP, which is used to set the pointer position, which should be obtained by the previous Telldir call
void Seekdir (DIR *dirp,long int loc);
Close Function
Closes a directory stream and frees the resource associated with it, returns 0 on successful execution, and returns 1 on error
Here is a program that scans the directory
#include <sys/types.h>#include <dirent.h>intClosedir (DIR *dirp);#include <unistd.h>#include <stdio.h>#include <dirent.h>#include <string.h>#include <sys/stat.h>#include <stdlib.h>voidPrintdir (Char*dir,intDepth) {DIR *DP;structDirent *entry;structStat statbuf;if((Dp=opendir (dir)) ==null)//Open dir to the directory and create a directory stream to the DP{printf("Cannot open directory:%s\n", dir);return; } chdir (dir);//Enter this directory while((Entry=readdir (DP))!=null) {//If the next catalog entry in the current directory is not a holeLstat (ENTRY->D_NAME,&STATBUF);//latat Returns the information that the link points to the file if(S_isdir (Statbuf.st_mode)) {//If it's a catalogue if(strcmp(".", entry->d_name) = =0||strcmp("..", entry->d_name) = =0)Continue;//If the current directory entry and the previous catalog item are not printed printf("%*s%s/\n", Depth,"", entry->d_name);//Print the directory, first print depth a spacePrintdir (entry->d_name,depth+4);//Enter in this directory}Else printf("%*s%s\n", Depth,"", entry->d_name);//Print file name} chdir ("..");//Go back to previous level directoryClosedir (DP);//Turn off DIR-set directory flow to directory}intMain () {Printdir ("/root/test",0);return 0;}
The operation results are as follows
[[email protected] mytest]# ./a.out a2/ a2_2 a2_1printdir.cwrite.ca3/copy_system.cfile.out.write.c.swpfile.ina1/ a1_2 a1_1a.out
Linux file operations