The author of a directory below has 2000 C files to be processed, in order to quickly implement, write the following code to open:
1#include <stdio.h>
2#include <string.h>
3
4int Main (void)
5{
6 int i = 0;
7 FILE * fp = NULL;
8 char filename[10] = {0,};
9
printf ("hello!\n");
11
(i=0;i<8192;i++) {
memset (filename, 10, 0);
sprintf (filename, "t%d.c", I);
fp = fopen (filename, "A +");
printf ("Open%s Successfully:turn%d done!\n", filename, i);
17}
18
return 0;
20}
Executed very well, but with a sentence written between the 15/16 lines above, the execution failed:
..............
fp = fopen (filename, "A +");
fwrite (filename, 1, strlen (filename), FP);
-printf ("Open%s Successfully:turn%d done!\n", filename, i);
.............
The results of the implementation are as follows:
OPENT1018.C Successfully:turn 1018 done!
OPENT1019.C Successfully:turn 1019 done!
OPENT1020.C Successfully:turn 1020 done!
Segmentationfault (core dumped).
is baffled by the time, suddenly think of the course of the junior operating system on the process block mentioned the Open File record table This information, and then open the 0.96 kernel source code, went to look under, sure enough, the number of open files per process is an array, rather than an infinitely extensible list, 0.96/ The code in Linux/include/linux/sched.h is as follows:
112struct Task_struct {
113/* these is Hardcoded-don ' t touch */
Long state; /*-1 unrunnable, 0 runnable, >0 stopped */
Counter long;
a long priority;
117 long Signal;
118 struct sigaction sigaction[32];
119 long blocked; /* Bitmap of masked signals */
120/* various fields * *
121 int Exit_code;
122 int dumpable;
123 unsigned long start_code,end_code,end_data,brk,start_stack;
124 long Pid,pgrp,session,leader;
groups[ngroups int];
126/*
127 * Pointers to (original) The parent process, youngest child, Youngersibling,
* older sibling, respectively. (P->father can Replacedwith
129 * P->p_pptr->pid)
130 */
131 struct task_struct *p_opptr,*p_pptr, *p_cptr, *p_ysptr, *p_osptr;
132/*
133 * Sleep makes a singly linked list with this.
134 */
135 struct task_struct *next_wait;
136 unsigned short uid,euid,suid;
137 unsigned short gid,egid,sgid;
138 unsigned long timeout;
..................
156 struct {
157 struct inode * library;
158 unsigned long start;
159 unsigned long length;
Libraries[max_shared_libs];
161 int Numlibraries;
162 struct file * Filp[nr_open];
163 unsigned long close_on_exec;
164/* Ldt for this task 0-zero 1-cs 2-DS&SS */
165 struct desc_struct ldt[3];
166/* TSS for this task */
167 struct Tss_struct TSS;
168};
Within the 0.96 kernel 0.96/linux/include/linux/fs.h, nr_open is defined as a relatively small number:
#defineNR_OPEN 32
Although I am using the 4.2 kernel, this limitation still exists. Refer to the file uapi/linux/limits.h, which defines the number of open files, file name length and other restrictions. In modules such as PROC/FS, this header file is included.
#defineNR_OPEN 1024
#defineNGROUPS_MAX 65536/* Supplemental Group IDs is available */
#defineARG_MAX 131072/* # bytes of args + environ for exec () */
#defineLINK_MAX 127/* # Links a file may have */
#defineMAX_CANON 255/* Size of the canonical input queue */
#defineMAX_INPUT 255/* Size of the type-ahead buffer */
#defineNAME_MAX 255/* # chars in a file name */
#definePATH_MAX 4096/* # chars in a path name including NUL */
#definePIPE_BUF 4096/* # bytes in atomic write to a pipe */
#defineXATTR_NAME_MAX 255/* # chars in an extended attribute NAME * *
#defineXATTR_SIZE_MAX 65536/* SIZE of an extended attribute value (64k) */
#defineXATTR_LIST_MAX 65536/* Size of Extended attribute NameList (64k) */
#defineRTSIG_MAX 32
But then the question comes, why does it just call fopen () and there's no problem after calling Fwrite () behind it? And why didn't the T1020.C and the previous write operations have a disk? And then I thought about it. vfs/File system/bio/block device The specific process of these modules, the intuition is that there is a delay between the VFS and the file system distribution:
1. File descriptors are allocated only when they are actually written, so that they occupy a slot in the Open File table in the process description block;
2. Most modern file system data is written in the Pagecache assigned to the file system, only after being asked to refresh,
To find a space to accept the data from the Pagebuffer, and then write back the contents of the dirty Pagecache. And before my program execution failed, has not called fflush () to refresh, the data naturally can not drop disk. Later, after Fwrite (), added a sentence of Fflush (FP), sure enough, the data can be written before the disk.
Through the above simple program, you can see that if you want to have a deep understanding of the C language IO operation, depends on the kernel file system, the system IO path in-depth understanding, only so that we can through the segment error, data can not be written and so on, see behind the file system in the implementation of the essence.
Related connections:
http://blog.csdn.net/kai_ding/article/details/9914629
http://blog.csdn.net/dongpy/article/details/4552062
This article is from the "Store Chef" blog, so be sure to keep this source http://xiamachao.blog.51cto.com/10580956/1867239
Thinking caused by failure to open a file