" http://990487026.blog.51cto.com "
Linux system Development file operation Ext2 File System Understanding Stat () function access () function chmod () function utime () function truncate () function link () Hard link function symlink () Soft link function readlink () function Unlink function Rename function () directory operation ChDir ()/fchdir () GETCWD/GETWD ()/get_current_dir_name () pathconf () Opendir () Readdir () DUP () /dup2 () Exercise:
Deep parsing of the ext2 file system
Stat function Get File size
[email protected]:~/linux_c$ cat main.c #include <stdio.h> #include < stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h># include <sys/types.h>//#include <fcntl.h>int main (int argc,char **argv) { Struct stat s_buf;if (argc < 2) {printf ("Insufficient parameters \ n"); exit (1);} if (stat (ARGV[1],&S_BUF) < 0) {perror ("stat"); exit (2);} printf ("FileName:%s\n", argv[1]);p rintf ("File Size:%ld bytes \n", s_buf.st_size);} int stat (CONST&NBSP;CHAR&NBSP;*PATHNAME,&NBSP;STRUCT&NBSP;STAT&NBSP;*BUF);// int fstat (INT&NBSP;FD,&NBSP;STRUCT&NBSP;STAT&NBSP;*BUF);// int lstat ( CONST&NBSP;CHAR&NBSP;*PATHNAME,&NBSP;STRUCT&NBSP;STAT&NBSP;*BUF);// lstat do not track symbolic links//// Struct stat {//dev_t st_dev; /* id of device containing file *///ino_t st_ino;&nbsP;/* inode number *///mode_tst_mode;/* protection *///nlink_t st_ nlink; /* number of hard links *///uid_t st_uid; /* User id of owner *///gid_t st_gid; /* group id of owner *///dev_t st_rdev;/* device ID (If special file) *///off_t st_ Size;/* total size, in bytes *///blksize_t st_blksize; /* blocksize for filesystem i/o *///blkcnt_t st_blocks; /* number of 512B blocks allocated *//////* Since Linux 2.6, the kernel Supports nanosecond// precision for the following timestamp fields.// for the details before Linux 2.6, see notes. */////struct timespec st_atim; /* time of last Access *///struct timespec st_mtim; /* time of last modification *///struct timespec st_ctim; /* time of last status change */////#define st_atime st_atim.tv_sec /* backward compatibility */// #define &NBSP;ST_MTIME&NBSP;ST_MTIM.TV_SEC//#define st_ctime st_ctim.tv_sec//};//[email protected]:~/linux_c$ gcc main.c && ./a.out main.c File name: main.c file Size: 1454 bytes [email protected]:~/linux_c$
Access () file accessor function to test whether the file exists program
[email protected]:~/linux_c$ gcc main.c && ./a.out main.c ./ main.c exists [email protected]:~/linux_c$ [email protected]:~/linux_c$ [email protected]:~/linux_c$ cat main.c #include <stdio.h> #include <stdlib.h># include <errno.h> #include <unistd.h> #include <sys/stat.h> #include < sys/types.h>//#include <fcntl.h>int main (void) {if (Access ("./main.c", F_OK) < 0) {perror ("Open ./haha.txt"); exit (1);} printf ("./main.c exists \ n");} Int access (Const char *pathname, int mode);//the mode specifies the accessibility check (s) to be performed, //and is either the value F_OK, or a mask consisting of the bitwise// OR of one or more of r_ok, w_ok,and X_OK.&NBSP;F_OK&NBSP;TESTS&NBSP;FOR&NBSP;THE//&NBSP;EXISTENCE&NBSP;OF&NBSP;THE&NBSP;FILE.&NBSP;&NBSP;R_OK, w_ok, and x_ok test whether the// file exists and grants read, write, and execute permissions, respec‐tively.//return value: //On success (all requested permissions granted, //or mode is f_ok and the file exists), zero is returned.//on error (At least one bit in mode asked for a permission ,//that is denied, or mode is F_OK and the file does not exist, //or some other error occurred), -1 is returned, and errno is set appropriately. [email protected]:~/linux_c$ gcc main.c && ./a.out main.c ./main.c presence [email protected]:~/linux_c$
Sticky bit: User executes with root permission
[Email protected]:~$ ll/usr/bin/passwd-rwsr-xr-x 1 root root 53K March 17:25/usr/bin/passwd*
chmod () function
[email protected]:~/linux_c$ cat main.c #include <stdio.h> #include < stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h># include <sys/types.h>//#include <fcntl.h>int main (int argc,char **argv) { if (argc < 3) {printf ("parameter not!\n");} Need to test whether the file exists//"0222" => go 8 int mode = atoi (argv[2]); chmod (Argv[1],mode);} Need to perfect the place://1 string to 8 binary//2 determine if the file exists only should go to CHMOD[EMAIL&NBSP;PROTECTED]:~/LINUX_C$&NBSP;GCC&NBSP;MAIN.C Total dosage of && ./a.out file 111[email protected]:~/linux_c$ ll 16k-rwxrwxr-x 1 chunli chunli 8.5k 8 Month 4 09:59 a.out*--- Xr-xrwx 1 chunli chunli 0 8 Month 4 09:55 File*-rw-rw-r-- 1 chunli chunli 435 8 Month 4 09:59 main. c[email protected]:~/linux_c$ gcc main.c && ./a.out file 511 [Email protected]:~/linux_c$ ll Total Dosage 16K-rwxrwxr-x 1 chunli chunli 8.5K August 4 10:00 a.out*-rwxrwxrwx 1 chunli chunli 0 8 Month 4 09:55 file*-rw-rw-r-- 1 chunli chunli 435 8 Month 4 09:59 main.c[email protected]:~/linux_c$
Utime () Update file Time function
#include <sys/types.h>//#include <utime.h>////int utime (const char *filename, const struct UTIMB UF *times);////#include <sys/time.h>////int utimes (const char *filename, const struct timeval times[2]);
Truncate () function, truncate file
#include <unistd.h>//#include <sys/types.h>////int truncate (const char *path, off_t len GTH);//int ftruncate (int fd, off_t length);
2.7.1 Link
Create a hard link
When RM deletes a file, it simply deletes the record entry under the directory and puts the inode hard link count minus 1 when the hard link count
Minus 0 o'clock, the file is actually deleted.
#include <unistd.h>
int link (const char *oldpath, const char *newpath);
* Hard links are usually required to be in the same file system, POSIX allows the file system to boast
* Symbolic links do not have file system restrictions
* Usually does not allow the creation of hard links to the directory, some UNIX systems under which superuser can create a hard chain of directories
* Creating catalog items and increasing the hard link count should be an atomic operation
2.7.2 Symlink
int symlink (const char *oldpath, const char *newpath)
2.7.3 Readlink
Read the file name pointed to by the symbolic link, do not read the contents of the file
ssize_t readlink (const char *path, char *buf, size_t bufsiz)
2.7.4 unlink
int unlink (const char *pathname)
1. If it is a symbolic link, delete the symbolic link
2. If a hard link, the number of hard links minus 1, when reduced to 0 o'clock, the release of data blocks and Inode
3. If the file has a hard-link number of 0, but a process has opened the file and holds the file descriptor, the kernel will not be true until the process closes the file.
To delete the file
4. Use this feature to create a temporary file, open or creat create a file, immediately unlink this file
RM Bottom is also called unlink function
2.8 Rename
File Rename
#include <stdio.h>
int rename (const char *oldpath, const char *newpath);
2.9 chdir
#include <unistd.h>
int chdir (const char *path);
int fchdir (int fd);
Change the working directory of the current process
2.10 GETCWD
Gets the working directory of the current process
#include <unistd.h>
Char *getcwd (char *buf, size_t size);
ChDir (), GETCWD () Char *getcwd (char *buf, size_t size);//user-defined character array char *getwd (char *buf);//no array size check cha R *get_current_dir_name (void);//function static array or heap space
Get file path
[Email protected]:~/linux_c$ cat main.c #include <stdio.h> #include <stdlib.h> #include <errno.h># Include <unistd.h> #include <sys/stat.h> #include <sys/types.h>int main (int Argc,char **argv) {Char buf [] = {0};chdir ("/Home"), GETCWD (buf,sizeof (BUF));p rintf ("%s \ n", buf);} [Email protected]:~/linux_c$ gcc main.c &&./a.out file 511/home [email protected]:~/linux_c$
pathconf File configuration information
#include <unistd.h>
Long fpathconf (int fd, int name);
Long pathconf (char *path, int name);
[Email protected]:~/linux_c$ cat main.c #include <stdio.h> #include <stdlib.h> #include <errno.h># Include <unistd.h> #include <sys/stat.h> #include <sys/types.h>int main (int argc,char **argv) {printf ("%ld\n", fpathconf (Stdout_fileno,_pc_name_max));p rintf ("%ld\n", pathconf ("./main.c", _pc_name_max)); return 0;} [Email protected]:~/linux_c$ gcc main.c &&./a.out file 511255255[email protected]:~/linux_c$
Opendir () Readdir () directory traversal
struct direntstruct stat[email protected]:~/linux_c$ cat main.c #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <dirent.h > #include <stdio.h> #include <string.h> #define max_path 1024/* dirwalk: apply fcn to all files in dir */void dirwalk (Char *dir, void (*FCN) (char *)//Traverse directory {char name[max_path];struct dirent *dp;dir *dfd; if ((Dfd = opendir (dir)) == null) //If Open Directory failed {fprintf (stderr, "Dirwalk: can ' t open %s\n ", dir); return;} while (Dp = readdir (DFD)) != null) //Read directory contents {if (strcmp, ".") == 0 | | &NBSP;STRCMP (dp->d_name, "...") == 0) {continue; /* skip self and parent */}if (strlen (dir) + Strlen (Dp->d_name)+2 > sizeof (name))// bar with 0 "/home/chunli\0" {fprintf (stderr, "dirwalk: name %s %s too long\n ", dir, dp->d_name);} else {sprintf (name, "%s/%s", dir, dp->d_name);(*FCN) (name);}} Closedir (DFD);} /* fsize: print the size and name of file "Name" */void fsize (Char *name)//Display file size {struct stat stbuf;if (stat (NAME,&NBSP;&STBUF) == -1) {fprintf (stderr, "Fsize: can ' t access %s\n", name); return;} if ((STBUF.ST_MODE&NBSP;&&NBSP;S_IFMT) == s_ifdir)//Judging is not the directory {Dirwalk (name, fsize);// If the directory is recursive}printf ("%8ld byte %s\n", stbuf.st_size, name);} Int main (INT&NBSP;ARGC,&NBSP;CHAR&NBSP;**ARGV) {if (argc == 1) /* default: Current directory */{fsize (".");} else{while (--argc > 0)//To do so, you can all the parameters behind the program to traverse {fsize (* (++ARGV));}} return 0;}[email protected]:~/linux_c$ gcc main.c && ./a.out /linux_c/ 0 bytes .. /linux_c//file 1504 bytes .. /linux_c//main.c 12288 bytes .. /linux_c//.main.c.swp 9232 bytes .. /linux_c//a.out 4096 bytes .. /linux_c/[email protected]:~/linux_c$
Dup/dup2
#include <unistd.h>
int dup (int oldfd);
int dup2 (int oldfd, int newfd);
Both DUP and dup2 can be used to copy an existing file descriptor so that two file descriptors point to the same
The structure of the body. If two file descriptors point to the same file struct, file Status flag and read and write locations only hold one
is in the file structure, and the reference count for the file struct is 2. If two times open the same file gets two files
Descriptor, each descriptor corresponds to a different file structure body, which can have different file Status flags and read-write
Position. Be careful to distinguish between the two cases.
[email protected]:~/linux_c$ cat main.c #include <unistd.h> #include < sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h>int main (void) {int fd, save_fd;char msg[] = "This is a test\n "; Fd = open (" Somefile ", o_rdwr| o_creat, s_irusr| S_IWUSR), if (fd<0) {perror ("open"); exit (1);} printf ("fd = %d\n", FD); Save_fd = dup (Stdout_fileno);p rintf ("save_fd = %d\n", Save _FD);d up2 (Fd, stdout_fileno);//This step will close STDOUT_FILENO,&NBSP;FD is the standard output of printf ("3rd Time fd = %d\n", FD), Close (FD), Write (Stdout_fileno, msg, strlen (msg));d up2 (Save_fd, stdout_fileno); Write (Stdout_ Fileno, msg, strlen (msg)); close (save_fd); return 0;} [email protected]:~/linux_c$ gcc main.c && ./a.out fd = 3save_fd = 4this is a test[email protected]:~/linux_c$ cat somefile 3rd time fd = 3this is a test[email protected]:~/linux_c$
2.14 Practice
1. Implement Ls-l function, can parse file permission bit.
2. Implement Ls-l function, can parse out the file owner and file all groups. (Partial difficulty)
3. Implement the RM Delete command, such as
RM file
RM Directory
* Note, do not test in the directory where you have the code, prevent the deletion of your useful files, friendly hints (Rmdir/unlink and recursive traversal
Recorded
4. Read 1000 random numbers from the file, sort them, and then write to another file. (Consider using redirect dup/dup2)
This article from "Soul Bucket Luo" blog, declined reprint!
Linux system development 3 file system development files/directories