Index: trunk/kernel/kern/process.c
===================================================================
--- trunk/kernel/kern/process.c	(revision 657)
+++ trunk/kernel/kern/process.c	(revision 662)
@@ -1077,4 +1077,22 @@
 
 ///////////////////////////////////////////
+char * process_fd_type_str( uint32_t type )
+{
+    switch( type )
+    {
+        case INODE_TYPE_FILE : return "FILE";
+        case INODE_TYPE_DIR  : return "DIR";
+        case INODE_TYPE_FIFO : return "FIFO";
+        case INODE_TYPE_PIPE : return "PIPE";
+        case INODE_TYPE_SOCK : return "SOCK";
+        case INODE_TYPE_DEV  : return "DEV";
+        case INODE_TYPE_BLK  : return "BLK";
+        case INODE_TYPE_SYML : return "SYML";
+        
+        default              : return "undefined";
+    }
+}
+   
+///////////////////////////////////////////
 void process_fd_init( process_t * process )
 {
@@ -1085,5 +1103,5 @@
 
     // initialize number of open files
-    process->fd_array.current = 0;
+    process->fd_array.max = 0;
 
     // initialize array
@@ -1101,5 +1119,8 @@
     bool_t    found;
     uint32_t  id;
-    xptr_t    xp;
+    uint32_t  max;             // current value of max non-free slot index
+    xptr_t    entry_xp;        // current value of one fd_array entry 
+    xptr_t    lock_xp;         // extended pointer on lock protecting fd_array
+    xptr_t    max_xp;          // extended pointer on max field in fd_array
 
     // get target process cluster and local pointer
@@ -1107,7 +1128,7 @@
     cxy_t       process_cxy = GET_CXY( process_xp );
 
-// check target process is reference process
-assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->ref_xp ) ) ),
-"client process must be reference process\n" );
+// check target process is owner process
+assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
+"process must be owner process\n" );
 
 #if DEBUG_PROCESS_FD_REGISTER
@@ -1120,6 +1141,7 @@
 #endif
 
-    // build extended pointer on lock protecting reference fd_array
-    xptr_t lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
+    // build extended pointers on lock & max 
+    lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
+    max_xp  = XPTR( process_cxy , &process_ptr->fd_array.max );
 
     // take lock protecting reference fd_array
@@ -1128,14 +1150,24 @@
     found   = false;
 
+    // get current value of max_fdid
+    max = hal_remote_l32( max_xp );
+
     for ( id = 0; id < CONFIG_PROCESS_FILE_MAX_NR ; id++ )
     {
-        xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
-        if ( xp == XPTR_NULL )
+        // get fd_array entry
+        entry_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
+        
+        if ( entry_xp == XPTR_NULL )
         {
-            // update reference fd_array
+            // update  fd_array
             hal_remote_s64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) , file_xp );
-	        hal_remote_atomic_add( XPTR( process_cxy , &process_ptr->fd_array.current ) , 1 );
-
-            // exit
+
+            // update max when required
+            if( id > max ) hal_remote_s32( max_xp , id );
+
+            // increase file refcount
+            vfs_file_count_up( file_xp );
+
+            // exit loop
 			*fdid = id;
             found = true;
@@ -1165,4 +1197,5 @@
     pid_t       pid;           // target process PID 
     lpid_t      lpid;          // target process LPID
+    xptr_t      file_xp;       // extended pointer on file descriptor
     xptr_t      iter_xp;       // iterator for list of process copies
     xptr_t      copy_xp;       // extended pointer on process copy
@@ -1170,21 +1203,15 @@
     cxy_t       copy_cxy;      // process copy cluster identifier
 
-// check process_xp argument
-assert( (process_xp != XPTR_NULL), "process_xp argument cannot be XPTR_NULL");
-
     // get target process cluster and local pointer
     process_t * process_ptr = GET_PTR( process_xp );
     cxy_t       process_cxy = GET_CXY( process_xp );
 
+// check target process is owner process
+assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ) ) ),
+"process must be owner process\n" );
+
     // get target process pid and lpid
     pid  = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) );
     lpid = LPID_FROM_PID( pid );
-
-    // get process descriptor in owner cluster and in reference cluster
-    xptr_t  owner_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ));
-    xptr_t  ref_xp   = hal_remote_l64( XPTR( process_cxy , &process_ptr->ref_xp   ));
-
-// check target process in in owner cluster 
-assert( (process_xp == owner_xp), "target process must be in owner process\n" );
 
 #if DEBUG_PROCESS_FD_REMOVE
@@ -1196,20 +1223,23 @@
 #endif
 
+    // get extended pointer on file descriptor
+    file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[fdid] ));
+
     // build extended pointers on list_of_copies root and lock (in owner cluster)
     xptr_t copies_root_xp = XPTR( process_cxy , &LOCAL_CLUSTER->pmgr.copies_root[lpid] );
     xptr_t copies_lock_xp = XPTR( process_cxy , &LOCAL_CLUSTER->pmgr.copies_lock[lpid] );
  
