Reprint Please specify: http://blog.csdn.net/suool/article/details/38141047
Problem Introduction
The difference between a file stream and a file descriptor
In the previous section, the implementation of ANSI C library functions in the user-state, the corresponding resources of the flow in the user space, but ultimately, the implementation of the kernel through the implementation of the file read and write control. Therefore, the fopen function must invoke the system call to the OS. This call is open, close, read, write, and so on under Linux. These all follow the POSIX standard.
So, how is the POSIX standard implemented in Linux systems to manage file operations and directories?
Problem Resolution
The Linux system defines the file structure as follows: Fs.h header file
To view the full file, please visit: http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/fs.h
struct file {906/*907 * Fu_list becomes invalid after file_free are called and queued via908 * f U_rcuhead for RCU freeing909 */910 Union {911 struct List_head fu_list;912 struct Rcu_head fu_rcuhead;913} f_u;914 struct path f_path;915 #define F_den Try f_path.dentry916 #define F_VFSMNT f_path.mnt917 const struct File_operations *f_op;918 spinlock_t F_lock; /* F_ep_links, F_flags, no IRQ */919 atomic_long_t f_count;920 unsigned int f_flags;9 fmode_t f_mode;922 loff_t f_pos;923 struct fown_struct f_ owner;924 const struct cred *f_cred;925 struct file_ra_state f_ra;926 927 u64 f_version;928 #ifdef config_security929 void *f_security;930 #endif931 /* Needed for TTY driver, and maybe others */932 void *private_data;933 934 #ifdef config_e POLL935/* Used by FS/EVENTPOLL.C to link all the hooks to this file */936 struct List_head f_ep_li nks;937 #endif/* #ifdef config_epoll */938 struct address_space *f_mapping;939 #ifdef config_debug_writecount9 unsigned long f_mnt_write_state;941 #endif942};
file Descriptor & File Structure
For the user space, any open file will be assigned a non-negative number to represent the open file, the value is a file descriptor, so any process at run time by default open three stream objects have their own file descriptor, corresponding to 0,1,2.
The file descriptor for the standard file is defined as follows:
is the kernel data structure of the process open file:
converting a file stream to a file descriptor
Linux provides the user layer with the function Fileno () to read its file descriptor from the file stream, which is to get the _fileno member of the struct file, while the Fdopen () function implements a stream that touches a file descriptor.
The function declaration is as follows:
file I/O management under POSIX standards
First look at the definition of the OS source code for the file operation:
Open the file , using the system's open function.
#include <fcntl.h>int open (const char *path, int oflag, ...);
For a detailed description of this function, see: pubs.opengroup.org/onlinepubs/009695399/functions/open.html
The first parameter of the function is the path of the file to be opened, and the second parameter is the way the file is opened, as defined in each way:
close the file using the Close function
#include <unistd.h>int close (int fildes);
For details, see: http://pubs.opengroup.org/onlinepubs/009695399/functions/close.html
Create a file
In addition to the argument o_create in the Open function, you can explicitly use the CREATE function,
#include <fcntl.h>int creat (const char *path, mode_t mode);
The first parameter is the path to the file that was created. The second parameter is the file permission that mode and Umask together determine. Successful return of the created file identifier, error returned-1.
The following is an example program.
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main (int argc, Char *argv[]) {int fd_open,fd_open_create,fd_create;if ((Fd_open=open ("/bin/ls", o_rdonly) ==-1) //Open a file Existed{perror ("open"); exit (exit_failure);} printf ("The file ' s descriptor is:%d\n", fd_open);//Open a file, if not existed then create one which named Temp1if ((fd_ope N_create=open ("./tmp1", o_creat| o_excl,0644)) (==-1) {perror ("open");//exit (exit_failure);} printf ("The Tmp1 file descriptor is:%d\n", fd_open_create); if ((Fd_create=creat ("./tmp2", 0644)) ==-1) //Create Temp2{perror ("create"); exit (exit_failure);} printf ("The Tmp2 file descriptor is:%d\n", fd_create); close (Fd_open); close (fd_create); Close (Fd_open_create ); Close Filereturn 0;}
The results are as follows: (second file creation failed) ...
File Control Fcntl
#include <fcntl.h>int fcntl (int fildes, int cmd, ...);
The first parameter is the file descriptor to be modified, and the second is the corresponding action of CMD.
The commonly used commands are:
具体
The meaning of each parameter is no longer mentioned, you can search by yourself .
Read and Write file contents
Click to view detailed description
Read () function
Write () function
File location
When you read and write to the file, when you open the file there is usually a read and write location, usually pointing to the head of the file, if you open the file in an additional way, then the file you tail.
Lseek () function
Here is an example:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>char buf1[] = "1234567890\n"; Temporary information required to write char buf2[] = "abcdefghij\n"; char buf3[] = "abcdefghij\n"; int main (int argc,char *argv[]) {int fd;if (FD = CR Eat ("/tmp/test", 0644)) < 0) //Create file {perror ("creat"); exit (exit_failure);} if (Write (FD, BUF1)! =) //start writing {perror ("write") from the file; exit (exit_failure);} if (Lseek (fd, seek_set) = =-1) //from 20 bits write {perror ("Lseek"); exit (exit_failure);} if (Write (FD, BUF2, ten)! =) {perror ("write"); exit (exit_failure);} if (Lseek (fd, seek_set) = =-1) //write { perror ("Lseek") starting from 10; Exit (exit_failure);} if (Write (FD, BUF3, ten)! =) { perror ("write"); Exit (exit_failure);} return 0;}
Result
Lock unlock File
Both the flock () function and the FCNTL () can lock and unlock files. But the former can only lock the entire file, while the latter provides file locking in any location.
The following example program is fcntl to a file lock operation, and another process cannot manipulate the file during a process lock.
The code for one of these processes is as follows:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include < Time.h>struct flock* File_lock (short type, short whence) {static struct flock ret; Ret.l_type = type; Ret.l_start = 0; Ret.l_whence = whence; Ret.l_len = 0; Ret.l_pid = Getpid (); return &ret;} int main (int argc,char *argv[]) {int fd = open (argv[1], o_wronly| o_append); int i;time_t now; for (i=0; i<1000; ++i) {fcntl (fd, F_SETLKW, File_lock (F_wrlck, Seek_set)), Time (&now);p rintf ("%s\t%s f_setlkw Lock file%s for 5s\n ", CTime (&now), argv[0],argv[1]); Char buf[1024] = {0}; sprintf (buf, "Hello World%d\n", I); int len = strlen (BUF); if (Write (FD, buf, Len)) printf ("%s\t%s Write File sccess\n", CTime (&now), argv[0],argv[1]); sleep (5); Fcntl (FD, F_SETLKW, File_lock (F_unlck, Seek_set)); Sleep (1); } close (FD);}
Another code similar to this, the difference is as follows:
Running a process at a terminal is as follows:
Directory Flow Basic Operations
The use of the functions mentioned in this section is similar to the above function usage, please consult the source code or document usage for specific needs.
1. Open the Close directory file
function Opendor () and
Closedir () function
2. Read and write directory contents
Readdir ()//not secure in multi-threaded operation
Readdir_r ()//implement multithreading to read directory contents
3. Locating directory Locations
Telldir () is similar to the Ftell () function, which returns the current location associated with the directory.
Seekdir () similar to the file Locator function fseek () function
Rewinddir () function similar to file read/write position reset function rewind ()
4. Add and Remove directories
mkdir ()
RmDir ()
5. Current work path operation
GETCWD () Gets the current path
Get_current_dir_name () is also
To modify the current directory:
ChDir () && Fchdir ()
Case Application
Directory copy operation for recursive files
Where the flowchart of the Mian function is as follows
The difficulty of the program is recursive subdirectory, the following is a recursive subdirectory flowchart:
The source code is as follows:
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys /stat.h> #include <dirent.h> #include <linux/types.h> #include <fcntl.h> #include <errno.h> /*CP the Link_file ' s src to dst*/int cp_file (const char *SRC, const char *dst,mode_t mode) {int fd_src,fd_dst;if ( -1 = = (fd_ SRC =open (src,o_rdonly)) {perror ("open src"); exit (exit_failure);} if ( -1 = = (Fd_dst =open (dst,o_wronly| o_trunc| O_creat,mode)) {perror ("open DST"); exit (exit_failure);} int Len=0;do{char buf[1024];len=read (fd_src,buf,1024); write (Fd_dst,buf,len);} while (len>0); close (FD_SRC); close (FD_DST);} int Cp_dir (const char *src,const char *dst) {dir *dirp = null;if (null== (Dirp=opendir (SRC))) {perror ("Opendir"); Exit (exit _failure);} struct Dirent *entp = null;while (NULL! = (entp =readdir (DIRP))) {if (strcmp (Entp->d_name, "...") ==0 | | strcmp (Entp->d_name, ".") ==0)//ignore./... /{continue; }char *NAME_SRC = (char *) malloc (strlen (src) + 1 + strlen (entp->d_name) + 1); sprintf (NAME_SRC, "%s/%s\0", src,entp->d_name); char *name_dst = (char *) malloc (str Len (DST) + 1 + strlen (entp->d_name) + 1), sprintf (NAME_DST, "%s/%s\0", dst,entp->d_name), struct stat stat_src;if ( Stat (NAME_SRC, &stat_src) = =-1) {fprintf (stderr, "%s" (%d): Stat error (%s)!\n ", __file__, __line__, Strerror (errno)); Exit (exit_failure);} if (S_isreg (stat_src.st_mode))//regular file{cp_file (Name_src,name_dst,stat_src.st_mode); free (NAME_SRC); NAME_DST);} else if (S_isdir (Stat_src.st_mode)) {if (-1 ==mkdir (Name_dst,stat_src.st_mode)) {perror ("mkdir"); exit (exit_failure);} Cp_dir (NAME_SRC, NAME_DST); free (NAME_SRC); free (NAME_DST);}}} int main (int argc,char *argv[]) {if (ARGC < 3) {fprintf (stderr, "usage%s src_dir dst_src\n", argv[0]); Exit (exit_failure );} struct Stat stat_src;if (stat (argv[1], &stat_src)! = 0) {fprintf (stderr, "%s" (%d): Stat error (%s)!\n ", __file__, __line__, Strerror (errno)); Exit (Exit_failure); }umask (0000); if (s_isREG (stat_src.st_mode))//regular file {struct stat stat_dst;if (stat (argv[2], &stat_dst) = =-1) {if (errno! = ENOENT) If errno not cause by File/dir not exist{fprintf (stderr, "%s (%d): Stat error (%s)!\n", __file__, __line__, Strerror (errno ); exit (exit_failure);} else//if Dst_flie not exist. {cp_file (Argv[1],argv[2],stat_src.st_mode);}} ELSE//DST file exist. {if (S_isdir (Stat_dst.st_mode))//cp a file to a exist Dir{char *ptr= (char *) malloc (strlen (argv[2]) +1+strlen (argv[1]) +1) ; sprintf (PTR, "%s/%s\0", argv[2],argv[1]); Cp_file (Argv[1],ptr,stat_src.st_mode);} ELSE//CP file to a exist file{printf ("file%s exist, does you want overwrite it[y/n]:", argv[2]); Char Ch;while (!SCANF ("%c", &A Mp;ch)) {GetChar ();} if (ch = = ' Y ' | | ch = = ' Y ') {unlink (argv[2]); Cp_file (Argv[1],argv[2],stat_src.st_mode);} Elsereturn 1;}} }else if (S_isdir (Stat_src.st_mode))//dir {struct stat stat_dst;if (stat (argv[2], &stat_dst) = =-1) {if (errno! = EN oent)//if errno not cause by File/dir not exist{fprintf (stderr, "%s (%d): sTat error (%s)!\n ", __file__, __line__, Strerror (errno)); exit (exit_failure);} Else//file/dir not exist{errno=0;if ( -1 = = mkdir (Argv[2],stat_src.st_mode)) {perror ("mkdir"); exit (exit_failure);} Cp_dir (argv[1],argv[2]);}} else if (S_isreg (stat_dst.st_mode))//can ' t copy a dir to a file{fprintf (stderr, "can ' t copy a dir to a file\n"); Exit (EXIT_FA Ilure);} Else//copy a dir to a exsit dir, {char *ptr= (char *) malloc (strlen (argv[1]) +1+strlen (argv[2]) +1); sprintf (PTR, "%s/%s\0", ARGV[2],ARGV[1]); if ( -1 = = mkdir (Ptr,stat_src.st_mode)) {perror ("mkdir"); exit (exit_failure);} Cp_dir (argv[1],ptr); free (PTR);}}}
The results of the operation are as follows:
Displays a successful copy .
Next:
Normal file/link File/Directory File---Property management
Terminal and serial programming
Reprint Please specify: http://blog.csdn.net/suool/article/details/38141047