예제 #1
0
void event_do_wakeup_calls (enum einit_event_code c) {
 struct wakeup_data *d = event_wd;

 while (d) {
  if (d->code == c) {
   struct lmodule *m = NULL;
   emutex_lock (&event_wakeup_mutex);
   if (d->module && (d->module->status & status_suspended))
    m = d->module;
   emutex_unlock (&event_wakeup_mutex);

   if (m) {
    mod(einit_module_resume, m, NULL);
    time_t nt = time(NULL) + 60;
    emutex_lock (&event_wakeup_mutex);
    if (!event_snooze_time || ((event_snooze_time+30) < nt)) {
     event_snooze_time = nt;
     emutex_unlock (&event_wakeup_mutex);

     {
      struct einit_event ev = evstaticinit (einit_timer_set);
      ev.integer = event_snooze_time;

      event_emit (&ev, einit_event_flag_broadcast);

      evstaticdestroy (ev);
     }
    } else
     emutex_unlock (&event_wakeup_mutex);
   }
  }
  d = d->next;
 }
}
예제 #2
0
파일: oled_app.c 프로젝트: MaxGekk/ZigZag
void    stimer_fired( const uint8_t tnum ) 
{
   static unsigned int i;
   if(tnum == KBRD_ANTIRING_TIMER)
   {
      kbrd_clear_ring_buf();
      P2IE  &= ~0x0f; // Disable interrupts
//      port_write(4, 0x01, PIN_LO);
      kbrd_service();
//      port_write(4, 0x01, PIN_HI);
      P2IE  |=  0x0f; // Enable interrupts
      port_write(KBRD_SOUND_PORT, KBRD_SOUND_PIN, PIN_LO);
      if(kbrd_pressed)
      event_emit(KBRD_EVT_PRIORITY, KBRD_EVT, 0);
   }
   else if(tnum == KBRD_SOUND_TIMER)
   {
      port_write(KBRD_SOUND_PORT, KBRD_SOUND_PIN, PIN_LO);
   }
   else
   {
      stimer_set(1, 1000);
      update_time();
      //toggleLED(LED_FIRE | LED_POWER);
   }
}
예제 #3
0
파일: sensor.c 프로젝트: MaxGekk/ZigZag
void stimer_fired( const uint8_t timer_num)
   {
    result_t err;
    int res;

    DBG("call fired");

    if(timer_num)
    {
       DBG("Timer not supported");
       return;
    }

    if(stage == STAGE_IDLE)
    {
       err = event_emit( NORMAL_PRIORITY, TIMER_EVENT, 0);
       if( ENOERR != err ) DBG("FAIL: emit timer event");
       return;
    }

    
    res = init_PyroMeasurement(1);
   
    err = stimer_set(TIMER_0, SHOT_PERIOD);
        if( ENOERR != err ) DBG("FAIL: start usual timer");


    DBG("return fired");
    return;
   }
예제 #4
0
void *event_emit (struct einit_event *event, enum einit_event_emit_flags flags) {
 pthread_t **threads = NULL;
 if (!event || !event->type) return NULL;

 event_do_wakeup_calls (event->type);

 if (flags & einit_event_flag_spawn_thread) {
  struct einit_event *ev = evdup(event);
  if (!ev) return NULL;

  ethread_spawn_detached_run ((void *(*)(void *))event_subthread, (void *)ev);

  return NULL;
 }

 uint32_t subsystem = event->type & EVENT_SUBSYSTEM_MASK;

/* initialise sequence id and timestamp of the event */
  event->seqid = cseqid++;
  event->timestamp = time(NULL);

  struct event_function *cur = event_functions;
  while (cur) {
   if (((cur->type == subsystem) || (cur->type == einit_event_subsystem_any)) && cur->handler) {
    if (flags & einit_event_flag_spawn_thread_multi_wait) {
     pthread_t *threadid = emalloc (sizeof (pthread_t));
     struct evt_wrapper_data *d = emalloc (sizeof (struct evt_wrapper_data));

     d->event = evdup(event);
     d->handler = cur->handler;

     ethread_create (threadid, NULL, (void *(*)(void *))event_thread_wrapper, d);
     threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC);
    } else
     cur->handler (event);
   }
   cur = cur->next;
  }

 if (event->chain_type) {
  event->type = event->chain_type;
  event->chain_type = 0;
  event_emit (event, flags);
 }

 if ((flags & einit_event_flag_spawn_thread_multi_wait) && threads) {
  int i = 0;

  for (; threads[i]; i++) {
   pthread_join (*(threads[i]), NULL);

   free (threads[i]);
  }

  free (threads);
 }

 return NULL;
}
예제 #5
0
void    irq_handler( irq_t  irq )
{
    if( GERCON_IRQ == irq ) {
        /* Обрабатываем прерывание от геркона */
        port_attr_t   port_attr;
        /* Перенастраиваем вход от геркона. Если до этого прерывание от геркона генерилось
         * на спаде, то перенастраиваем на фронт. Если же на фронте, то перенастраиваем на спад.  */
        port_get_attr( GERCON_PORT, GERCON_PIN, &port_attr );
        port_attr.ies ^= GERCON_PIN; 
        port_set_attr( GERCON_PORT, GERCON_PIN, &port_attr );
        /* Продолжаем обработку прерывания в обработчике события */
        if( PIN_IS_SET( port_attr.ies, GERCON_PIN ) )
            event_emit( PRIORITY_HIGH, EV_TYPE_OPEN, 0 );
        else
            event_emit( PRIORITY_HIGH, EV_TYPE_CLOSE, 0 );
    }
    return;
}
예제 #6
0
void event_timer_cancel (time_t t) {
 struct einit_event ev = evstaticinit (einit_timer_cancel);

 ev.integer = t;

 event_emit (&ev, einit_event_flag_broadcast);

 evstaticdestroy (ev);
}
예제 #7
0
struct lmodule *mod_update (struct lmodule *module) {
 if (!module->module) return module;

 struct einit_event ee = evstaticinit (einit_core_update_module);
 ee.para = (void *)module;
 event_emit (&ee, einit_event_flag_broadcast);
 evstaticdestroy(ee);