-    // get reference process cluster and local pointer
-    process_t * ref_ptr = GET_PTR( ref_xp );
-    cxy_t       ref_cxy = GET_CXY( ref_xp );
-
-    // build extended pointer on lock protecting reference fd_array
-    xptr_t fd_lock_xp = XPTR( ref_cxy , &ref_ptr->fd_array.lock );
-
-    // take lock protecting reference fd_array
+    // build extended pointer on fd_array lock and max 
+    xptr_t fd_lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
+    xptr_t fd_max_xp  = XPTR( process_cxy , &process_ptr->fd_array.max );
+
+    // take lock protecting fd_array
 	remote_queuelock_acquire( fd_lock_xp );
 
     // take the lock protecting the list of copies
     remote_queuelock_acquire( copies_lock_xp );
+
+    // get max value
+    uint32_t max = hal_remote_l32( fd_max_xp );
 
     // loop on list of process copies
@@ -1223,5 +1253,11 @@
         // release the fd_array entry in process copy
         hal_remote_s64( XPTR( copy_cxy , &copy_ptr->fd_array.array[fdid] ), XPTR_NULL );
-    }
+
+        // decrease file refcount
+        vfs_file_count_down( file_xp );
+    }
+
+    // update max when required
+    if( fdid == max ) hal_remote_s32( fd_max_xp , max-1 );
 
     // release the lock protecting reference fd_array
@@ -1240,7 +1276,87 @@
 }  // end process_fd_remove()
 
-////////////////////////////////////////////////
-xptr_t process_fd_get_xptr( process_t * process,
-                            uint32_t    fdid )
+//////////////////////////////////////////////
+void process_fd_clean_all( xptr_t process_xp )
+{
+    uint32_t  id;
+    xptr_t    file_xp;         // one fd_array entry
+    xptr_t    lock_xp;         // extendad pointer on lock protecting fd_array
+    uint32_t  max;             // number of registered files
+    error_t   error;
+
+    // get process cluster, local pointer and PID
+    process_t * process_ptr = GET_PTR( process_xp );
+    cxy_t       process_cxy = GET_CXY( process_xp );
+    pid_t       pid         = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid) );
+
+// check target process is owner process
+assert( (process_xp == hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) ),
+"process must be owner process\n" );
+
+#if DEBUG_PROCESS_FD_CLEAN_ALL
+thread_t * this  = CURRENT_THREAD;
+uint32_t   cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_FD_CLEAN_ALL < cycle )
+printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, pid, cycle );
+
+process_fd_display( process_xp );
+#endif
+
+    // build extended pointer on lock protecting the fd_array
+    lock_xp = XPTR( process_cxy , &process_ptr->fd_array.lock );
+
+    // get max index for fd_array
+    max = hal_remote_l32( XPTR( process_cxy , &process_ptr->fd_array.max ));
+
+    // take lock protecting fd_array
+	remote_queuelock_acquire( lock_xp );
+
+    for ( id = 0; id <= max ; id++ )
+    {
+        // get fd_array entry
+        file_xp = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[id] ) );
+        
+        if ( file_xp != XPTR_NULL )
+        {
+            // close the file or socket
+            error = sys_close( id );
+
+            if( error )
+            printk("/n[ERROR] in %s : cannot close the file %d for process %x\n",
+            __FUNCTION__, id, pid );
+        }
+    }
+
+    // release lock protecting fd_array
+	remote_queuelock_release( lock_xp );
+
+#if DEBUG_PROCESS_FD_CLEAN_ALL
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_FD_CLEAN_ALL < cycle )
+printk("\n[%s] thread[%x,%x] exit for process %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, pid, cycle );
+#endif
+
+}  // end process_fd_clean_all()
+
+//////////////////////////////////////////////////////////////
+xptr_t process_fd_get_xptr_from_owner( xptr_t      process_xp,
+                                       uint32_t    fdid )
+{
+    cxy_t       process_cxy = GET_CXY( process_xp );
+    process_t * process_ptr = GET_PTR( process_xp );
+
+assert( (hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp )) == process_xp),
+"process_xp argument must be the owner process" );
+
+    // access owner process fd_array
+    return hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[fdid] ));
+
+}  // end process_fd_get_xptr_from_owner()
+
+///////////////////////////////////////////////////////////
+xptr_t process_fd_get_xptr_from_local( process_t * process,
+                                       uint32_t    fdid )
 {
     xptr_t  file_xp;
@@ -1252,22 +1368,28 @@
     if( file_xp == XPTR_NULL )
     {
-        // get reference process cluster and local pointer
-        xptr_t      ref_xp  = process->ref_xp;
-        cxy_t       ref_cxy = GET_CXY( ref_xp );
-        process_t * ref_ptr = GET_PTR( ref_xp );
-
-        // build extended pointer on lock protecting reference fd_array
-        lock_xp = XPTR( ref_cxy , &ref_ptr->fd_array.lock );
-
-        // take lock protecting reference fd_array
+        // get owner process cluster and local pointer
+        xptr_t      owner_xp  = process->owner_xp;
+        cxy_t       owner_cxy = GET_CXY( owner_xp );
+        process_t * owner_ptr = GET_PTR( owner_xp );
+
+        // build extended pointer on lock protecting fd_array
+        lock_xp = XPTR( owner_cxy , &owner_ptr->fd_array.lock );
+
+        // take lock protecting fd_array
 	    remote_queuelock_acquire( lock_xp );
 
         // access reference process descriptor
-        file_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->fd_array.array[fdid] ) );
-
-        // update local fd_array if found
-        if( file_xp != XPTR_NULL )  process->fd_array.array[fdid] = file_xp;
+        file_xp = hal_remote_l64( XPTR( owner_cxy , &owner_ptr->fd_array.array[fdid] ) );
+
+        if( file_xp != XPTR_NULL )  
+        {
+           // update local fd_array 
+            process->fd_array.array[fdid] = file_xp;
         
-        // release lock protecting reference fd_array
+            // increase file refcount
+            vfs_file_count_up( file_xp );
+        }
+
+        // release lock protecting fd_array
 	    remote_queuelock_release( lock_xp );
     }
