Changeset 651 for trunk/kernel/syscalls
- Timestamp:
- Nov 14, 2019, 11:50:09 AM (5 years ago)
- Location:
- trunk/kernel/syscalls
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_exit.c
r625 r651 108 108 __FUNCTION__, pid, this->trdid ); 109 109 #endif 110 thread_delete( XPTR( local_cxy , this ) , pid , true );110 thread_delete( XPTR( local_cxy , this ) , true ); // forced 111 111 } 112 112 -
trunk/kernel/syscalls/sys_get_nb_cores.c
r639 r651 35 35 #include <syscalls.h> 36 36 37 //////////////////////////////////// 37 ///////////////////////////////////// 38 38 int sys_get_nb_cores( uint32_t cxy, 39 39 uint32_t * ncores ) … … 51 51 #if DEBUG_SYS_GET_NB_CORES 52 52 if( DEBUG_SYS_GET_NB_CORES < tm_start ) 53 printk("\n[%s] thread[%x,%x] enter / cycle %d\n",54 __FUNCTION__, process->pid, this->trdid, (uint32_t)tm_start );53 printk("\n[%s] thread[%x,%x] enter for cluster %x / cycle %d\n", 54 __FUNCTION__, process->pid, this->trdid, cxy, (uint32_t)tm_start ); 55 55 #endif 56 56 … … 88 88 #if DEBUG_SYS_GET_NB_CORES 89 89 if( DEBUG_SYS_GET_NB_CORES < tm_end ) 90 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",91 __FUNCTION__ , process->pid, this->trdid, (uint32_t)tm_end );90 printk("\n[%s] thread[%x,%x] exit / ncores %d / cycle %d\n", 91 __FUNCTION__ , process->pid, this->trdid, k_ncores, (uint32_t)tm_end ); 92 92 #endif 93 93 -
trunk/kernel/syscalls/sys_lseek.c
r457 r651 1 1 /* 2 * kern/sys_lseek.c - set the read/write offset of an opened file2 * kern/sys_lseek.c - Kernel function implementing the lseek system call. 3 3 * 4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless 5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites 4 * AUthor Alain Greiner (2016,2017,2018,2019) 5 s 6 * Copyright (c) UPMC Sorbonne Universites 6 7 * 7 * This file is part of ALMOS- kernel.8 * This file is part of ALMOS-MKH. 8 9 * 9 * ALMOS- kernelis free software; you can redistribute it and/or modify it10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 10 11 * under the terms of the GNU General Public License as published by 11 12 * the Free Software Foundation; version 2.0 of the License. 12 13 * 13 * ALMOS- kernelis distributed in the hope that it will be useful, but14 * ALMOS-MKH is distributed in the hope that it will be useful, but 14 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 17 18 * 18 19 * You should have received a copy of the GNU General Public License 19 * along with ALMOS- kernel; if not, write to the Free Software Foundation,20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 20 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 22 */ … … 31 32 #include <process.h> 32 33 33 //////////////////////////////// 34 int sys_lseek ( uint32_t file_id,35 uint32_t offset,36 uint32_t whence )34 ///////////////////////////////// 35 int sys_lseek ( uint32_t file_id, 36 uint32_t offset, 37 uint32_t whence ) 37 38 { 38 39 error_t error; … … 43 44 process_t * process = this->process; 44 45 46 #if (DEBUG_SYS_LSEEK || CONFIG_INSTRUMENTATION_SYSCALLS) 47 uint64_t tm_start = hal_get_cycles(); 48 #endif 49 50 #if DEBUG_SYS_LSEEK 51 if( DEBUG_SYS_LSEEK < tm_start ) 52 printk("\n[%s] thread[%x,%x] enter / file_id %d / offset %d / cycle %d\n", 53 __FUNCTION__, process->pid, this->trdid, file_id, offset, (uint32_t)tm_start ); 54 #endif 55 45 56 // check file_id argument 46 57 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 47 58 { 48 printk("\n[ERROR] in %s : illegal file descriptor index = %d\n", 49 __FUNCTION__ , file_id ); 59 60 #if DEBUG_SYSCALLS_ERROR 61 printk("\n[ERROR] in %s : thread[%x,%x] illegal file descriptor index %d\n", 62 __FUNCTION__ , process->pid, this->trdid, file_id ); 63 #endif 50 64 this->errno = EBADFD; 51 65 return -1; … … 57 71 if( file_xp == XPTR_NULL ) 58 72 { 59 printk("\n[ERROR] in %s : undefined file descriptor index = %d\n", 60 __FUNCTION__ , file_id ); 73 74 #if DEBUG_SYSCALLS_ERROR 75 printk("\n[ERROR] in %s : thread[%x,%x] undefined fd_id %d\n", 76 __FUNCTION__, process->pid, this->trdid, file_id ); 77 #endif 61 78 this->errno = EBADFD; 62 79 return -1; 63 80 } 64 81 65 /* FIXME: file may be closed in parallel 66 * of seek/read/write/mmap ..etc 67 * so file may be NULL or invalid */ 82 // FIXME: file may be closed in parallel of seek/read/write/mmap ..etc 68 83 69 84 // call relevant VFS function … … 72 87 if( error ) 73 88 { 74 printk("\n[ERROR] in %s : cannot seek file = %d\n", 75 __FUNCTION__ , file_id ); 89 90 #if DEBUG_SYSCALLS_ERROR 91 printk("\n[ERROR] in %s : thread[%x,%x] cannot seek file_id %d\n", 92 __FUNCTION__, process->pid, this->trdid, file_id ); 93 #endif 76 94 this->errno = error; 77 95 return -1; 78 96 } 97 98 #if (DEBUG_SYS_LSEEK || CONFIG_INSTRUMENTATION_SYSCALLS) 99 uint64_t tm_end = hal_get_cycles(); 100 #endif 101 102 #if DEBUG_SYS_LSEEK 103 if( DEBUG_SYS_LSEEK < tm_end ) 104 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 105 __FUNCTION__ , process->pid, this->trdid, (uint32_t)tm_end ); 106 #endif 107 108 #if CONFIG_INSTRUMENTATION_SYSCALLS 109 hal_atomic_add( &syscalls_cumul_cost[SYS_LSEEK] , tm_end - tm_start ); 110 hal_atomic_add( &syscalls_occurences[SYS_LSEEK] , 1 ); 111 #endif 79 112 80 113 return new_offset; -
trunk/kernel/syscalls/sys_mmap.c
r637 r651 112 112 } 113 113 114 114 // FIXME handle Copy_On_Write for MAP_PRIVATE... 115 115 116 116 // test mmap type : can be FILE / ANON / REMOTE … … 127 127 #endif 128 128 129 129 // FIXME: handle concurent delete of file by another thread 130 130 131 131 if( fdid >= CONFIG_PROCESS_FILE_MAX_NR ) … … 164 164 #endif 165 165 166 // get inode pointer & mapper pointer 167 vfs_inode_t * inode_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode )); 166 // get mapper pointer 168 167 mapper_t * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper)); 169 168 170 // get file size 171 uint32_t size = hal_remote_l32( XPTR( file_cxy , &inode_ptr->size ) ); 172 173 #if (DEBUG_SYS_MMAP & 1) 174 if ( DEBUG_SYS_MMAP < tm_start ) 175 printk("\n[%s] thread[%x,%x] get file size : %d bytes\n", 176 __FUNCTION__, process->pid, this->trdid, size ); 177 #endif 178 179 // chek offset and length arguments 180 if( (offset + length) > size) 181 { 182 183 #if DEBUG_SYSCALLS_ERROR 184 printk("\n[ERROR] in %s: thread[%x,%x] / offset(%d) + len(%d) >= file's size(%d)\n", 185 __FUNCTION__, process->pid, this->trdid, k_attr.offset, k_attr.length, size ); 186 #endif 187 this->errno = ERANGE; 188 return -1; 189 } 169 #if (DEBUG_SYS_MMAP & 1) 170 if ( DEBUG_SYS_MMAP < tm_start ) 171 printk("\n[%s] thread[%x,%x] get file mapper %x\n", 172 __FUNCTION__, process->pid, this->trdid, mapper_ptr ); 173 #endif 190 174 191 175 /* TODO -
trunk/kernel/syscalls/sys_thread_cancel.c
r506 r651 101 101 { 102 102 // block target thread and mark it for delete 103 thread_delete( target_xp , pid , false );103 thread_delete( target_xp , false ); // not forced 104 104 } 105 105 -
trunk/kernel/syscalls/sys_thread_create.c
r637 r651 154 154 else // set default attributes 155 155 { 156 kern_attr.attributes = PT_ATTR_ DETACH | PT_ATTR_CLUSTER_DEFINED;156 kern_attr.attributes = PT_ATTR_CLUSTER_DEFINED; 157 157 child_cxy = dqdt_get_cluster_for_thread( LOCAL_CLUSTER->dqdt_root_xp ); 158 158 } -
trunk/kernel/syscalls/sys_thread_exit.c
r635 r651 33 33 #include <syscalls.h> 34 34 35 //////////////////////////////////////// 36 int sys_thread_exit( void * exit_ value)35 ///////////////////////////////////////// 36 int sys_thread_exit( void * exit_status ) 37 37 { 38 error_t error; 39 vseg_t * vseg; 40 38 41 thread_t * this = CURRENT_THREAD; 39 42 trdid_t trdid = this->trdid; 40 43 process_t * process = this->process; 41 44 pid_t pid = process->pid; 45 46 // check exit_value pointer in user space if required 47 if( exit_status != NULL ) 48 { 49 error = vmm_get_vseg( process , (intptr_t)exit_status , &vseg ); 42 50 43 // check exit_value argument 44 if( exit_value != NULL ) 45 { 51 if( error ) 52 { 46 53 47 54 #if DEBUG_SYSCALLS_ERROR 48 printk("\n[ERROR] in %s : thread[%x,%x] / exit_value argument %x must be NULL\n",49 __FUNCTION__ , pid, trdid , exit_value);55 printk("\n[ERROR] in %s : exit_status buffer %x unmapped / thread[%x,%x]\n", 56 __FUNCTION__, (intptr_t)exit_status, process->pid, this->trdid ); 50 57 #endif 51 this->errno = EINVAL; 52 return -1; 58 this->errno = EINVAL; 59 return -1; 60 } 61 } 62 63 // check busylocks 64 uint32_t count = this->busylocks; 65 if( count ) 66 { 67 68 #if DEBUG_SYSCALLS_ERROR 69 printk("\n[ERROR] in %s : busylocks count = %d / thread[%x,%x]\n", 70 __FUNCTION__ , count, process->pid, this->trdid ); 71 #endif 72 this->errno = EINVAL; 73 return -1; 53 74 } 54 75 55 76 // If calling thread is the main thread, the process must be deleted. 56 // => delete all process threads and synchronise with parent process. 57 // If calling thread is not the main thread, it must be deleted. 58 // => block the thread and mark it for delete. 59 if( (CXY_FROM_PID( pid ) == local_cxy) && (LTID_FROM_TRDID(trdid) == 0) ) 77 // => delete all process threads and synchronize with parent process. 78 // If calling thread is not the main thread, only this thread must be deleted. 79 // => register exit_status in thread descriptor, block the thread, 80 // mark it for delete, and synchronize with joining thread. 81 82 if( (CXY_FROM_PID( pid ) == local_cxy) && (LTID_FROM_TRDID(trdid) == 0) ) // main 60 83 { 61 84 … … 69 92 sys_exit( 0 ); 70 93 } 71 else 94 else // not the main 72 95 { 73 96 … … 78 101 __FUNCTION__ , pid , trdid , (uint32_t)tm_start ); 79 102 #endif 103 // register exit_status in thread descriptor 104 this->exit_status = exit_status; 105 80 106 // block calling thread and mark it for delete, 81 thread_delete( XPTR( local_cxy , this ) , pid , false );107 thread_delete( XPTR( local_cxy , this ) , false ); // not forced 82 108 83 109 // deschedule -
trunk/kernel/syscalls/sys_thread_join.c
r637 r651 1 1 /* 2 * sys_thread_join.c - passive wait on the end of a giventhread.2 * sys_thread_join.c - wait termination of of an attached thread. 3 3 * 4 4 * Authors Alain Greiner (2016,2017,2018,2019) … … 26 26 #include <hal_special.h> 27 27 #include <hal_irqmask.h> 28 #include <hal_uspace.h> 28 29 #include <thread.h> 29 30 #include <vmm.h> … … 37 38 /////////////////////////////////////// 38 39 int sys_thread_join ( trdid_t trdid, 39 void ** exit_ value)40 void ** exit_status ) 40 41 { 42 error_t error; 41 43 reg_t save_sr; 42 44 xptr_t target_xp; … … 47 49 xptr_t target_flags_xp; 48 50 xptr_t target_join_xp_xp; 51 xptr_t target_exit_status_xp; 49 52 xptr_t killer_xp; 50 53 xptr_t joining_xp; 51 54 thread_t * joining_ptr; 52 55 process_t * process; 56 vseg_t * vseg; 57 void * status; 53 58 54 59 // get joining thread pointers … … 62 67 63 68 #if DEBUG_SYS_THREAD_JOIN 64 uint64_t tm_start; 65 uint64_t tm_end; 66 tm_start = hal_get_cycles(); 69 uint64_t tm_start = hal_get_cycles(); 67 70 if( DEBUG_SYS_THREAD_JOIN < tm_start ) 68 printk("\n[ DBG] %s :joining thread[%x,%x] enter / target thread[%x,%x] / cycle %d\n",71 printk("\n[%s] joining thread[%x,%x] enter / target thread[%x,%x] / cycle %d\n", 69 72 __FUNCTION__ , process->pid, joining_ptr->trdid, 70 73 process->pid, trdid, (uint32_t)tm_start ); … … 77 80 78 81 #if DEBUG_SYSCALLS_ERROR 79 printk("\n[ERROR] in %s : illegal trdid argument %x \n",80 __FUNCTION__, trdid );82 printk("\n[ERROR] in %s : illegal trdid argument %x / joining thread[%x,%x]\n", 83 __FUNCTION__, trdid, joining_ptr->process->pid, joining_ptr-trdid ); 81 84 #endif 82 85 joining_ptr->errno = EINVAL; … … 84 87 } 85 88 86 // check exit_value argument 87 if( exit_value != NULL ) 89 // check exit_value argument in user space 90 error = vmm_get_vseg( process , (intptr_t)exit_status , &vseg ); 91 if( error ) 88 92 { 89 93 90 94 #if DEBUG_SYSCALLS_ERROR 91 printk("\n[ERROR] in %s : exit_ value argument must be NULL\n",92 __FUNCTION__ );95 printk("\n[ERROR] in %s : exit_status argument %x not mapped / joining thread[%x,%x]\n", 96 __FUNCTION__, exit_status, joining_ptr->process->pid, joining_ptr-trdid ); 93 97 #endif 94 98 joining_ptr->errno = EINVAL; … … 101 105 102 106 #if DEBUG_SYSCALLS_ERROR 103 printk("\n[ERROR] in %s : this thread (%x) == target thread(%x)\n",104 __FUNCTION__, joining_ptr-> trdid,trdid );107 printk("\n[ERROR] in %s : joinig thread[%x,%x] == target thread\n", 108 __FUNCTION__, joining_ptr->process->pid, joining_ptr->trdid ); 105 109 #endif 106 110 joining_ptr->errno = EDEADLK; … … 116 120 117 121 #if DEBUG_SYSCALLS_ERROR 118 printk("\n[ERROR] in %s : target thread %x not found\n",119 __FUNCTION__, trdid );122 printk("\n[ERROR] in %s : target thread[%x,%x] not found / joining_thread[%x,%x]\n", 123 __FUNCTION__, process->pid, trdid, joining_ptr->process->pid, joining_ptr-trdid ); 120 124 #endif 121 125 joining_ptr->errno = ESRCH; … … 124 128 125 129 // get extended pointers on various fields in target thread 126 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 127 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 128 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 130 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 131 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 132 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 133 target_exit_status_xp = XPTR( target_cxy , &target_ptr->exit_status ); 129 134 130 135 // check target thread joinable … … 133 138 134 139 #if DEBUG_SYSCALLS_ERROR 135 printk("\n[ERROR] in %s : target thread %x not joinable\n", __FUNCTION__, trdid ); 140 printk("\n[ERROR] in %s : target thread[%x,‰x] not attached / joining thread[%x,%x]\n", 141 __FUNCTION__, process->pid, trdid, joining_ptr->process->pid, joining_ptr-trdid ); 136 142 #endif 137 143 joining_ptr->errno = EINVAL; … … 146 152 147 153 // test the kill_done flag from the target thread 148 if( hal_remote_l32( target_flags_xp ) & THREAD_FLAG_KILL_DONE ) // killer thread is first 149 { 154 if( hal_remote_l32( target_flags_xp ) & THREAD_FLAG_KILL_DONE ) // killer is first 155 { 156 // get exit_status from target thread 157 status = (void*)hal_remote_lpt( target_exit_status_xp ); 158 150 159 // get pointers on killer thread 151 160 killer_xp = (xptr_t)hal_remote_l64( target_join_xp_xp ); … … 159 168 // release the lock protecting join 160 169 remote_busylock_release( target_join_lock_xp ); 161 162 #if DEBUG_SYS_THREAD_JOIN 163 tm_end = hal_get_cycles(); 164 if( DEBUG_SYS_THREAD_JOIN < tm_end ) 165 printk("\n[DBG] %s : joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n", 166 __FUNCTION__, process->pid, joining_ptr->trdid, process->pid, trdid, (uint32_t)tm_end ); 167 #endif 168 169 } 170 else // joining thread is first 170 } 171 else // joining is first 171 172 { 172 173 // set the join_done flag in target thread … … 184 185 #if DEBUG_SYS_THREAD_JOIN 185 186 if( DEBUG_SYS_THREAD_JOIN < tm_start ) 186 printk("\n[ DBG] %s :joining thread[%x,%x] deschedules / target thread[%x,%x] not completed\n",187 printk("\n[%s] joining thread[%x,%x] deschedules / target thread[%x,%x] not completed\n", 187 188 __FUNCTION__ , process->pid, joining_ptr->trdid, process->pid, trdid ); 188 189 #endif 189 190 // deschedule 190 191 sched_yield( "joining thread waiting killer thread" ); 192 193 // returns exit_status from joining thread 194 status = joining_ptr->exit_status; 195 } 191 196 197 // returns exit_status to user space 198 hal_copy_to_uspace( exit_status, 199 XPTR( local_cxy , &status ), 200 sizeof( void* ) ); 201 202 // restore IRQs 203 hal_restore_irq( save_sr ); 204 205 hal_fence(); 206 207 #if (DEBUG_SYS_THREAD_JOIN || CONFIG_INSTRUMENTATION_SYSCALLS) 208 uint64_t tm_end = hal_get_cycles(); 209 #endif 210 211 #if CONFIG_INSTRUMENTATION_SYSCALLS 212 hal_atomic_add( &syscalls_cumul_cost[SYS_THREAD_JOIN] , tm_end - tm_start ); 213 hal_atomic_add( &syscalls_occurences[SYS_THREAD_JOIN] , 1 ); 214 #endif 215 192 216 #if DEBUG_SYS_THREAD_JOIN 193 217 tm_end = hal_get_cycles(); 194 218 if( DEBUG_SYS_THREAD_JOIN < tm_end ) 195 printk("\n[ DBG] %s :joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n",219 printk("\n[%s] joining thread[%x,%x] exit / target thread[%x,%x] completed / cycle %d\n", 196 220 __FUNCTION__ , process->pid, joining_ptr->trdid, process->pid, trdid, (uint32_t)tm_end ); 197 221 #endif 198 222 199 }200 201 // restore IRQs202 hal_restore_irq( save_sr );203 204 223 return 0; 205 224 -
trunk/kernel/syscalls/syscalls.h
r642 r651 37 37 38 38 /****************************************************************************************** 39 * [0] This function terminates the execution of the calling user thread, 40 * and makes the exit_valuepointer available to any successful pthread_join() with the39 * [0] This function terminates the execution of the calling user thread, and makes 40 * the <exit_status> pointer available to any successful pthread_join() with the 41 41 * terminating thread. 42 * It actually set the THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in the 43 * thread descriptor and deschedule. 44 * The thread will be detached from its process, and the memory allocated to the thread 45 * descriptor will be released later by the scheduler. 46 ****************************************************************************************** 47 * @ exit_vallue : pointer to be returned to joining thread if thread is attached. 42 * - If the calling thread is the main thread, it calls the sys_exit() function to delete 43 * completely the user process. 44 * - if the calling thread is not the main thread, it registers the <exit_status> pointer 45 * in the thread descriptor, and calls the thread_delete() function, that will set the 46 * THREAD_SIG_EXIT signal, set the THREAD_BLOCKED_GLOBAL bit in thread descriptor, and 47 * deschedules. All memory allocated to the thread is released later by the scheduler. 48 * If the thread is in "detached" mode, the thread_delete() function implements 49 * the synchonisation with the joining thread. 50 ****************************************************************************************** 51 * @ exit_status : pointer to be returned to joining thread if thread is attached. 48 52 * @ return 0 if success / return -1 if all locks not released or illegal argument. 49 53 *****************************************************************************************/ 50 int sys_thread_exit( void * exit_ value);54 int sys_thread_exit( void * exit_status ); 51 55 52 56 /****************************************************************************************** … … 222 226 ****************************************************************************************** 223 227 * @ attr : pointer on attributes structure. 224 * @ return 0 if success / return-1 if failure.228 * @ returns 0 if success / returns -1 if failure. 225 229 *****************************************************************************************/ 226 230 int sys_mmap( mmap_attr_t * attr ); … … 234 238 * @ buf : buffer virtual address in user space. 235 239 * @ count : number of bytes. 236 * @ return number of bytes actually read if success / returns -1 if failure.240 * @ returns number of bytes actually read if success / returns -1 if failure. 237 241 *****************************************************************************************/ 238 242 int sys_read( uint32_t file_id, … … 251 255 * @ buf : buffer virtual address in user space. 252 256 * @ count : number of bytes. 253 * @ return number of bytes actually written if success / returns -1 if failure.257 * @ returns number of bytes actually written if success / returns -1 if failure. 254 258 *****************************************************************************************/ 255 259 int sys_write( uint32_t file_id, … … 258 262 259 263 /****************************************************************************************** 260 * [16] This function repositions the offset of the file descriptor identified by <file_id>,261 * according to the operation type defined by the <whence> argument.264 * [16] This function repositions the offset of the file descriptor identified by the 265 * <file_id> argument, according to the operation type defined by the <whence> argument. 262 266 ****************************************************************************************** 263 267 * @ file_id : open file index in fd_array. 264 268 * @ offset : used to compute new offset value. 265 269 * @ whence : operation type (see below). 266 * @ return 0if success / returns -1 if failure.270 * @ returns new offset value if success / returns -1 if failure. 267 271 *****************************************************************************************/ 268 272 int sys_lseek( xptr_t file_id, … … 276 280 ****************************************************************************************** 277 281 file_id : file descriptor index in fd_array. 278 * @ return 0 if success / returns -1 if failure.282 * @ returns 0 if success / returns -1 if failure. 279 283 *****************************************************************************************/ 280 284 int sys_close( uint32_t file_id ); … … 289 293 ****************************************************************************************** 290 294 * @ pathname : pathname (can be relative or absolute). 291 * @ return 0 if success / returns -1 if failure.295 * @ returns 0 if success / returns -1 if failure. 292 296 *****************************************************************************************/ 293 297 int sys_unlink( char * pathname );
Note: See TracChangeset
for help on using the changeset viewer.