 return module;
}
예제 #8
0
파일: sensor.c 프로젝트: MaxGekk/ZigZag
void irq_handler( irq_t interrupt )
{
   uint16_t tmp; // General purpose temporal variable
   
   switch(interrupt)
   {
   case INT_NUM_ADC12:
      tmp = adc_int_handler(ADC12IV);
      event_emit(NORMAL_PRIORITY, ADC12_EVENT, tmp);
      break;
   }
}
예제 #9
0
time_t event_timer_register (struct tm *t) {
 struct einit_event ev = evstaticinit (einit_timer_set);
 time_t tr = timegm (t);

 ev.integer = tr;

 event_emit (&ev, einit_event_flag_broadcast);

 evstaticdestroy (ev);

 return tr;
}
예제 #10
0
time_t event_timer_register_timeout (time_t t) {
 struct einit_event ev = evstaticinit (einit_timer_set);
 time_t tr = time (NULL) + t;

 ev.integer = tr;

 event_emit (&ev, einit_event_flag_broadcast);

 evstaticdestroy (ev);

 return tr;
}
예제 #11
0
파일: oled_app.c 프로젝트: MaxGekk/ZigZag
//size_t    msg_recv( msg_t   msg ) // Return type has changed in new version
void    msg_recv( msg_t   msg )
{
   size_t msg_size;
   
   OLED_puts(0, 41, 0xff, font6x9, "Message");
   msg_size = parse_message(msg);
   total_msg_count++;
   event_emit(LOW_PRIORITY, DISPLAY_EVT, 2);
   msg_destroy(msg);
      
//   return msg_size;
//   return (sizeof(struct msginfo) + minfo.body_size);
}
예제 #12
0
void linux_static_dev_boot_event_handler (struct einit_event *ev) {
    switch (ev->type) {
    case einit_boot_early:
        if (linux_static_dev_run() == status_ok) {
            struct einit_event eml = evstaticinit(einit_boot_devices_available);
            event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait);
            evstaticdestroy(eml);
        }
        break;

    default:
        break;
    }
}
예제 #13
0
/* Инициализация портов */
void    sys_init()
{
    port_attr_t   port_attr;


    /* Настройка выхода на зелёный светодиод */
    PIN_SET( port_attr.dir, GREEN_PIN, PIN_HI );    /* Направление на вывод */
    PIN_CLEAR( port_attr.sel, GREEN_PIN );          /* Функция ввода/вывода */
    port_set_attr( GREEN_PORT, GREEN_PIN, &port_attr );
    port_write( GREEN_PORT, GREEN_PIN, PIN_LO );       /* По умолчанию гасим светодиод */

    /* Настройка выхода на красный светодиод */
    PIN_SET( port_attr.dir, RED_PIN, PIN_HI );    /* Направление на вывод */
    PIN_CLEAR( port_attr.sel, RED_PIN );          /* Функция ввода/вывода */
    port_set_attr( RED_PORT, RED_PIN, &port_attr );
    port_write( RED_PORT, RED_PIN, PIN_LO );       /* По умолчанию гасим светодиод */

    /* Настройка входа от геркона  */
    {   port_t  gercon_port = 0x00;
        event_type_t    event_type = 0;
        result_t    res = ENOSYS;    

        port_reset_iflag( GERCON_PORT, GERCON_PIN );

        PIN_CLEAR( port_attr.dir, GERCON_PIN );     /* Направление на ввод */
        PIN_CLEAR( port_attr.sel, GERCON_PIN );     /* Функция ввода/вывода */ 
        PIN_SET( port_attr.ie, GERCON_PIN, PIN_HI );    /* Разрешаем прерывания от кнопки */
        PIN_SET( port_attr.ies, GERCON_PIN, PIN_HI );   /* Ловим изменение с высокого на низкий уровень */ 
        port_set_attr( GERCON_PORT, GERCON_PIN, &port_attr );

        port_read( GERCON_PORT, GERCON_PIN, &gercon_port );

        /* Определение текущего состояния геркона */
        if( PIN_IS_SET( gercon_port, GERCON_PIN) ) {
            event_type = EV_TYPE_OPEN;
        } else {   
            PIN_SET( port_attr.ies, GERCON_PIN, PIN_LO );   /* Ловим изменение с низкого на высокий уровень */ 
            port_set_attr( GERCON_PORT, GERCON_PIN, &port_attr );
            event_type = EV_TYPE_CLOSE;
        }
        res = event_emit( PRIORITY_LOW, event_type, 0 );
        if( IS_ERROR(res) ) {
            /* Не смогли начать работу, зажигаем красный светодиод */
            port_write( RED_PORT, RED_PIN, PIN_HI );
        }
    }

    return;
}
예제 #14
0
파일: mbtx.c 프로젝트: MaxGekk/ZigZag
void    event_handler( event_type_t event_type, unidata_t   unidata )
{
    if( EV_MBREQ_DONE == event_type ) {
        result_t    res;
        res = mb_master_request( slave_addr[cur_slave],
                100, 0,0, &ans_fcode,ans_dptr,&ans_dsize );
        if( IS_OK(res) ) {
            cur_slave++;
            if( cur_slave >= SLAVE_TOTAL )
                cur_slave = 0;
            return;
        }
        event_emit( PRIORITY_HIGH, EV_MBREQ_DONE, (unidata_t)ENOERR );
    }
}
예제 #15
0
파일: giop.c 프로젝트: MaxGekk/ZigZag
/* Инициализация портов */
void    sys_init()
{
    port_attr_t   port_attr;
#if defined(BLINK_ON)
    PIN_SET( port_attr.dir, LED1|LED2|LED3, PIN_HI );   /* Направление на вывод */
    PIN_CLEAR( port_attr.sel, LED1|LED2|LED3 );         /* Функция ввода/вывода */
    PIN_CLEAR( port_attr.ie, LED1|LED2|LED3 );          /* Запрет прерываний */
    port_set_attr( LED_PORT, LED1|LED2|LED3, &port_attr );
    port_write( LED_PORT, LED1|LED2|LED3, PIN_LO );
#endif
#if defined(PLATFORM_FIRE_BUTTON)
    PIN_SET( port_attr.dir, CONTROL_PINS, PIN_HI );   /* Направление на вывод */
    PIN_CLEAR( port_attr.sel, CONTROL_PINS );         /* Функция ввода/вывода */
    PIN_CLEAR( port_attr.ie, CONTROL_PINS );          /* Запрет прерываний */
    port_set_attr( CONTROL_PORT, CONTROL_PINS, &port_attr );
    port_write( CONTROL_PORT, CONTROL_PINS, PINT1 );
#endif
    /* Настройка входа от геркона  */
    {   port_t  iport = 0x00;
        event_type_t    event_type = 0;
        result_t    res = ENOSYS;    

        port_reset_iflag( IPORT, IPINS );

        PIN_CLEAR( port_attr.dir, IPINS );     /* Направление на ввод */
        PIN_CLEAR( port_attr.sel, IPINS );     /* Функция ввода/вывода */ 
        PIN_SET( port_attr.ie, IPINS, PIN_HI );    /* Разрешаем прерывания от кнопки */
        PIN_SET( port_attr.ies, IPINS, PIN_LO );   /* Ловим изменение с низкого на высокий уровень */ 
        port_set_attr( IPORT, IPINS, &port_attr );

        /* Определение текущего состояния входов */
        port_read( IPORT, IPINS, &iport );
        /* У тех входов, которые уже в 1 настраиваем прерывания на спад */
        PIN_SET( port_attr.ies, iport, PIN_HI );   /* Ловим изменение с высокого на низкий уровень */ 
        port_set_attr( IPORT, iport, &port_attr );
        res = event_emit( PRIORITY, GIOP_INTERRUPT, (unidata_t)iport );
        if( IS_ERROR(res) ) {
            port_write( LED_PORT, LED1, PIN_HI );
        }
    }
    return;
}
예제 #16
0
파일: giop.c 프로젝트: MaxGekk/ZigZag
void    irq_handler( irq_t  irq )
{
    /* Обрабатываем изменение состояний входов */
    if( IPORT_IRQ == irq ) {
        port_attr_t   port_attr;
        port_t  ifg, in;
        /* Перенастраиваем прерывания от входов */
        port_get_attr( IPORT, IPINS, &port_attr );
        port_get_iflag( IPORT, IPINS, &ifg );   /* Маска флагов прерываний */
        if( ifg ) {
            port_reset_iflag( IPORT, ifg );         /* Сбрасываем флаги прерываний */
            port_attr.ies ^= ifg;   /* Меняем условие генерации прерывания, у входов, у которых изменилось состояние */
            port_set_attr( IPORT, IPINS, &port_attr );
            port_read( IPORT, IPINS, &in );         /* Вычитываем состояние входов, чтобы записать их в атрибут */
            /* Продолжаем обработку прерывания в обработчике события */
            event_emit( PRIORITY, GIOP_INTERRUPT, in );
        }
    }
    return;
}
예제 #17
0
파일: sensor.c 프로젝트: MaxGekk/ZigZag
void sys_init()
   {
    result_t err;	    

    DBG("call init_module");

    stage = STAGE_IDLE; // Wait for the system to start up


    err = event_emit( NORMAL_PRIORITY, TIMER_EVENT, 0);
    if( ENOERR != err ) DBG("FAIL: module start");

    cur_MotionState = MOTION_STATE_QUIET;
    motion_detect_count = 0;
    middle_point        = (4096 / 2) << 4;


    DBG("return init_module");    
    return; 
   }