@@ -1275,5 +1397,5 @@
     return file_xp;
 
-}  // end process_fd_get_xptr()
+}  // end process_fd_get_xptr_from_local()
 
 ///////////////////////////////////////////
@@ -1319,17 +1441,89 @@
 bool_t process_fd_array_full( void )
 {
-    // get extended pointer on reference process
-    xptr_t ref_xp = CURRENT_THREAD->process->ref_xp;
-
-    // get reference process cluster and local pointer
-    process_t * ref_ptr = GET_PTR( ref_xp );
-    cxy_t       ref_cxy = GET_CXY( ref_xp );
-
-    // get number of open file descriptors from reference fd_array
-    uint32_t current = hal_remote_l32( XPTR( ref_cxy , &ref_ptr->fd_array.current ) );
-
-	return ( current >= CONFIG_PROCESS_FILE_MAX_NR );
+    // get extended pointer on owner process
+    xptr_t owner_xp = CURRENT_THREAD->process->owner_xp;
+
+    // get owner process cluster and local pointer
+    process_t * owner_ptr = GET_PTR( owner_xp );
+    cxy_t       owner_cxy = GET_CXY( owner_xp );
+
+    // get number of open file descriptors from  fd_array
+    uint32_t max = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->fd_array.max ));
+
+	return ( max == CONFIG_PROCESS_FILE_MAX_NR - 1 );
 }
 
+////////////////////////////////////////////
+void process_fd_display( xptr_t process_xp )
+{
+    uint32_t      fdid;
+    xptr_t        file_xp;
+    vfs_file_t *  file_ptr;
+    cxy_t         file_cxy;
+    uint32_t      file_type;
+    xptr_t        inode_xp;
+    vfs_inode_t * inode_ptr;
+
+    char          name[CONFIG_VFS_MAX_NAME_LENGTH];
+
+    // get process cluster and local pointer
+    process_t * process_ptr = GET_PTR( process_xp );
+    cxy_t       process_cxy = GET_CXY( process_xp );
+
+    // get process PID
+    pid_t  pid = hal_remote_l32( XPTR( process_cxy , &process_ptr->pid ));
+
+    // get pointers on owner process descriptor
+    xptr_t      owner_xp  = hal_remote_l64( XPTR( process_cxy , &process_ptr->owner_xp ));
+    process_t * owner_ptr = GET_PTR( owner_xp );
+    cxy_t       owner_cxy = GET_CXY( owner_xp );
+
+    // get max fdid from owner process descriptor
+    uint32_t max = hal_remote_l32( XPTR( owner_cxy , &owner_ptr->fd_array.max ));
+
+    printk("\n***** fd_array for pid %x in cluster %x / max %d *****\n",
+    pid, process_cxy, max );
+
+    for( fdid = 0 ; fdid <= max ; fdid++ )
+    {
+        // get pointers on file descriptor
+        file_xp  = hal_remote_l64( XPTR( process_cxy , &process_ptr->fd_array.array[fdid] ));
+        file_ptr = GET_PTR( file_xp );
+        file_cxy = GET_CXY( file_xp );
+
+        if( file_xp != XPTR_NULL )
+        {
+            // get file type
+            file_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type )); 
+
+            // get file name for a true file
+            if( file_type == INODE_TYPE_FILE )
+            {
+                // get inode pointers 
+                inode_ptr = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ));
+                inode_xp  = XPTR( file_cxy , inode_ptr );
+
+                // get file name
+                vfs_inode_get_name( inode_xp , name );
+
+                // display relevant file decriptor info
+                printk(" - %d : type %s (%s)\n",
+                fdid , process_fd_type_str(file_type), name );
+            }
+            else
+            {
+                // display relevant file decriptor info
+                printk(" - %d : type %s\n",
+                fdid , process_fd_type_str(file_type) );
+            }
+        }
+        else
+        {
+            // display relevant file decriptor info
+            printk(" - %d : empty slot\n",
+            fdid );
+        }
+    }
+}   // end process_fd_display()
 
 ////////////////////////////////////////////////////////////////////////////////////
