99#include "vfs.h"
1010
1111static int procfs_id = 0 ;
12+ static int proc_self_id = 0 ;
1213vfs_node_t procfs_root = NULL ;
1314spin_t procfs_oplock = SPIN_INIT ;
1415
@@ -24,6 +25,10 @@ static int dummy() {
2425 return 0 ;
2526}
2627
28+ static int udummy () {
29+ return VFS_STATUS_FAILED ;
30+ }
31+
2732const char * get_vma_permissions (vma_t * vma ) {
2833 static char perms [5 ];
2934
@@ -86,39 +91,19 @@ char *proc_gen_maps_file(pcb_t task, size_t *content_len) {
8691 return buf ;
8792}
8893
94+ extern lock_queue * pgb_queue ;
95+
8996errno_t procfs_mount (const char * src , vfs_node_t node ) {
9097 if (src != (void * )PROC_REGISTER_ID ) return VFS_STATUS_FAILED ;
9198 procfs_root = node ;
9299
93100 procfs_root -> fsid = procfs_id ;
94101
95102 vfs_node_t procfs_self = vfs_node_alloc (procfs_root , "self" );
96- procfs_self -> type = file_dir ;
103+ procfs_self -> type = file_symlink ;
97104 procfs_self -> mode = 0644 ;
98-
99- vfs_node_t self_environ = vfs_node_alloc (procfs_self , "environ" );
100- self_environ -> type = file_none ;
101- self_environ -> mode = 0700 ;
102- proc_handle_t * self_environ_handle = malloc (sizeof (proc_handle_t ));
103- self_environ -> handle = self_environ_handle ;
104- self_environ_handle -> task = NULL ;
105- sprintf (self_environ_handle -> name , "self/environ" );
106-
107- vfs_node_t self_maps = vfs_node_alloc (procfs_self , "maps" );
108- self_maps -> type = file_none ;
109- self_maps -> mode = 0700 ;
110- proc_handle_t * self_maps_handle = malloc (sizeof (proc_handle_t ));
111- self_maps -> handle = self_maps_handle ;
112- self_maps_handle -> task = NULL ;
113- sprintf (self_maps_handle -> name , "self/maps" );
114-
115- vfs_node_t self_cmdline = vfs_node_alloc (procfs_self , "cmdline" );
116- self_cmdline -> type = file_none ;
117- self_cmdline -> mode = 0700 ;
118- proc_handle_t * self_cmdline_handle = malloc (sizeof (proc_handle_t ));
119- self_cmdline -> handle = self_cmdline_handle ;
120- self_cmdline_handle -> task = NULL ;
121- sprintf (self_cmdline_handle -> name , "self/cmdline" );
105+ procfs_self -> linkto = NULL ;
106+ procfs_self -> fsid = proc_self_id ;
122107
123108 vfs_node_t cmdline = vfs_node_alloc (procfs_root , "cmdline" );
124109 cmdline -> type = file_none ;
@@ -136,6 +121,10 @@ errno_t procfs_mount(const char *src, vfs_node_t node) {
136121 filesystems_handle -> task = NULL ;
137122 sprintf (filesystems_handle -> name , "filesystems" );
138123
124+ queue_foreach (pgb_queue , node ) {
125+ procfs_on_new_task (node -> data );
126+ }
127+
139128 return VFS_STATUS_SUCCESS ;
140129}
141130
@@ -177,30 +166,12 @@ size_t procfs_read(void *file, void *addr, size_t offset, size_t size) {
177166 len = (len + 1 ) > size ? size : len + 1 ;
178167 memcpy (addr , get_kernel_cmdline (), len );
179168 return len ;
180- } else if (!strcmp (handle -> name , "self/maps" )) {
181- size_t content_len = 0 ;
182- char * content = proc_gen_maps_file (get_current_task ()-> parent_group , & content_len );
183- if (offset >= content_len ) {
184- free (content );
185- return 0 ;
186- }
187- content_len = MIN (content_len , offset + size );
188- size_t to_copy = MIN (content_len , size );
189- memcpy (addr , content + offset , to_copy );
190- free (content );
191- ((char * )addr )[to_copy ] = '\0' ;
192- return to_copy ;
193- } else if (!strcmp (handle -> name , "self/cmdline" )) {
194- ssize_t len = strlen (get_current_task ()-> parent_group -> cmdline );
195- if (len == 0 ) return 0 ;
196- len = (len + 1 ) > size ? size : len + 1 ;
197- memcpy (addr , get_current_task ()-> parent_group -> cmdline , len );
198- return len ;
199169 } else if (!strcmp (handle -> name , "proc_cmdline" )) {
200- ssize_t len = strlen (task -> cmdline );
170+ char * cmdline = task -> cmdline ? task -> cmdline : "no_cmdline" ;
171+ ssize_t len = strlen (cmdline );
201172 if (len == 0 ) return 0 ;
202173 len = (len + 1 ) > size ? size : len + 1 ;
203- memcpy (addr , task -> cmdline , len );
174+ memcpy (addr , cmdline , len );
204175 return len ;
205176 } else if (!strcmp (handle -> name , "proc_maps" )) {
206177 size_t content_len = 0 ;
@@ -234,15 +205,8 @@ errno_t procfs_stat(void *file, vfs_node_t node) {
234205 node -> size = strlen (filesystems_content );
235206 else if (!strcmp (handle -> name , "cmdline" ))
236207 node -> size = strlen (get_kernel_cmdline ());
237- else if (!strcmp (handle -> name , "self/maps" )) {
238- size_t content_len = 0 ;
239- char * content = proc_gen_maps_file (get_current_task ()-> parent_group , & content_len );
240- free (content );
241- node -> size = content_len ;
242- } else if (!strcmp (handle -> name , "proc_cmdline" ))
243- node -> size = strlen (handle -> task -> cmdline );
244- else if (!strcmp (handle -> name , "self/cmdline" ))
245- node -> size = strlen (get_current_task ()-> parent_group -> cmdline );
208+ else if (!strcmp (handle -> name , "proc_cmdline" ))
209+ node -> size = strlen (handle -> task -> cmdline ? handle -> task -> cmdline : "null" );
246210 else if (!strcmp (handle -> name , "proc_maps" )) {
247211 size_t content_len = 0 ;
248212 char * content = proc_gen_maps_file (handle -> task , & content_len );
@@ -252,6 +216,77 @@ errno_t procfs_stat(void *file, vfs_node_t node) {
252216 node -> size = strlen ("cpkernel_drm" );
253217}
254218
219+ void procfs_self_open (void * parent , const char * name , vfs_node_t node ) {
220+ logkf ("procfs: self open node: %p\n" , get_current_task ()-> parent_group -> procfs_node );
221+ procfs_self_handle_t * handle = malloc (sizeof (procfs_self_handle_t ));
222+ handle -> self = node ;
223+ node -> linkto = get_current_task ()-> parent_group -> procfs_node ;
224+ node -> handle = handle ;
225+ vfs_node_t new_self_node = vfs_node_alloc (node -> parent , "self" );
226+ new_self_node -> type = file_symlink ;
227+ new_self_node -> mode = 0644 ;
228+ new_self_node -> fsid = proc_self_id ;
229+ list_delete (node -> parent -> child , node );
230+ }
231+
232+ void procfs_self_close (void * current ) {
233+ procfs_self_handle_t * handle = current ;
234+ handle -> self -> type |= file_delete ;
235+ free (handle );
236+ }
237+
238+ size_t procfs_self_read (void * fd , void * addr , size_t offset , size_t size ) {
239+ procfs_self_handle_t * handle = fd ;
240+ return procfs_read (handle -> self -> linkto -> handle , addr , offset , size );
241+ }
242+
243+ size_t procfs_self_write (void * fd , const void * addr , size_t offset , size_t size ) {
244+ procfs_self_handle_t * handle = fd ;
245+ return procfs_write (handle -> self -> linkto -> handle , addr , offset , size );
246+ }
247+
248+ size_t procfs_self_readlink (vfs_node_t file , void * addr , size_t offset , size_t size ) {
249+ procfs_self_handle_t * handle = file -> handle ;
250+ if (offset >= strlen (handle -> self -> linkto -> name )) return 0 ;
251+ logkf ("procfs: readlink offset:%llu size:%llu" , offset , size );
252+ char * ptr = handle -> self -> linkto -> name + offset ;
253+ ssize_t len = strlen (ptr );
254+ len = MIN (len , (ssize_t )size );
255+ memcpy (addr , ptr , len );
256+ return len ;
257+ }
258+
259+ errno_t procfs_self_stat (void * file , vfs_node_t node ) {
260+ procfs_self_handle_t * handle = file ;
261+ node -> type |= file_symlink ;
262+ node -> size = strlen (handle -> self -> linkto -> name );
263+ }
264+
265+ void procfs_self_free_handle (procfs_self_handle_t * handle ) {
266+ free (handle );
267+ }
268+
269+ static struct vfs_callback procfs_self_callbacks = {
270+ .open = procfs_self_open ,
271+ .close = procfs_self_close ,
272+ .read = procfs_self_read ,
273+ .write = procfs_self_write ,
274+ .readlink = procfs_self_readlink ,
275+ .mkdir = (vfs_mk_t )dummy ,
276+ .mkfile = (vfs_mk_t )dummy ,
277+ .link = (vfs_mk_t )dummy ,
278+ .symlink = (vfs_mk_t )dummy ,
279+ .delete = (vfs_del_t )dummy ,
280+ .rename = (vfs_rename_t )dummy ,
281+ .stat = procfs_self_stat ,
282+ .ioctl = (vfs_ioctl_t )dummy ,
283+ .map = (vfs_mapfile_t )dummy ,
284+ .poll = (vfs_poll_t )dummy ,
285+ .mount = (vfs_mount_t )udummy ,
286+ .unmount = (vfs_unmount_t )dummy ,
287+ .dup = (vfs_dup_t )dummy ,
288+ };
289+
255290static struct vfs_callback procfs_callbacks = {
256291 .mount = procfs_mount ,
257292 .unmount = (vfs_unmount_t )dummy ,
@@ -274,30 +309,34 @@ static struct vfs_callback procfs_callbacks = {
274309};
275310
276311void procfs_setup () {
277- procfs_id = vfs_regist ("proc" , & procfs_callbacks , PROC_REGISTER_ID );
278- if (procfs_id == VFS_STATUS_FAILED ) { kerror ("procfs register error" ); }
312+ procfs_id = vfs_regist ("proc" , & procfs_callbacks , PROC_REGISTER_ID );
313+ proc_self_id = vfs_regist ("proc_self" , & procfs_self_callbacks , PROC_REGISTER_ID );
314+ if (procfs_id == VFS_STATUS_FAILED || proc_self_id == VFS_STATUS_FAILED ) {
315+ kerror ("procfs register error" );
316+ }
279317}
280318
281319void procfs_on_new_task (pcb_t task ) {
282320 if (procfs_root == NULL ) return ;
283- spin_lock (procfs_oplock );
284321
285322 char name [MAX_PID_NAME_LEN ];
286323 sprintf (name , "%d" , task -> pid );
287324
288- char fname [6 + MAX_PID_NAME_LEN ];
289- sprintf (fname , "/proc/%d" , task -> pid );
325+ char * root_path = vfs_get_fullpath (procfs_root );
326+ char fname [strlen (root_path ) + 1 + MAX_PID_NAME_LEN ];
327+ sprintf (fname , "%s/%d" , root_path , task -> pid );
290328 vfs_node_t pro = vfs_open (fname );
329+ free (root_path );
291330 if (pro != NULL ) {
292331 vfs_close (pro );
293- spin_unlock (procfs_oplock );
294332 return ;
295333 }
296334
297- vfs_node_t node = vfs_child_append (procfs_root , name , NULL );
298- node -> type = file_dir ;
299- node -> mode = 0644 ;
300- node -> fsid = procfs_id ;
335+ vfs_node_t node = vfs_child_append (procfs_root , name , NULL );
336+ node -> type = file_dir ;
337+ node -> mode = 0644 ;
338+ node -> fsid = procfs_id ;
339+ task -> procfs_node = node ;
301340
302341 vfs_node_t cmdline = vfs_child_append (node , "cmdline" , NULL );
303342 cmdline -> type = file_none ;
@@ -316,16 +355,16 @@ void procfs_on_new_task(pcb_t task) {
316355 mmaps -> handle = handle_m ;
317356 handle_m -> task = task ;
318357 sprintf (handle_m -> name , "proc_maps" );
319-
320- spin_unlock (procfs_oplock );
321358}
322359
323360void procfs_on_exit_task (pcb_t task ) {
324361 if (procfs_root == NULL ) return ;
325362 spin_lock (procfs_oplock );
326363
327- char name [6 + MAX_PID_NAME_LEN ];
328- sprintf (name , "/proc/%d" , task -> pid );
364+ char * root_path = vfs_get_fullpath (procfs_root );
365+ char name [strlen (root_path ) + 1 + MAX_PID_NAME_LEN ];
366+ sprintf (name , "%s/%d" , root_path , task -> pid );
367+ free (root_path );
329368
330369 vfs_node_t node = vfs_open (name );
331370 if (node && node -> parent ) {
@@ -335,33 +374,3 @@ void procfs_on_exit_task(pcb_t task) {
335374
336375 spin_unlock (procfs_oplock );
337376}
338-
339- extern lock_queue * pgb_queue ;
340-
341- void procfs_update_task_list () {
342- if (procfs_root == NULL ) return ;
343- do {
344- vfs_node_t proc_node = NULL ;
345- list_foreach (procfs_root -> child , node ) {
346- vfs_node_t pnode = node -> data ;
347- if (pnode -> handle != NULL ) {
348- proc_handle_t * handle = pnode -> handle ;
349- if (handle -> task == NULL ) continue ;
350- proc_node = pnode ;
351- break ;
352- }
353- }
354- if (proc_node == NULL ) break ;
355- proc_handle_t * handle = proc_node -> handle ;
356- if (handle -> task -> status == DEATH ) {
357- if (proc_node && proc_node -> parent ) {
358- list_delete (proc_node -> parent -> child , proc_node );
359- vfs_free (proc_node );
360- }
361- }
362- } while (true);
363- queue_foreach (pgb_queue , node ) {
364- pcb_t process = node -> data ;
365- procfs_on_new_task (process );
366- }
367- }
0 commit comments