예제 #18
0
void linux_static_dev_hotplug_handle (char **v) {
    if (v && v[0]) {
        int i = 0;
        char **args = NULL;
        struct einit_event ev = evstaticinit(einit_hotplug_generic);

        if (strstr (v[0], "add@") == v[0]) {
            ev.type = einit_hotplug_add;
        } else if (strstr (v[0], "remove@") == v[0]) {
            ev.type = einit_hotplug_remove;
        } else if (strstr (v[0], "change@") == v[0]) {
            ev.type = einit_hotplug_change;
        } else if (strstr (v[0], "online@") == v[0]) {
            ev.type = einit_hotplug_online;
        } else if (strstr (v[0], "offline@") == v[0]) {
            ev.type = einit_hotplug_offline;
        } else if (strstr (v[0], "move@") == v[0]) {
            ev.type = einit_hotplug_move;
        }

        for (i = 1; v[i]; i++) {
            char *n = strchr (v[i], '=');
            if (n) {
                *n = 0;
                n++;

                args = (char **)setadd ((void **)args, v[i], SET_TYPE_STRING);
                args = (char **)setadd ((void **)args, n, SET_TYPE_STRING);
            }
        }

        ev.stringset = args;

        /* emit the event, waiting for it to be processed */
        event_emit (&ev, einit_event_flag_broadcast);
        evstaticdestroy (ev);

        if (args) free (args);
    }
}
예제 #19
0
파일: oled_app.c 프로젝트: MaxGekk/ZigZag
void    sys_init()
{
//   char str[32];
//   unsigned long ul;
//   struct LogEntry entry;
   struct NodeCfg ncfg;
   unsigned long long _ull;
   
   FILEDESCR_t fd;
   int err;
   static struct child c = {BAD_ADDRESS, 0};
   
//   msg_count       = 0;
//   last_msg_pos    = 0;
   total_msg_count = 0;

   for(err = MAX_CHILDREN; err--; )
      memcopy(&children[err], &c, sizeof(struct child));
   //memset(zone_state, 0, sizeof(zone_state));
   for(err = STRG_MAX_ZONE_NUM; err--;)
      zone_state[err] = ZONE_STATE_ON;

   init_LEDs();
   setNormalState();
   //switchOnLED(LED_RED);
//   scroll_pos      = 0;
//   port_attr_t p4;

//   event_emit(0, INIT_EVT, 0);

   /*
   PIN_SET(p4.dir, 0x19, PIN_HI);
   PIN_CLEAR(p4.sel, 0x19);
   port_set_attr(4, 0x19, &p4);
   port_write(4, 0x19, PIN_HI);
   p4_val = 0x01;
   */
  
//   SPI_init();
//   err = initStorage();
//   OLED_init();
//   init_kbrd();
//   menu_init(0);
//   OLED_clr(68, 3*9, 2 * 6, 9);
//   err = mmcReadBlock(23, 3, &ul);

   //err = logEntriesNum();
   //err = logAddEntry(&entry, "Test message3");
   //err = strgFindNode(0x66ULL, &ncfg);
   //itoa(err, fd.filename, 10);
   //OLED_puts(0, 0, 0xff, font6x9, fd.filename);
   //out_dump (0, 50, sizeof(struct NodeCfg), &ncfg);
   /*
   strcpy(str, "Pos: ");
   ul = logstat.last_entry_pos;
   //ul = (unsigned long)syscfg.log_state_pos << 9;
   ultoa(ul, str + strlen(str), 10);
   str[strlen(str) + 1] = 0;
   str[strlen(str)]     = ' ';
   ul = syscfg.log_state_pos;
   ultoa(ul, str + strlen(str), 10);

   OLED_puts(0, 0, 0xff, font6x9, str);
   */

//   init_FAT();
//   Read_PBR();
//   ultoa(fat.root_dir, fd.filename, 16);
//   OLED_puts(17 * 6, 50, 0xff, font6x9, fd.filename);
/*
   strcpy(fd.filename, "LOG     ");
   if(FindFile(fat.root_dir, &fd) != FAT_SUCCESS)
      OLED_puts(0, 50, 0xff, font6x9, "FindFile failed");
   else
   {
      itoa(fd.clust, fd.filename, 16);
      OLED_puts(0, 50, 0xff, font6x9, fd.filename);
      ultoa(fd.size, fd.filename, 16);
      OLED_puts(10 * 6, 50, 0xff, font6x9, fd.filename);
   }
*/

   event_emit(LOW_PRIORITY, INIT_EVT, 0);

//   stimer_set(1, 1000);
//
               
    return;
}
예제 #20
0
int mod (enum einit_module_task task, struct lmodule *module, char *custom_command) {
 struct einit_event *fb;
 unsigned int ret;

 if (!module) return 0;

/* wait if the module is already being processed in a different thread */
 if (!(task & einit_module_ignore_mutex)) {
  if ((task & einit_module_suspend) || (task & einit_module_resume)) {
   if (pthread_mutex_trylock (&module->mutex))
    return status_failed;
  } else
   emutex_lock (&module->mutex);
 }

 if (task & einit_module_suspend) {
  int retval = mod_suspend (module);

  if (!(task & einit_module_ignore_mutex))
   emutex_unlock (&module->mutex);

  return retval;
 }

 if (task & einit_module_resume) {
  int retval = mod_resume (module);

  if (!(task & einit_module_ignore_mutex))
   emutex_unlock (&module->mutex);

  return retval;
 }

 if (module->status & status_suspended) {
  if (!(mod_resume (module) == status_ok)) {
   if (!(task & einit_module_ignore_mutex))
    emutex_unlock (&module->mutex);

   return status_failed;
  }
 }

 if (task & einit_module_custom) {
  if (!custom_command) {
   if (!(task & einit_module_ignore_mutex))
    emutex_unlock (&module->mutex);

   return status_failed;
  }

  goto skipdependencies;
 }

 if (task & einit_module_ignore_dependencies) {
  notice (2, "module: skipping dependency-checks");
  task ^= einit_module_ignore_dependencies;
  goto skipdependencies;
 }

 if (module->status & MOD_LOCKED) { // this means the module is locked. maybe we're shutting down just now.
  if (!(task & einit_module_ignore_mutex))
   emutex_unlock (&module->mutex);

  if (task & einit_module_enable)
   return status_failed;
  else if (task & einit_module_disable)
   return status_ok;
  else
   return status_ok;
 }

 module->status |= status_working;

/* check if the task requested has already been done (or if it can be done at all) */
 if ((task & einit_module_enable) && (!module->enable || (module->status & status_enabled))) {
  wontload:
  module->status ^= status_working;
  if (!(task & einit_module_ignore_mutex))
   emutex_unlock (&module->mutex);
  return status_idle;
 }
 if ((task & einit_module_disable) && (!module->disable || (module->status & status_disabled) || (module->status == status_idle)))
  goto wontload;

 if (task & einit_module_enable) {
  if (!service_usage_query(service_requirements_met, module, NULL))
   goto wontload;
 } else if (task & einit_module_disable) {
  if (!service_usage_query(service_not_in_use, module, NULL))
   goto wontload;
 }

 skipdependencies:

/* inform everyone about what's going to happen */
 {
  struct einit_event eem = evstaticinit (einit_core_module_update);

  modules_work_count++;

  eem.task = task;
  eem.status = status_working;
  eem.para = (void *)module;
  eem.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0];
  event_emit (&eem, einit_event_flag_broadcast);
  evstaticdestroy (eem);

/* same for services */
  if (module->si && module->si->provides) {
   struct einit_event ees = evstaticinit (einit_core_service_update);
   ees.task = task;
   ees.status = status_working;
   ees.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0];
   ees.set = (void **)module->si->provides;
   ees.para = (void *)module;
   event_emit (&ees, einit_event_flag_broadcast);
   evstaticdestroy (ees);
  }
 }

