int main() { setenv("HOME","/",1); setenv("PATH","/bin:/usr/sbin:/bin",1); while(1) { int pid = fork(); if(pid) { _syscall_waitpid(pid); } else { char *command[] = {"/bin/terminal", "/bin/sh", 0}; execve(command[0], command, environ); } } }
/*-------------------------------------------- | Name: _syscall_exit | Description: | Parameters: none | Return Type: none | Comments: | See: ----------------------------------------------*/ int _syscall_exit(kernel_pthread_t* pthread_ptr, pid_t pid, void* data){ pid_t ppid = process_lst[pid]->ppid; exit_t* exit_dt=(exit_t*)data; if(process_lst[pid]->pthread_ptr->parent_pthread_ptr && process_lst[pid]->pthread_ptr->parent_pthread_ptr->stat&PTHREAD_STATUS_FORK ) { kernel_pthread_t* parent_pthread_ptr= process_lst[pid]->pthread_ptr; fork_t* fork_dt; //close all process(pid) file descriptor //must be execute before __atomic_in() and __stop_sched() //because in some _vfs_close() operation on driver, this operation need inter pthread communication to be completed //(ex: lwip_sock_close() deadlock risk); _close_process_fd(pid); //atomic code no task switching __atomic_in(); //wakeup locked process _sys_unlockw(); //warning all!!! micro-kernel operation is not advised. __stop_sched(); fork_dt=(fork_t*)pthread_ptr->parent_pthread_ptr->reg.data; //restore father context _sys_vfork_exit(pthread_ptr,exit_dt->status); //restart father fork_dt->pid=pid; __flush_syscall(pthread_ptr); __restart_sched(); __flush_syscall(parent_pthread_ptr); //cancel the pthread //_sys_pthread_cancel(process_lst[pid]->pthread_ptr, pid); //free(process_lst[pid]->pthread_ptr); //wake up dad on waitpid //__kernel_ret_int(parent_pthread_ptr);//father } else { //close all process(pid) file descriptor //must be execute before __atomic_in() and __stop_sched() //because in some _vfs_close() operation on driver, this operation need inter pthread communication to be completed //(ex: lwip_sock_close() deadlock risk); _close_process_fd(exit_dt->pid); //atomic code no task switching __atomic_in(); //_close_process_fd(exit_dt->pid); //wakeup locked process _sys_unlockw(); //warning!!! all micro-kernel operation is not advised. __stop_sched(); // _sys_exit(exit_dt->pid,exit_dt->status); // __flush_syscall(pthread_ptr); __atomic_out(); //ppid threads are on waitpid()? if( ppid) { //get main thread of father process kernel_pthread_t* _pthread_ptr=process_lst[ppid]->pthread_ptr; //walking on threads chained list in parent process while(_pthread_ptr) { //is thread blocked on waitpid()? if(_pthread_ptr->stat&PTHREAD_STATUS_STOP && _pthread_ptr->reg.syscall== _SYSCALL_WAITPID) { waitpid_t* waitpid_dt = (waitpid_t*)_pthread_ptr->reg.data; _syscall_waitpid(_pthread_ptr,ppid,waitpid_dt); } _pthread_ptr=_pthread_ptr->next; } //send signal to one pthread father processus if no one are in WAITPID and STOP state _sys_kill(process_lst[ppid]->pthread_ptr,SIGCHLD,1); _sys_pthread_cancel_for_exit(pthread_ptr, pid); } else{ pid_t _pid; //it's a daemon process //free process // free(process_lst[pid]); // process_lst[pid]= 0; // //printf("_syscall_exit\r\n"); //checkif it's the last process for(_pid=1; _pid<=PROCESS_MAX; _pid++) if(process_lst[_pid]) { free(process_lst[pid]); process_lst[pid]= 0; goto end; } return -1; //in this case stop all } // } end: __restart_sched(); __atomic_out(); return 0; }