/////////////////////////////////////////////////////////////////////////////////////// // File : init.c // Date : January 2018 // Author : Alain Greiner /////////////////////////////////////////////////////////////////////////////////////// // This single thread application implement the "init" process for ALMOS-MKH. // - It uses the fork/exec syscalls to create N KSH child processes // (one child process per user terminal), and register the corresponding PIDs // in the ksh_pid[] array. Then it calls the wait() function to block. // - It is reactivated when any child KSH process is terminated by a SIGKILL signal, // or stopped by a SIGSTOP signal. In case of SIGKILL, it scan all registered KSH // processes and re-creates each killed KSH process, using a new fork/exec. // It includes the hard_config.h file to get the NB_TXT_CHANNELS parameter. /////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #define NB_KSH (NB_TXT_CHANNELS - 1) ////////// int main() { int i; int ret; // fork return value int child_pid; int status; // used by the wait function char string[64]; // check number of TXT channels assert( NB_TXT_CHANNELS > 1 ); // create the KSH processes (one per user terminal) for( i = 0 ; i < NB_KSH ; i++ ) { // INIT process fork process CHILD ret = fork(); if( ret < 0 ) // error in fork { // display error message on TXT0 terminal display_string( "init process cannot fork\n" ); // INIT process exit exit( 1 ); } else if( ret > 0 ) // we are in INIT process { // INIT display string on kernel TXT0 snprintf( string , 64 , "INIT created KSH[%d]\n" , i ); display_string( string ); // INIT process deschedule pthread_yield(); } else // we are in CHILD process { // CHILD process exec process KSH if ( exec( "/bin/user/ksh.elf" , NULL , NULL ) ) // CHILD failure { // display error message on TXT0 terminal display_string( "child process cannot exec process ksh\n" ); // CHILD process exit exit( 1 ); } else // child success { // CHILD process deschedule pthread_yield(); } } } // @@@ display_string( "@@@ INIT process created all KSH processes\n" ); display_process( 0 ); display_sched( 0 , 0 ); // @@@ // This blocking loop is only for debug, because KSH[i] processes // should never be killed, and INIT should never exit the wait() function. while( 1 ) { // block on child process termination child_pid = wait( &status ); // build a string to report unexpected KSH process termination snprintf( string , 64 , "KSH process %x unexpectedly terminated" , child_pid ); // display string on kernel TXT0 (INIT has no TXT terminal) display_string( string ); } } // end main()