/* actual loading bit */
 {
  fb = evinit (einit_feedback_module_status);
  fb->para = (void *)module;
  fb->task = task | einit_module_feedback_show;
  fb->status = status_working;
  fb->flag = 0;
  fb->string = NULL;
  fb->stringset = (char **)setadd ((void **)NULL, (module->module && module->module->rid) ? module->module->rid : module->si->provides[0], SET_TYPE_STRING);
  fb->integer = module->fbseq+1;
  status_update (fb);

  if (task & einit_module_custom) {
   if (strmatch (custom_command, "zap")) {
    char zerror = module->status & status_failed ? 1 : 0;
    fb->string = "module ZAP'd.";
    module->status = status_idle;
    module->status = status_disabled;
    if (zerror)
     module->status |= status_failed;
   } else if (module->custom) {
    module->status = module->custom(module->param, custom_command, fb);
   } else {
    module->status = (module->status & (status_enabled | status_disabled)) | status_failed | status_command_not_implemented;
   }
  } else if (task & einit_module_enable) {
    ret = module->enable (module->param, fb);
    if (ret & status_ok) {
     module->status = status_ok | status_enabled;
    } else {
     module->status = status_failed | status_disabled;
    }
  } else if (task & einit_module_disable) {
    ret = module->disable (module->param, fb);
    if (ret & status_ok) {
     module->status = status_ok | status_disabled;
    } else {
     module->status = status_failed | status_enabled;
    }
  }

  fb->status = module->status;
  module->fbseq = fb->integer + 1;

  status_update (fb);
//  event_emit(fb, einit_event_flag_broadcast);
//  if (fb->task & einit_module_feedback_show) fb->task ^= einit_module_feedback_show; fb->string = NULL;

/* module status update */
  {
   struct einit_event eem = evstaticinit (einit_core_module_update);
   eem.task = task;
   eem.status = fb->status;
   eem.para = (void *)module;
   eem.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0];
   event_emit (&eem, einit_event_flag_broadcast);
   evstaticdestroy (eem);

/* service status update */
   if (module->si && module->si->provides) {
    struct einit_event ees = evstaticinit (einit_core_service_update);
    ees.task = task;
    ees.status = fb->status;
    ees.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0];
    ees.set = (void **)module->si->provides;
    ees.para = (void *)module;
    event_emit (&ees, einit_event_flag_broadcast);
    evstaticdestroy (ees);
   }
  }

  free (fb->stringset);
  evdestroy (fb);

  service_usage_query(service_update, module, NULL);
  modules_work_count--;
 }

 if (!(task & einit_module_ignore_mutex))
  emutex_unlock (&module->mutex);

 return module->status;
}
예제 #21
0
파일: mbtx.c 프로젝트: MaxGekk/ZigZag
void    sys_init()
{
    event_emit( PRIORITY_HIGH, EV_MBREQ_DONE, (unidata_t)ENOERR );
    return;
}
void einit_feedback_visual_fbsplash_boot_event_handler(struct einit_event *ev) {
/* preinit */
 if ((ev->type == einit_boot_devices_available) && !(coremode & einit_mode_ipconly)) {
  if (einit_initial_environment) {
/* check for kernel params */
   uint32_t i = 0;
   char start_splash = 0, *ttypatch = NULL, *splashargs = NULL;

   for (; einit_initial_environment[i]; i++) {
    if (strstr (einit_initial_environment[i], "splash=") == einit_initial_environment[i]) {
     start_splash = 1;

     splashargs = einit_initial_environment[i]+7;

     if (!ttypatch)
      ttypatch = "tty1";
    } else if ((strstr (einit_initial_environment[i], "console=") == einit_initial_environment[i]) ||
               (strstr (einit_initial_environment[i], "einitty=") == einit_initial_environment[i])) {

     ttypatch = einit_initial_environment[i]+8;
    }
   }

   if (splashargs && *splashargs) {
    char *fbtheme = NULL/*, *fbmode = NULL*/;

    if (splashargs) {
     char **p = str2set (',', splashargs);
     if (p) {
      for (i = 0; p[i]; i++) {
       char *sep = strchr (p[i], ':');
       if (sep) {
        *sep = 0;
        sep++;
        if (strmatch (p[i], "theme")) {
         fbtheme = estrdup (sep);
        }
       }/* else {
        fbmode = estrdup(p[i]);
       }*/
      }
      free (p);
     }
    }

    if (fbtheme) {
     struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-fbsplash-theme", NULL);

     if (node && node->arbattrs) {
      uint32_t u = 0;
      for (; node->arbattrs[u]; u+=2) {
       if (strmatch(node->arbattrs[u], "s")) {
        notice (4, "patching fbsplash theme to %s", fbtheme);

        node->arbattrs[u+1] = fbtheme;
        node->svalue = fbtheme;
       }
      }
     }
    }
/*    if (fbmode) {
    }*/
   } else
    fbsplash_disabled = 1;

   if (ttypatch && *ttypatch) {
    struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-std-io", NULL);
    /* patch console */
    if (node && node->arbattrs) {
     uint32_t ri = 0;

     for (; node->arbattrs[ri]; ri+=2) {
      if (strmatch (node->arbattrs[ri], "stdio")) {
       char tx[BUFFERSIZE];

       if (ttypatch[0] == '/')
        esprintf (tx, BUFFERSIZE, "%s", ttypatch);
       else
        esprintf (tx, BUFFERSIZE, "/dev/%s", ttypatch);

       notice (4, "patching stdio output to go to %s", tx);

       node->arbattrs[ri+1] = estrdup(tx);
      } else if (strmatch (node->arbattrs[ri], "activate-vt")) {
       notice (4, "removing activate-vt= instruction");

       node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]);
       node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]);
      }
     }
    }
   }

   if (start_splash) {
    struct einit_event ee = evstaticinit(einit_core_change_service_status);

    ee.argv = (char **)setadd ((void **)ee.set, "splashd", SET_TYPE_STRING);
    ee.argv = (char **)setadd ((void **)ee.set, "enable", SET_TYPE_STRING);

    event_emit (&ee, einit_event_flag_broadcast);

    evstaticdestroy(ee);

    notice (4, "enabling feedack (fbsplash)");
    einit_feedback_visual_fbsplash_enable();
   }
  }
 }
}
예제 #23
0
파일: hblink.c 프로젝트: MaxGekk/ZigZag
void    atimer_fired( uint8_t    tnum ) 
{ 
    event_emit( EV_PRIORITY, EV_TYPE, EV_UNIDATA );
    return;
}
예제 #24
0
void linux_static_dev_load_kernel_extensions() {
    struct einit_event eml = evstaticinit(einit_boot_load_kernel_extensions);
    event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait);
    evstaticdestroy(eml);
}
예제 #25
0
파일: oled_app.c 프로젝트: MaxGekk/ZigZag
void    event_handler( event_type_t event_type, unidata_t   unidata ) 
{
   char str[32];
   unsigned char ch;
   static int err;
   
   switch(event_type)
   {
   case KBRD_EVT:
//      ltoa((int32_t)unidata, str, 10);
//      OLED_puts(0, 41, 0xff, font6x9, str);
     
      if(kbrd_pressed)
      {
         kbrd_pressed = 0;
         //display_node(kbrd_getch());
         ch = kbrd_getch();
         /*
      itoa((int16_t)ch, str, 16);
      OLED_clr(0, 41, 3 * 6, 9);
      OLED_puts(0, 41, 0xff, font6x9, str);
         */
         if(!(ch & 0x80))
         {
            ch = active.menu->action(ch);
            active.menu->display(ch);
            update_statusbar();
         }
         /*
         switch((ch = kbrd_getch()))
         {
         case 1:
         case 129:
            display(0, 0);
            break;
         case 16:
         case 144:
            display(1, 0);
            break;
         case 14:
            if((scroll_pos < (MSG_TABLE_SIZE - MSG_VIEW_SIZE)) && (scroll_pos < msg_count - 1))
            {
               scroll_pos ++;
               event_emit(LOW_PRIORITY, DISPLAY_EVT, 2);
            }
         case 142:
            break;
         case 13:
            if(scroll_pos)
            {
               scroll_pos--;
               event_emit(LOW_PRIORITY, DISPLAY_EVT, 2);
            }
         case 141:
            break;
         case 11:
            OLED_cls();
            err = initConfig();
            //sprintf(str, "initConfig res: %d", err);
            //OLED_puts(0, 0, 0xff, font6x9, str);
            OLED_puts(0, 0, 0xff, font6x9, (err ? "initConfig failed" : "initConfig success"));
            break;
         case 134:
            {
               struct LogEntry entry;
               
               err = STRG_SUCCESS;
               entry.timestamp  = 0;
               err += logAddEntry(&entry, "Msg 0");
               entry.timestamp  = 1000;
               err += logAddEntry(&entry, "Msg 1");
               entry.timestamp  = 2000;
               err += logAddEntry(&entry, "Msg 2");
               sprintf(str, "Error code: %d", err);
               OLED_puts(0, 2*9, 0xff, font6x9, str);
            }
            break;
         default:
            display(2, ch);
            break; // display(0, 0);
         }
         */
         
         /*
         OLED_puts(64 + 12, 41, 0xff, font6x9, "Key pressed ");
         itoa(kbrd_getch(), str, 10);
         OLED_puts(64 + 12 + sizeof("Key pressed ") * 6, 41, 0xff, font6x9, str);
         OLED_puts(64 + 12 + sizeof("Key pressed ") * 6 + strlen(str) * 6, 41, 0xff, font6x9, "   ");
         */
      }
      /*
      else
         OLED_puts(0, 41, 0xff, font6x9, "Key not pressed");
         */
      break;

   case INIT_EVT:
      //OLED_init();
      //init_kbrd();
      SPI_init();
      event_emit(LOW_PRIORITY, INIT_MMC_EVT, 0);
      break;

   case INIT_MMC_EVT:
      initMMC();
      err = initStorage();
      event_emit(LOW_PRIORITY, INIT_OLED_EVT, 0);
      break;

   case INIT_OLED_EVT:
      OLED_init();
      OLED_puts(0, 0 , 0xff, font6x9, "System initialization...");
      OLED_puts(0, 1 * 9 , 0xff, font6x9, "SPI     init'ed.");
      OLED_puts(0, 2 * 9 , 0xff, font6x9, "MMC     init'ed.");
      OLED_puts(0, 3 * 9 , 0xff, font6x9, "OLED    init'ed.");
      event_emit(LOW_PRIORITY, INIT_STORAGE_EVT, 0);
      break;

   case INIT_STORAGE_EVT:
      //err = initStorage();
      //OLED_puts(0, 4 * 9 , 0xff, font6x9, err ? "Storage init failed!" : "Storage init'ed.");
      format_str(str, 32, "Storage err: %d", err);
      OLED_puts(0, 4 * 9 , 0xff, font6x9, err ? str : "Storage init'ed.");
      /*
      format_str(str, 32, "ZoneCfg pos: %u", syscfg.zone_cfg_addr);
      OLED_puts(0, 5 * 9 , 0xff, font6x9, str);
      err = 1;
      */
      event_emit(LOW_PRIORITY, INIT_USER_IO_EVT, 0);
      break;

   case INIT_USER_IO_EVT:
      init_kbrd();
      menu_init(err ? MNU_INIT | MNU_DO_NOT_SHOW : MNU_INIT);
      //set_sys_time((uint64_t)20000);
      stimer_set(1, 1000);
      break;
   }
       /*
   else if(event_type == INIT_SEND_MSGS_EVT)
   {
       msg_t msg;
       struct msginfo minfo;

       uint16_t addr_attr = 0x0000;
       uint8_t  port_attr = PORT;

       //attr_write(0x02, &addr_attr);
       //attr_write(0x07, &port_attr);

       // This must be the code for us to say ZigZag (Node Dispatcher)
       // that we are interested in listening for messages and events
       msg = msg_new(0x00, 0x00, 0x01, 3, MFLAG_DEFAULT);
       if(msg < 0)
          OLED_puts(0, 0, 0xff, font6x9, "Error: msg_new");
       if(msg_info(msg, &minfo) != ENOERR)
          OLED_puts(0, 9, 0xff, font6x9, "Error: msg_info");
       ((unsigned char *)minfo.body_ptr)[0] = 0x02;
       ((unsigned char *)minfo.body_ptr)[1] = 0x00;
       ((unsigned char *)minfo.body_ptr)[2] = 0x00;
       if(msg_send(msg) != ENOERR)
          OLED_puts(0, 18, 0xff, font6x9, "Error: msg_send (1)");
       msg = msg_new(0x00, 0x00, 0x01, 2, MFLAG_DEFAULT);
       if(msg < 0)
          OLED_puts(0, 0, 0xff, font6x9, "Error: msg_new");
       if(msg_info(msg, &minfo) != ENOERR)
          OLED_puts(0, 9, 0xff, font6x9, "Error: msg_info");
       ((unsigned char *)minfo.body_ptr)[0] = 0x07;
       ((unsigned char *)minfo.body_ptr)[1] = (uint8_t)PORT;
//       ((unsigned char *)minfo.body_ptr)[2] = (uint8_t)(PORT >> 8);
       if(msg_send(msg) != ENOERR)
          OLED_puts(0, 18, 0xff, font6x9, "Error: msg_send (2)");
   }
          */
   /*
   else
   {
      //sprintf(str, "Evt: %u", (uint16_t)event_type);
      //OLED_puts(0, 0, 0xff, font6x9, str);
   }
   */
}
예제 #26
0
int main(int argc, char **argv, char **environ) {
#else
int main(int argc, char **argv) {
#endif
 int i, ret = EXIT_SUCCESS;
 pid_t pid = getpid(), wpid = 0;
 char **ipccommands = NULL;
 int pthread_errno;
 FILE *commandpipe_in, *commandpipe_out;
 int commandpipe[2];
 int debugsocket[2];
 char need_recovery = 0;
 char debug = 0;
 int debugme_pipe = 0;
 char crash_threshold = 5;
 char *einit_crash_data = NULL;

 boottime = time(NULL);

 uname (&osinfo);
 config_configure();

// initialise subsystems
 ipc_configure(NULL);

// is this the system's init-process?
 isinit = getpid() == 1;

 event_listen (einit_event_subsystem_core, core_einit_event_handler);
 event_listen (einit_event_subsystem_timer, core_timer_event_handler);

 if (argv) einit_argv = (char **)setdup ((const void **)argv, SET_TYPE_STRING);

/* check command line arguments */
 for (i = 1; i < argc; i++) {
  if (argv[i][0] == '-')
   switch (argv[i][1]) {
    case 'c':
     if ((++i) < argc)
      einit_default_startup_configuration_files[0] = argv[i];
     else
      return print_usage_info ();
     break;
    case 'h':
     return print_usage_info ();
     break;
    case 'v':
     eputs("eINIT " EINIT_VERSION_LITERAL "\n", stdout);
     return 0;
    case 'L':
     eputs("eINIT " EINIT_VERSION_LITERAL
          "\nThis Program is Free Software, released under the terms of this (BSD) License:\n"
          "--------------------------------------------------------------------------------\n"
          "Copyright (c) 2006, 2007, Magnus Deininger\n"
          BSDLICENSE "\n", stdout);
     return 0;
    case '-':
     if (strmatch(argv[i], "--check-configuration") || strmatch(argv[i], "--checkup") || strmatch(argv[i], "--wtf")) {
      ipccommands = (char **)setadd ((void **)ipccommands, "examine configuration", SET_TYPE_STRING);
     } else if (strmatch(argv[i], "--help"))
      return print_usage_info ();
     else if (strmatch(argv[i], "--ipc-command") && argv[i+1])
      ipccommands = (char **)setadd ((void **)ipccommands, (void *)argv[i+1], SET_TYPE_STRING);
     else if (strmatch(argv[i], "--override-init-check"))
      initoverride = 1;
     else if (strmatch(argv[i], "--sandbox")) {
      einit_default_startup_configuration_files[0] = "lib/einit/einit.xml";
      coremode = einit_mode_sandbox;
      need_recovery = 1;
     } else if (strmatch(argv[i], "--metadaemon")) {
      coremode = einit_mode_metadaemon;
     } else if (strmatch(argv[i], "--bootstrap-modules")) {
      bootstrapmodulepath = argv[i+1];
     } else if (strmatch(argv[i], "--debugme")) {
      debugme_pipe = parse_integer (argv[i+1]);
      i++;
      initoverride = 1;
     } else if (strmatch(argv[i], "--debug")) {
      debug = 1;
     }

     break;
   }
 }

/* check environment */
 if (environ) {
  uint32_t e = 0;
  for (e = 0; environ[e]; e++) {
   char *ed = estrdup (environ[e]);
   char *lp = strchr (ed, '=');

   *lp = 0;
   lp++;

   if (strmatch (ed, "softlevel")) {
    einit_startup_mode_switches = str2set (':', lp);
   } if (strmatch (ed, "mode")) {
/* override default mode-switches with the ones in the environment variable mode= */
    einit_startup_mode_switches = str2set (':', lp);
   } else if (strmatch (ed, "einit")) {
/* override default configuration files and/or mode-switches with the ones in the variable einit= */
    char **tmpstrset = str2set (',', lp);
    uint32_t rx = 0;

    for (rx = 0; tmpstrset[rx]; rx++) {
     char **atom = str2set (':', tmpstrset[rx]);

     if (strmatch (atom[0], "file")) {
/* specify configuration files */
      einit_startup_configuration_files = (char **)setdup ((const void **)atom, SET_TYPE_STRING);
      einit_startup_configuration_files = (char **)strsetdel (einit_startup_configuration_files, (void *)"file");
     } else if (strmatch (atom[0], "mode")) {
/* specify mode-switches */
      einit_startup_mode_switches = (char **)setdup ((const void **)atom, SET_TYPE_STRING);
      einit_startup_mode_switches = (char **)strsetdel (einit_startup_mode_switches, (void *)"mode");
     } else if (strmatch (atom[0], "stfu")) {
      einit_quietness = 3;
     } else if (strmatch (atom[0], "silent")) {
      einit_quietness = 2;
     } else if (strmatch (atom[0], "quiet")) {
      einit_quietness = 1;
     }

     free (atom);
    }

    free (tmpstrset);
   }

   free (ed);
  }

  einit_initial_environment = (char **)setdup ((const void **)environ, SET_TYPE_STRING);
 }

 if (!einit_startup_mode_switches) einit_startup_mode_switches = einit_default_startup_mode_switches;
 if (!einit_startup_configuration_files) einit_startup_configuration_files = einit_default_startup_configuration_files;

 respawn:

 pipe (commandpipe);

 fcntl (commandpipe[1], F_SETFD, FD_CLOEXEC);

 socketpair (AF_UNIX, SOCK_STREAM, 0, debugsocket);
 fcntl (debugsocket[0], F_SETFD, FD_CLOEXEC);
 fcntl (debugsocket[1], F_SETFD, FD_CLOEXEC);

 if (!debug) {
  fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC);
  commandpipe_in = fdopen (commandpipe[0], "r");
 }
 commandpipe_out = fdopen (commandpipe[1], "w");

 if (!initoverride && ((pid == 1) || ((coremode & einit_mode_sandbox) && !ipccommands))) {
// if (pid == 1) {
  initoverride = 1;
#if 0
#ifdef LINUX
  if ((einit_sub = syscall(__NR_clone, CLONE_PTRACE | SIGCHLD, 0, NULL, NULL, NULL)) < 0) {
   bitch (bitch_stdio, errno, "Could not fork()");
   eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr);
  }
#else
#endif
#endif
  if ((einit_sub = fork()) < 0) {
   bitch (bitch_stdio, errno, "Could not fork()");
   eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr);
  }
 }

 if (einit_sub) {
/* PID==1 part */
  int rstatus;
  struct sigaction action;

/* signal handlers */
  action.sa_sigaction = einit_sigint;
  sigemptyset(&(action.sa_mask));
  action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
  if ( sigaction (SIGINT, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed.");

/* ignore sigpipe */
  action.sa_sigaction = (void (*)(int, siginfo_t *, void *))SIG_IGN;

  if ( sigaction (SIGPIPE, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed.");

  close (debugsocket[1]);
  if (einit_crash_data) {
   free (einit_crash_data);
   einit_crash_data = NULL;
  }

  while (1) {
   wpid = waitpid(-1, &rstatus, 0); /* this ought to wait for ANY process */

   if (wpid == einit_sub) {
//    goto respawn; /* try to recover by re-booting */
    if (!debug) if (commandpipe_in) fclose (commandpipe_in);
    if (commandpipe_out) fclose (commandpipe_out);

    if (WIFEXITED(rstatus) && (WEXITSTATUS(rstatus) != einit_exit_status_die_respawn)) {
     fprintf (stderr, "eINIT has quit properly.\n");

     if (!(coremode & einit_mode_sandbox)) {
      if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_halt) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "h", NULL);
      } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_reboot) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "r", NULL);
      } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_kexec) {
       execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "k", NULL);
      }
     }

     exit (EXIT_SUCCESS);
    }

    int n = 5;
    fprintf (stderr, "The secondary eINIT process has died, waiting a while before respawning.\n");
    if ((einit_crash_data = readfd (debugsocket[0]))) {
     fprintf (stderr, " > neat, received crash data\n");
    }
    while ((n = sleep (n)));
    fprintf (stderr, "Respawning secondary eINIT process.\n");

    if (crash_threshold) crash_threshold--;
    else debug = 1;
    need_recovery = 1;
    initoverride = 0;

    close (debugsocket[0]);

    goto respawn;
   } else {
    if (commandpipe_out) {
     if (WIFEXITED(rstatus)) {
      fprintf (commandpipe_out, "pid %i terminated\n\n", wpid);
     } else {
      fprintf (commandpipe_out, "pid %i died\n\n", wpid);
     }
     fflush (commandpipe_out);
    }
   }
  }
 } else {
  enable_core_dumps ();

  close (debugsocket[0]);
  sched_trace_target = debugsocket[1];

  if (debug) {
   char **xargv = (char **)setdup ((const void **)argv, SET_TYPE_STRING);
   char tbuffer[BUFFERSIZE];
   struct stat st;
   char have_valgrind = 0;
   char have_gdb = 0;

   fputs ("eINIT needs to be debugged, starting in debugger mode\n.", stderr);

   xargv = (char **)setadd ((void **)xargv, (void *)"--debugme", SET_TYPE_STRING);
   snprintf (tbuffer, BUFFERSIZE, "%i", commandpipe[0]);
   xargv = (char **)setadd ((void **)xargv, (void *)tbuffer, SET_TYPE_STRING);

   xargv = strsetdel (xargv, "--debug"); // don't keep the --debug flag

   if (!stat ("/usr/bin/valgrind", &st)) have_valgrind = 1;
   if (!stat ("/usr/bin/gdb", &st)) have_gdb = 1;

   if (have_valgrind) {
    char **nargv = NULL;
    uint32_t i = 1;

#ifdef LINUX
    if (!(coremode & einit_mode_sandbox)) {
     mount ("proc", "/proc", "proc", 0, NULL);
     mount ("sys", "/sys", "sysfs", 0, NULL);

     system ("mount / -o remount,rw");
    }
#endif

    nargv = (char **)setadd ((void **)nargv, "/usr/bin/valgrind", SET_TYPE_STRING);
    nargv = (char **)setadd ((void **)nargv, "--log-file=/einit.valgrind", SET_TYPE_STRING);
    nargv = (char **)setadd ((void **)nargv, (coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", SET_TYPE_STRING);

    for (; xargv[i]; i++) {
     nargv = (char **)setadd ((void **)nargv, xargv[i], SET_TYPE_STRING);
    }

    execv ("/usr/bin/valgrind", nargv);
   } else {
    execv ((coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", xargv);
   }
  }

  if (debugme_pipe) { // commandpipe[0]
   fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC);
   commandpipe_in = fdopen (debugme_pipe, "r");
  }

/* actual system initialisation */
  struct einit_event cev = evstaticinit(einit_core_update_configuration);

  if (ipccommands && (coremode != einit_mode_sandbox)) {
   coremode = einit_mode_ipconly;
  }

  eprintf (stderr, "eINIT " EINIT_VERSION_LITERAL ": Initialising: %s\n", osinfo.sysname);

  if ((pthread_errno = pthread_attr_init (&thread_attribute_detached))) {
   bitch(bitch_epthreads, pthread_errno, "pthread_attr_init() failed.");

   if (einit_initial_environment) free (einit_initial_environment);
   return -1;
  } else {
   if ((pthread_errno = pthread_attr_setdetachstate (&thread_attribute_detached, PTHREAD_CREATE_DETACHED))) {
    bitch(bitch_epthreads, pthread_errno, "pthread_attr_setdetachstate() failed.");
   }
  }

  if ((pthread_errno = pthread_key_create(&einit_function_macro_key, NULL))) {
   bitch(bitch_epthreads, pthread_errno, "pthread_key_create(einit_function_macro_key) failed.");

   if (einit_initial_environment) free (einit_initial_environment);
   return -1;
  }

/* this should be a good place to initialise internal modules */
   if (coremodules) {
    uint32_t cp = 0;

    eputs (" >> initialising in-core modules:", stderr);

    for (; coremodules[cp]; cp++) {
     struct lmodule *lmm;
     eprintf (stderr, " [%s]", (*coremodules[cp])->rid);
     lmm = mod_add(NULL, (*coremodules[cp]));

     lmm->source = estrdup("core");
    }

    eputs (" OK\n", stderr);
   }

/* emit events to read configuration files */
  if (einit_startup_configuration_files) {
   uint32_t rx = 0;
   for (; einit_startup_configuration_files[rx]; rx++) {
    cev.string = einit_startup_configuration_files[rx];
    event_emit (&cev, einit_event_flag_broadcast);
   }

   if (einit_startup_configuration_files != einit_default_startup_configuration_files) {
    free (einit_startup_configuration_files);
   }
  }

  cev.string = NULL;
  cev.type = einit_core_configuration_update;

// make sure we keep updating until everything is sorted out
  while (cev.type == einit_core_configuration_update) {
//   notice (2, "stuff changed, updating configuration.");

   cev.type = einit_core_update_configuration;
   event_emit (&cev, einit_event_flag_broadcast);
  }
  evstaticdestroy(cev);

  if (ipccommands) {
   uint32_t rx = 0;
   for (; ipccommands[rx]; rx++) {
    ret = ipc_process (ipccommands[rx], stdout);
   }

//   if (gmode == EINIT_GMODE_SANDBOX)
//    cleanup ();

   free (ipccommands);
   if (einit_initial_environment) free (einit_initial_environment);
   return ret;
  } else if ((coremode == einit_mode_init) && !isinit && !initoverride) {
   eputs ("WARNING: eINIT is configured to run as init, but is not the init-process (pid=1) and the --override-init-check flag was not specified.\nexiting...\n\n", stderr);
   exit (EXIT_FAILURE);
  } else {
/* actual init code */
   uint32_t e = 0;

   nice (einit_core_niceness_increment);

   if (need_recovery) {
    notice (1, "need to recover from something...");

    struct einit_event eml = evstaticinit(einit_core_recover);
    event_emit (&eml, einit_event_flag_broadcast);
    evstaticdestroy(eml);
   }

   if (einit_crash_data) {
    notice (1, "submitting crash data...");

    struct einit_event eml = evstaticinit(einit_core_crash_data);
    eml.string = einit_crash_data;
    event_emit (&eml, einit_event_flag_broadcast);
    evstaticdestroy(eml);

    free (einit_crash_data);
    einit_crash_data = NULL;
   }

   {
    notice (3, "running early bootup code...");

    struct einit_event eml = evstaticinit(einit_boot_early);
    event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait);
    evstaticdestroy(eml);
   }

   notice (2, "scheduling startup switches.\n");

   for (e = 0; einit_startup_mode_switches[e]; e++) {
    struct einit_event ee = evstaticinit(einit_core_switch_mode);

    ee.string = einit_startup_mode_switches[e];
    event_emit (&ee, einit_event_flag_broadcast | einit_event_flag_spawn_thread | einit_event_flag_duplicate);
    evstaticdestroy(ee);
   }

   struct einit_event eml = evstaticinit(einit_core_main_loop_reached);
   eml.file = commandpipe_in;
   event_emit (&eml, einit_event_flag_broadcast);
   evstaticdestroy(eml);
  }

  if (einit_initial_environment) free (einit_initial_environment);
  return ret;
 }

/* this should never be reached... */
 if (einit_initial_environment) free (einit_initial_environment);
 return 0;
}
예제 #27
0
void core_einit_event_handler (struct einit_event *ev) {
 if (ev->type == einit_core_configuration_update) {
  struct cfgnode *node;
  char *str;

  ev->chain_type = einit_core_update_modules;

  if ((node = cfg_getnode ("core-mortality-bad-malloc", NULL)))
   mortality[bitch_emalloc] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-stdio", NULL)))
   mortality[bitch_stdio] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-regex", NULL)))
   mortality[bitch_regex] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-expat", NULL)))
   mortality[bitch_expat] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-dl", NULL)))
   mortality[bitch_dl] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-lookup", NULL)))
   mortality[bitch_lookup] = node->value;

  if ((node = cfg_getnode ("core-mortality-bad-pthreads", NULL)))
   mortality[bitch_epthreads] = node->value;

  if ((node = cfg_getnode ("core-settings-allow-code-unloading", NULL)))
   einit_allow_code_unloading = node->flag;

  if ((str = cfg_getstring ("core-scheduler-niceness/core", NULL)))
   einit_core_niceness_increment = parse_integer (str);

  if ((str = cfg_getstring ("core-scheduler-niceness/tasks", NULL)))
   einit_task_niceness_increment = parse_integer (str);
 } else if (ev->type == einit_core_update_modules) {
  struct lmodule *lm;

  repeat:

  lm = mlist;
  einit_new_node = 0;

  while (lm) {
   if (lm->source && strmatch(lm->source, "core")) {
    lm = mod_update (lm);

// tell module to scan for changes if it's a module-loader
    if (lm->module && (lm->module->mode & einit_module_loader) && (lm->scanmodules != NULL)) {
     notice (8, "updating modules (%s)", lm->module->rid ? lm->module->rid : "unknown");

     lm->scanmodules (mlist);

/* if an actual new node has been added to the configuration,
   repeat this step */
     if (einit_new_node) goto repeat;
    }

   }
   lm = lm->next;
  }

/* give the module-logic code and others a chance at processing the current list */
  struct einit_event update_event = evstaticinit(einit_core_module_list_update);
  update_event.para = mlist;
  event_emit (&update_event, einit_event_flag_broadcast);
  evstaticdestroy(update_event);
 } else if (ev->type == einit_core_recover) { // call everyone's recover-function (if defined)
  struct lmodule *lm = mlist;

  while (lm) {
   if (lm->recover) {
    lm->recover (lm);
   }

   lm = lm->next;
  }
 } else if (ev->type == einit_core_suspend_all) { // suspend everyone (if possible)
  struct lmodule *lm = mlist;
  int ok = 0;

  while (lm) {
   ok += (mod (einit_module_suspend, lm, NULL) == status_ok) ? 1 : 0;

   lm = lm->next;
  }

  if (ok)
   notice (4, "%i modules suspended", ok);

  event_snooze_time = event_timer_register_timeout(60);
 } else if (ev->type == einit_core_resume_all) { // resume everyone (if necessary)
  struct lmodule *lm = mlist;
  int ok = 0;

  while (lm) {
   ok += (mod (einit_module_resume, lm, NULL) == status_ok) ? 1 : 0;

   lm = lm->next;
  }

  if (ok)
   notice (4, "%i available", ok);
 }
}