Changeset 611 for trunk/kernel/syscalls/sys_readdir.c
- Timestamp:
- Jan 9, 2019, 3:02:51 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_readdir.c
r473 r611 1 1 /* 2 * sys_readdir.c - Read one entry from an open directory.2 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer. 3 3 * 4 * Author Alain Greiner (2016,2017 )4 * Author Alain Greiner (2016,2017,2018) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 30 30 #include <vfs.h> 31 31 #include <process.h> 32 #include <remote_dir.h> 32 33 #include <syscalls.h> 33 34 #include <shared_syscalls.h> … … 35 36 /////////////////////////////////////// 36 37 int sys_readdir( DIR * dirp, 37 struct dirent ** dentp)38 struct dirent ** buffer ) 38 39 { 39 printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__, dirp, dentp ); 40 return -1; 40 error_t error; 41 vseg_t * vseg; // for user space checking of buffer 42 xptr_t dir_xp; // extended pointer on remote_dir_t structure 43 remote_dir_t * dir_ptr; // local pointer on remote_dir_t structure 44 cxy_t dir_cxy; // remote_dir_t stucture cluster identifier 45 struct dirent * direntp; // dirent pointer in user space 46 uint32_t entries; // total number of dirent entries 47 uint32_t current; // current dirent index 48 49 thread_t * this = CURRENT_THREAD; // client thread 50 process_t * process = this->process; // client process 51 52 #if (DEBUG_SYS_READDIR || CONFIG_INSTRUMENTATION_SYSCALLS) 53 uint64_t tm_start = hal_get_cycles(); 54 #endif 55 56 #if DEBUG_SYS_READDIR 57 if( DEBUG_SYS_READDIR < tm_start ) 58 printk("\n[%s] thread[%x,%x] enter / dirp %x / cycle %d\n", 59 __FUNCTION__, process->pid, this->trdid, dirp, (uint32_t)tm_start ); 60 #endif 61 62 // check buffer in user space 63 error = vmm_get_vseg( process , (intptr_t)buffer, &vseg ); 64 65 if( error ) 66 { 67 68 #if DEBUG_SYSCALLS_ERROR 69 printk("\n[ERROR] in %s / thread[%x,%x] : user buffer %x unmapped\n", 70 __FUNCTION__ , process->pid , this->trdid, buffer ); 71 vmm_display( process , false ); 72 #endif 73 this->errno = EINVAL; 74 return -1; 75 } 76 77 // get pointers on remote_dir_t structure from dirp 78 dir_xp = remote_dir_from_ident( (intptr_t)dirp ); 79 dir_ptr = GET_PTR( dir_xp ); 80 dir_cxy = GET_CXY( dir_xp ); 81 82 if( dir_xp == XPTR_NULL ) 83 { 84 85 #if DEBUG_SYSCALLS_ERROR 86 printk("\n[ERROR] in %s / thread[%x,%x] : dirp %x not registered\n", 87 __FUNCTION__ , process->pid , this->trdid, dirp ); 88 #endif 89 this->errno = EBADF; 90 return -1; 91 } 92 93 // get "current" and "entries_nr" values from remote_dir_t structure 94 current = hal_remote_l32( XPTR( dir_cxy , &dir_ptr->current ) ); 95 entries = hal_remote_l32( XPTR( dir_cxy , &dir_ptr->entries ) ); 96 97 // check "current" index 98 if( current >= entries ) 99 { 100 this->errno = 0; 101 return -1; 102 } 103 104 // compute dirent pointer in user space 105 direntp = (struct dirent *)dirp + current; 106 107 #if (DEBUG_SYS_READDIR & 1) 108 if( DEBUG_SYS_READDIR < tm_start ) 109 printk("\n[%s] entries = %d / current = %d / direntp = %x\n", 110 __FUNCTION__, entries, current, direntp ); 111 #endif 112 113 // copy dirent pointer to user buffer 114 hal_copy_to_uspace( buffer, &direntp , sizeof(void *) ); 115 116 // update current index in "remote_dir_t" structure 117 hal_remote_atomic_add( XPTR( dir_cxy , &dir_ptr->current ) , 1 ); 118 119 hal_fence(); 120 121 #if (DEBUG_SYS_READDIR || CONFIG_INSTRUMENTATION_SYSCALLS) 122 uint64_t tm_end = hal_get_cycles(); 123 #endif 124 125 #if DEBUG_SYS_READDIR 126 if( DEBUG_SYS_READDIR < tm_end ) 127 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 128 __FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end ); 129 #endif 130 131 #if CONFIG_INSTRUMENTATION_SYSCALLS 132 hal_atomic_add( &syscalls_cumul_cost[SYS_READDIR] , tm_end - tm_start ); 133 hal_atomic_add( &syscalls_occurences[SYS_READDIR] , 1 ); 134 #endif 135 136 return 0; 137 41 138 } // end sys_readdir()
Note: See TracChangeset
for help on using the changeset viewer.