Changeset 407 for trunk/kernel/syscalls/sys_exec.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_exec.c
r406 r407 38 38 39 39 ////////////////////////////////////////////////i////////////////////////////////////// 40 // This static function is called by the sys_exec() function to register the .elf41 // pathname in the exec_info structure, from a string stored in user space.42 ////////////////////////////////////////////////i//////////////////////////////////////43 // @ exec_info : pointer on the exec_info structure.44 // @ pathname : string containing the path to the .elf file (user space).45 // return 0 if success / non-zero if one string too long, or too many strings.46 ///////////////////////////////////////////////////////////////////////////////////////47 static error_t process_exec_get_path( exec_info_t * exec_info,48 char * pathname )49 {50 error_t error;51 52 // copy string to exec_info53 error = hal_strcpy_from_uspace( &exec_info->path[0] , pathname ,54 CONFIG_VFS_MAX_PATH_LENGTH );55 if( error )56 return EINVAL;57 58 return 0;59 }60 61 ////////////////////////////////////////////////i//////////////////////////////////////62 40 // This static function is called twice by the sys_exec() function : 63 41 // - to register the main() arguments (args) in the exec_info structure. … … 71 49 // to store the (args) and (envs) strings are configuration parameters. 72 50 /////////////////////////////////////////////////////////////////////////////////////// 73 // @ exec_info : pointer on the exec_info structure.74 // @ is_args : true if called for (args) / false if called for (envs).75 // @ pointers : array of pointers on the strings (in user space).51 // @ exec_info : pointer on the exec_info structure. 52 // @ is_args : true if called for (args) / false if called for (envs). 53 // @ u_pointers : array of pointers on the strings (in user space). 76 54 // @ return 0 if success / non-zero if too many strings or no more memory. 77 55 /////////////////////////////////////////////////////////////////////////////////////// … … 173 151 // This function build an exec_info_t structure containing all informations 174 152 // required to create the new process descriptor and the associated thread. 175 // It calls the static process_exec_get_path() and process_exec_get_strings() functions 176 // to copy the .elf pathname, the main() arguments and the environment variables from 177 // user buffers to the exec_info_t structure, and call the process_make_exec() function. 153 // It calls the process_exec_get_strings() functions to copy the main() arguments and 154 // the environment variables from user buffers to the exec_info_t structure, allocate 155 // and call the process_make_exec() function. 156 // Finally, it destroys the calling thread and process. 157 // TODO : the args & envs arguments are not supported yet : both must be NULL 178 158 ///////////////////////////////////////////////////////////////////////////////////////// 179 int sys_exec( char * filename, // .elf file pathname159 int sys_exec( char * pathname, // .elf file pathname 180 160 char ** args, // process arguments 181 161 char ** envs ) // environment variables 182 162 { 183 exec_info_t exec_info; // structure to pass to process_make_exec() 184 error_t error; 185 paddr_t paddr; 186 163 exec_info_t exec_info; // structure to pass to process_make_exec() 164 error_t error; 165 166 uint64_t tm_start; 167 uint64_t tm_end; 168 169 tm_start = hal_get_cycles(); 170 171 // get pointers on parent process and thread 187 172 thread_t * this = CURRENT_THREAD; 188 173 process_t * process = this->process; 189 190 // check argument fileme 191 error = vmm_v2p_translate( false , filename , &paddr ); 174 pid_t pid = process->pid; 175 176 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / cycle %d\n", 177 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)hal_get_cycles() ); 178 179 sched_display( 0 ); 180 181 // check pathname length 182 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 183 { 184 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 185 this->errno = ENFILE; 186 return -1; 187 } 188 189 // copy pathname in exec_info structure (kernel space) 190 hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 191 // check args argument 192 assert( (args == NULL) , __FUNCTION__ , 193 "args not supported yet\n" ); 194 195 // check envs argument 196 assert( (envs == NULL) , __FUNCTION__ , 197 "args not supported yet\n" ); 198 199 // compute client_cxy (local cluster) and server_cxy (target cluster) 200 cxy_t cxy_server = CXY_FROM_PID( pid ); 201 cxy_t cxy_client = local_cxy; 202 203 // register parent process in exec_info 204 exec_info.parent_xp = process->ref_xp; 205 206 // new process keep the parent process PID 207 exec_info.keep_pid = true; 208 209 // check and store args in exec_info structure if required 210 if( args != NULL ) 211 { 212 if( process_exec_get_strings( &exec_info , true , args ) ) 213 { 214 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 215 this->errno = error; 216 return -1; 217 } 218 } 219 220 // check and store envs in exec_info structure if required 221 if( envs != NULL ) 222 { 223 if( process_exec_get_strings( &exec_info , false , envs ) ) 224 { 225 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 226 this->errno = error; 227 return -1; 228 } 229 } 230 231 // call process_make_exec (local or remote) 232 if( cxy_server == cxy_client ) 233 { 234 error = process_make_exec( &exec_info ); 235 } 236 else 237 { 238 rpc_process_exec_client( cxy_server , &exec_info , &error ); 239 } 192 240 193 241 if( error ) 194 242 { 195 printk("\n[ERROR] in %s : filename unmapped\n", __FUNCTION__ ); 196 this->errno = EINVAL; 197 return -1; 198 } 199 200 // check argument fileme 201 error = vmm_v2p_translate( false , args , &paddr ); 202 203 if( error ) 204 { 205 printk("\n[ERROR] in %s : args unmapped\n", __FUNCTION__ ); 206 this->errno = EINVAL; 207 return -1; 208 } 209 210 // check argument fileme 211 error = vmm_v2p_translate( false , envs , &paddr ); 212 213 if( error ) 214 { 215 printk("\n[ERROR] in %s : envs unmapped\n", __FUNCTION__ ); 216 this->errno = EINVAL; 217 return -1; 218 } 219 220 // compute client_cxy (local cluster) and server_cxy (target cluster) 221 cxy_t cxy_server = CXY_FROM_PID( process->pid ); 222 cxy_t cxy_client = local_cxy; 223 bool_t is_local = (cxy_server == cxy_client); 224 225 exec_dmsg("\n[DMSG] %s starts for process %x on core %d in cluster %x" 226 " / target_cluster = %x / cycle %d\n", 227 __FUNCTION__, process->pid , CURRENT_CORE->lid, 228 cxy_client, cxy_server, hal_get_cycles()); 229 230 // register reference parent process in exec_info 231 exec_info.parent_xp = process->ref_xp; 232 233 // check pathname and store it in exec_info structure 234 error = process_exec_get_path( &exec_info , filename ); 235 236 if ( error ) 237 { 238 printk("\n[ERROR] in %s : elf pathname too long\n", __FUNCTION__ ); 243 printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n", 244 __FUNCTION__, pid, cxy_server ); 239 245 this->errno = error; 240 246 return -1; 241 247 } 242 248 243 // check and store args in exec_info structure 244 error = process_exec_get_strings( &exec_info , true , args ); 245 246 if( error ) 247 { 248 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 249 this->errno = error; 250 return -1; 251 } 252 253 // check and store envs in exec_info structure 254 error = process_exec_get_strings( &exec_info , false , envs ); 255 256 if( error ) 257 { 258 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 259 this->errno = error; 260 return -1; 261 } 262 263 exec_dmsg("\n[DMSG] %s starts exec for process %x at cycle %d\n", 264 __FUNCTION__, process->pid, hal_get_cycles() ); 265 266 if( is_local ) error = process_make_exec( &exec_info ); 267 else rpc_process_exec_client( cxy_server , &exec_info , &error ); 268 269 if( error ) 270 { 271 printk("\n[ERROR] in %s : cannot create new process %x\n", 272 __FUNCTION__ , process->pid ); 273 this->errno = error; 274 return -1; 275 } 276 277 exec_dmsg("\n[DMSG] %s completes exec for process %x at cycle %d\n", 278 __FUNCTION__, process->pid , hal_get_cycles() ); 279 280 // delete the calling thread an process 281 thread_kill( CURRENT_THREAD ); 282 process_kill( CURRENT_THREAD->process ); 249 // FIXME delete the local process descriptor 250 // process_kill( process ); 251 252 tm_end = hal_get_cycles(); 253 254 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for process %x / cycle %d\n" 255 " pathname = %s / cost = %d\n", 256 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start, 257 exec_info.path , (uint32_t)(tm_end - tm_start) ); 283 258 284 259 return 0;
Note: See TracChangeset
for help on using the changeset viewer.