Linux Programming Learning Notes----POSIX file and directory management

Source: Internet
Author: User
Tags flock posix sprintf strcmp

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



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.