Пример #1
0
void main_final(void) {

    init_nick();
	if(GLOBAL(privacy)>2){ //firstboot
        execute_file("initanim.int");
        if(execute_file("1boot.int")){
            lcdPrintln("Badge SETUP");
            lcdPrintln("error.");
            lcdPrintln("Features may");
            lcdPrintln("be broken.");
            lcdRefresh();
            getInputWait();
            getInputWaitRelease();
            GLOBAL(privacy)=0;
        }else{
            saveConfig();
        };
    };
    //checkFirstBoot();
    init_final();
    menuflags|=MENU_TIMEOUT;

    while(1){
        if(GLOBAL(develmode))
            if(getInputRaw()==BTN_LEFT)
                ISPandReset();
        if(getInput()){
            handleMenu(&mainmenu);
            getInputWaitRelease();
            init_nick();
        };
        work_queue();
        fancyNickname();
    };
}
Пример #2
0
int init_plugin_from_file(Plugin *plugin, const char *path, const char *plugin_name)
{
  int fds[2], flags, buffer_size, n;
  
  printf("Loading plugin %s...\n", path);
  plugin->mrb = mrb_open_allocf(profiler_allocf, (void *)path);
  setup_api(plugin->mrb);
  execute_file(plugin->mrb, path);
  execute_file(plugin->mrb, config_path);
  
  C_CHECK("socketpair", socketpair(PF_UNIX, SOCK_DGRAM, 0, fds));
  
  buffer_size = PIPE_BUFFER_SIZE;
  n = sizeof(buffer_size);
  C_CHECK("setsockopt 0 snd", setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 0 rcv", setsockopt(fds[0], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  flags = fcntl(fds[0], F_GETFL);
  flags |= O_NONBLOCK;
  if( fcntl(fds[0], F_SETFL, flags) == -1 ){
    perror("fcntl");
    return -1;
  }
  
  
  plugin->host_pipe = fds[0];
  plugin->plugin_pipe = wrap_io(plugin->mrb, fds[1], "w");
  strncpy(plugin->name, plugin_name, sizeof(plugin->name) - 1);
  
  // set ivs
  // struct RClass *rprobe = mrb_class_get(plugin->mrb, "D3Probe");
  // mrb_value probe_klass = mrb_obj_value(rprobe);
  mrb_sym plugin_iv_sym = mrb_intern_cstr(plugin->mrb, "@plugin");
  
  plugin->plugin_obj = mrb_iv_get(plugin->mrb, mrb_obj_value(plugin->mrb->top_self), plugin_iv_sym);
  // pp(plugin->mrb, plugin->plugin_obj, 0);
  
  // associates the c structure with the ruby object
  DATA_PTR(plugin->plugin_obj)  = (void*)plugin;
  
  mrb_funcall(plugin->mrb, plugin->plugin_obj, "after_config", 0);
  check_exception("after_config", plugin->mrb);
  
  return 0;
}
Пример #3
0
void executeSelect(const char *ext){
    char filename[FLEN];

    if( selectFile(filename,ext) >= 0){
        if(execute_file(filename)!=0){
            getInputWait();
        };
    };
}
Пример #4
0
void executeSelect(const char *ext){
    char filename[15];
    filename[0]='0';
    filename[1]=':';
    filename[2]=0;

    if( selectFile(filename+2,ext) == 0)
        execute_file(filename);
};
Пример #5
0
int main(int argc, char **argv)
{
 //PyImport_AppendInittab((char*)("mpi"), &initmpi);
 PyImport_AppendInittab((char*)("_testarray"), &init_testarray);
 Py_Initialize(); // init the interpreter
 triqs::arrays::register_boost_converters();
 execute_file ( (std::string(AS_STRING(SOURCE_DIR)) + std::string("/test.py")).c_str() ) ;
 // now start the interpreter main loop and start executing the commands given to the new interpreter...
 //  Py_Main(argc,argv);
}
Пример #6
0
//# MENU config
void changer(void){
    if(execute_file("config.int")){
        lcdClear();
        lcdPrintln("config");
        lcdPrintln("l0dable");
        lcdPrintln("not found");
        lcdRefresh();
        getInputWait();
        getInputWaitRelease();
    }
}
Пример #7
0
void fancyNickname(void) {
    if(GLOBAL(l0nick)){
        if(execute_file(GLOBAL(nickl0)))
            GLOBAL(l0nick)=0;
        setTextColor(0xFF,0x00);
    }

    if(!GLOBAL(l0nick))
        simpleNickname();
    return;
}
Пример #8
0
// Main function
int main(int argc, char const *argv[]) {
  char input[MAX_LINE]; // input string
  char **cmd_argv;      // parsed arguments
  int cmd_argc;         // arguments number
  bool cmd_found;       // flag to indicate if command is found

  // Print initial help message
  cmd_help.execute(1,&(cmd_help.cmd));
  update_current_dir();

  // Main superloop
  while(true) {
    // Read command from input stream
    printf("[%s]%c ", current_dir, INVITE_CHAR);
    gets(input);

    // Parse input stream
    cmd_argv = parse(input, ARG_SEPARATOR, &cmd_argc);
    remove_empty_or_whitespace(&cmd_argv, &cmd_argc);
    if (cmd_argc == 0) continue;

    // Search for appropriate built-in command and execute it
    cmd_found = false;
    for (int i = 0; i < commands_count; ++i) {
      if (strcmp(cmd_argv[0],commands[i]->cmd) == 0) {
        cmd_found = true;
        commands[i]->execute(cmd_argc, cmd_argv);
        break;
      }
    }

    // Search for appropriate executable file and execute it
    if (!cmd_found) {
      if (is_exe_file(cmd_argv[0])) {
        cmd_found = true;
        execute_file(cmd_argc, cmd_argv);
      }
    }

    // Error message, if command not found
    if (!cmd_found) {
      fprintf(stderr, "Error: \"%s\" command not found!\n", cmd_argv[0]);
    }

    // Release resources
    free_strs(cmd_argv, cmd_argc);
  }
  return EXIT_SUCCESS;
}
Пример #9
0
int NerveTool::execute( int nargs , char **args ) {
	// parameters
	String url;
	String fin;
	String fout;
	for( int k = 0; k < nargs; k++ ) {
		String arg = args[ k ];
		if( arg.equals( "-i" ) ) {
			fin = args[ ++k ];
			continue;
		}

		if( arg.equals( "-o" ) ) {
			fout = args[ ++k ];
			continue;
		}

		printf( "unknown option: %s\n" , args[ k ] );
		return( -1 );
	}

	FILE *sin = NULL;
	if( !fin.isEmpty() ) {
		sin = fopen( fin , "rt" );
		if( sin == NULL ) {
			printf( "cannot open input file (%s)\n" , ( const char * )fin );
			return( -2 );
		}
	}

	FILE *sout = NULL;
	if( !fout.isEmpty() ) {
		sout = fopen( fout , "at" );
		if( sout == NULL ) {
			printf( "cannot open output file (%s)\n" , ( const char * )fout );
			return( -2 );
		}
	}

	execute_file( sin , sout );

	if( sin != NULL )
		fclose( sin );
	if( sout != NULL )
		fclose( sout );

	return( 0 );
}
Пример #10
0
ehval_p EHI::execute_named_file(const char *name) {
	// prevent including the same file more than once
	std::set<std::string> &included = parent->included_files;
	if(included.count(name) > 0) {
		return nullptr;
	}
	included.insert(name);

	// after this check, actually execute the file
	FILE *infile = fopen(name, "r");
	if(infile == nullptr) {
		throw_ArgumentError("Could not open input file", "EH core", String::make(strdup(name)), this);
	}
	ehval_p out = execute_file(infile);
	fclose(infile);
	return out;
}
Пример #11
0
void parse(char *line)
{
	char *str = strtok(line," ");
	char *arguments = strtok(NULL,"");
	if(!strcmp(str,"cd"))
		function_cd(arguments);
	else if(!strcmp(str,"pwd"))
		function_pwd(arguments);
	else if(!strcmp(str,"echo"))
		function_echo(arguments);
	else if(!strcmp(str,"exit"))
		function_exit(arguments);
	else if(!strcmp(str,"env"))
		function_env(arguments);
	else if(!strcmp(str,"setenv"))
		function_setenv(arguments);
	else if(execute_file(str,arguments));
	else printf("Invalid Command!\n");
}
Пример #12
0
int main(int argc, char *argv[]) {
	char *s;
	main_argv = argv;
	main_argc = argc;
	if (argc >= 2 && !strcmp(argv[1], "-t")) {
		timing_info = 1;
		s = argv[2];
	} else if (argc > 1) {
		s = argv[1];
	} else
		s = REPL_FILE;
	gettimeofday(&launch_time,NULL);
	init_scheme(HEAPSIZE,STACKSIZE,CODESIZE);
	define("system:*search-path*",list1(make_string(schemelib)));
	define("system:*repl-filename*",make_string(s));
	execute_file(BOOT_FILE);
	quit(0);
	return 0;
}
Пример #13
0
static void execute(const char *fn,const char *def)
     /* Load and execute a qmail command file. */
{
  stralloc file = {0,0,0};
  int code;
  if (def != 0)
    env_put2("DEFAULT",def);
  else
    env_unset("DEFAULT");
  if (slurp(fn,&file,256) != 1)
    strerr_die6sys(111,FATAL,ERR_READ_INPUT,basedir.s,"/",fn,": ");
  code = execute_file(fn,&file);
  substdio_puts(subfderr,"did 0+");
  substdio_put(subfderr,strnum,fmt_ulong(strnum,did_forward));
  substdio_puts(subfderr,"+");
  substdio_put(subfderr,strnum,fmt_ulong(strnum,did_program));
  substdio_putsflush(subfderr,"\n");
  _exit(code);
}
Пример #14
0
static void
handle_file(FileView *view, FileHandleExec exec, FileHandleLink follow)
{
	char full_path[PATH_MAX];
	int executable;
	int runnable;
	const dir_entry_t *const curr = &view->dir_entry[view->list_pos];

	get_full_path_of(curr, sizeof(full_path), full_path);

	if(is_dir(full_path) || is_unc_root(view->curr_dir))
	{
		if(!curr->selected && (curr->type != FT_LINK || follow == FHL_NO_FOLLOW))
		{
			open_dir(view);
			return;
		}
	}

	runnable = is_runnable(view, full_path, curr->type, follow == FHL_FOLLOW);
	executable = is_executable(full_path, curr, exec == FHE_NO_RUN, runnable);

	if(stats_file_choose_action_set() && (executable || runnable))
	{
		/* The call below does not return. */
		vifm_choose_files(view, 0, NULL);
	}

	if(executable && !is_dir_entry(full_path, curr->type))
	{
		execute_file(full_path, exec == FHE_ELEVATE_AND_RUN);
	}
	else if(runnable)
	{
		run_selection(view, exec == FHE_NO_RUN);
	}
	else if(curr->type == FT_LINK)
	{
		follow_link(view, follow == FHL_FOLLOW);
	}
}
Пример #15
0
int main(int argc,char *argv[])
# define CALL_MAIN main
#endif
{
   tsd_t *TSD;
   int processed;
   int compile_to_tokens=0;
   int execute_from_tokens=0;
   int locale_set=0;
   int stdinput, rcode;
   jmp_buf jbuf;

#ifdef MAC
   InitCursorCtl( nil );
#endif

   if ( argv0 == NULL )
      argv0 = GetArgv0( argv[0] );

   TSD = GLOBAL_ENTRY_POINT();

   setup_system( TSD, 0 );

   if ( setjmp( jbuf ) )
   {
      /*
       * We may either be jumped normally after an EXIT instruction or after
       * an error. The first reason means normal continuation, the other
       * means that we have to do an immediate stop.
       */
      if ( !TSD->instore_is_errorfree )
      {
         if ( TSD->systeminfo->result )
            return atoi( TSD->systeminfo->result->value );
         return -1;
      }
      else
      {
         if ( TSD->systeminfo->result )
            rcode = codeFromString( TSD, TSD->systeminfo->result );
         else
            rcode = EXIT_SUCCESS;
      }
   }
   else
   {
      TSD->systeminfo->script_exit = &jbuf;

      processed = check_args( TSD, argc, argv, &compile_to_tokens,
                              &execute_from_tokens, &locale_set );

      if ( processed == 0 )
         return 0;

      if ( !locale_set )
      {
         /*
          * Check for a comma separated default locale in REGINA_LANG.
          */
         char *ptr = getenv( "REGINA_LANG" );
         if ( ptr )
            ptr = strchr( ptr, ',' );
         if ( ptr )
            set_locale_info( ptr + 1 );
      }

      if ( processed < argc )
      {
         stdinput = 0;
         TSD->systeminfo->input_file = get_external_routine( TSD,
                                argv[processed], &TSD->systeminfo->input_fp );
         if ( !TSD->systeminfo->input_file )
         {
            TSD->systeminfo->input_file = Str_crestrTSD( argv[processed] );
            exiterror( ERR_PROG_UNREADABLE, 1, "Program was not found" );
         }
         processed++;
      }
      else
      {
         stdinput = 1;
         TSD->systeminfo->input_file = Str_crestrTSD( "<stdin>" );
         TSD->systeminfo->input_fp = NULL;
         if ( compile_to_tokens )
            exiterror( ERR_PROG_UNREADABLE, 1, "Too few arguments when "
                                "tokenising. Usage: -c inputfile outputfile" );
         if ( execute_from_tokens )
            exiterror( ERR_PROG_UNREADABLE, 1, "Cannot run tokenised code "
                                                               "from stdin." );
      }


      /*
       * -c switch specified - tokenise the input file before mucking around
       * with parameters etc.
       */
      if ( compile_to_tokens )
      {
         if ( processed >= argc )
            exiterror( ERR_PROG_UNREADABLE, 1, "Too few arguments when "
                                "tokenising. Usage: -c inputfile outputfile" );
         if ( processed + 1 < argc )
            exiterror( ERR_PROG_UNREADABLE, 1, "Too many arguments when "
                                "tokenising. Usage: -c inputfile outputfile" );

         just_compile( TSD, argv[processed] );
         return 0;
      }

      /*
       * Under DJGPP setmode screws up Parse Pull and entering code
       * interactively :-(
       */
#if defined(__EMX__) || (defined(_MSC_VER) && !defined(__WINS__)) || (defined(__WATCOMC__) && !defined(__QNX__))
      setmode( fileno( stdin ), O_BINARY );
      setmode( fileno( stdout ), O_BINARY );
      setmode( fileno( stderr ), O_BINARY );
#endif

      assign_args( TSD, argc, processed, argv );
      signal_setup( TSD );

      /*
       * -e switch specified - execute from tokenised code
       */
      if ( execute_from_tokens )
         rcode = execute_tokenized( TSD );
      else
         rcode = execute_file( TSD );
   }

#if defined(DEBUG) || defined(TRACEMEM)
   /*
    * Now do the cleanup. We don't need in real life, but for a proper cleanup
    * and for debugging aid it is a good idea to track down the whole beast.
    */
   purge_stacks( TSD );
   purge_filetable( TSD );
# if defined(FLISTS) && defined(NEW_FLISTS)
   free_flists();
# endif

# ifdef DYNAMIC
   /*
    * Remove all external function package functions
    * and libraries. Only valid for the DYNAMIC library.
    */
   purge_library( TSD );
# endif

# ifdef TRACEMEM
   if ( TSD->listleakedmemory )
      listleaked( TSD, MEMTRC_LEAKED );
# endif

   TSD->systeminfo->script_exit = NULL; /* cannot be freed, it's on the stack*/
   killsystem( TSD, TSD->systeminfo );
   TSD->systeminfo = NULL;

   /*
    * Remove all memory allocated by the flists internal memory manager.
    */
# ifdef FLISTS
   purge_flists( TSD );
# endif

#endif /* DEBUG */

   return rcode;
}
Пример #16
0
Файл: main.c Проект: robinp/neko
int main( int argc, char *argv[] ) {
	neko_vm *vm;
	value mload;
	int r;
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
	neko_global_init();
	vm = neko_vm_alloc(NULL);
	neko_vm_select(vm);
#	ifdef NEKO_STANDALONE
	neko_standalone_init();
#	endif
	if( !neko_has_embedded_module(vm) ) {
		int jit = 1;
		int stats = 0;
		while( argc > 1 ) {
			if( strcmp(argv[1],"-interp") == 0 ) {
				argc--;
				argv++;
				jit = 0;
				continue;
			}
			if( strcmp(argv[1],"-stats") == 0 ) {
				argc--;
				argv++;
				stats = 1;
				neko_vm_set_stats(vm,neko_stats_measure,neko_stats_measure);
				neko_stats_measure(vm,"total",1);
				continue;
			}
			break;
		}
#		ifdef NEKO_POSIX
		if( jit ) {
			struct sigaction act;
			act.sa_sigaction = NULL;
			act.sa_handler = handle_signal;
			act.sa_flags = 0;
			sigemptyset(&act.sa_mask);
			sigaction(SIGSEGV,&act,NULL);
		}
#		endif
		neko_vm_jit(vm,jit);
		if( argc == 1 ) {
#			ifdef NEKO_STANDALONE
			report(vm,alloc_string("No embedded module in this executable"),0);
#			else
			printf("NekoVM %d.%d.%d (c)2005-2009 Motion-Twin\n  Usage : neko <file>\n",NEKO_VERSION/100,(NEKO_VERSION/10)%10,NEKO_VERSION%10);
#			endif
			mload = NULL;
			r = 1;
		} else {
			mload = default_loader(argv+2,argc-2);
			r = execute_file(vm,argv[1],mload);
		}
		if( stats ) {
			value v;
			neko_stats_measure(vm,"total",0);
			v = neko_stats_build(vm);
			val_print(alloc_string("TOT\tTIME\tCOUNT\tNAME\n"));
			while( v != val_null ) {
				char buf[256];
				value *s = val_array_ptr(v);
				int errors = val_int(s[4]);
				sprintf(buf,"%d\t%d\t%d\t%s%c",
					val_int(s[1]),
					val_int(s[2]),
					val_int(s[3]),
					val_string(s[0]),
					errors?' ':'\n');
				if( errors )
					sprintf(buf+strlen(buf),"ERRORS=%d\n",errors);
				val_print(alloc_string(buf));
				v = s[5];
			}
		}
	} else {
		mload = default_loader(argv+1,argc-1);
		r = neko_execute_self(vm,mload);
	}
	if( mload != NULL && val_field(mload,val_id("dump_prof")) != val_null )
		val_ocall0(mload,val_id("dump_prof"));
	vm = NULL;
	mload = NULL;
	neko_vm_select(NULL);
	neko_global_free();
	return r;
}
Пример #17
0
int main(int argc, char const *argv[])
{
#ifdef _MEM_PROFILER
  uint8_t checkpoint_set = 0;
#endif
  fd_set rfds;
  char buffer[PIPE_BUFFER_SIZE];
  int i, n;
  Plugin plugins[MAX_PLUGINS];
  int plugins_count = 0;
  mrb_state *mrb;
  mrb_value r_output, r_plugins_list;
  mrb_sym output_gv_sym, plugins_to_load_gv_sym;
  
  printf("Version: %s\n", PROBE_VERSION);
  
  if( argc != 2 ){
    printf("Usage: %s <config_path>\n", argv[0]);
    exit(1);
  }
  
#ifdef _MEM_PROFILER
  init_profiler();
#endif
  
  config_path = argv[1];
  
  printf("Initializing core...\n");
  mrb = mrb_open_allocf(profiler_allocf, "main");
  output_gv_sym = mrb_intern_cstr(mrb, "$output");
  plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load");
  setup_api(mrb);
  execute_file(mrb, "plugins/main.rb");
  execute_file(mrb, config_path);
  
  printf("Loading plugins...\n");
  r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym);
  for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){
    char *path, tmp[100];
    int ssize;
    
    mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i);
    const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name);
    
    snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name);
    ssize = strlen(tmp);
    
    path = malloc(ssize + 1);
    strncpy(path, tmp, ssize);
    path[ssize] = '\0';
    
    if( access(path, F_OK) == -1 ){
      printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno));
      exit(1);
    }
    
    init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++;
  }
  
  printf("Instanciating output class...\n");
  r_output = mrb_gv_get(mrb, output_gv_sym);
  interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0));
  
  printf("Interval set to %dms\n", (int)interval);
  
  printf("Sending initial report...\n");
  mrb_funcall(mrb, r_output, "send_report", 0);
  
  if (mrb->exc) {
    mrb_print_error(mrb);
    
    exit(1);
  }

  
  // start all the threads
  for(i= 0; i< plugins_count; i++){
    // printf("== plugin %d\n", i);
    n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]);
    if( n < 0 ){
      fprintf(stderr, "create failed\n");
    }
  }
  
  if( signal(SIGINT, clean_exit) == SIG_ERR){
    perror("signal");
    exit(1);
  }
  
  while(running){
    int fds[MAX_PLUGINS];
    int maxfd = 0, ai;
    struct timeval tv;
    mrb_value r_buffer;
    struct timeval cycle_started_at, cycle_completed_at;
    
    gettimeofday(&cycle_started_at, NULL);
    
    bzero(fds, sizeof(int) * MAX_PLUGINS);
    
    // ask every plugin to send their data
    for(i= 0; i< plugins_count; i++){
      strcpy(buffer, "request");
      if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){
        printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name);
      }
      fds[i] = plugins[i].host_pipe;
      // printf("sent request to %d\n", i);
    }
    
    // printf("waiting answers...\n");
    // and now wait for each answer
    while(1){
      int left = 0;
      
      FD_ZERO(&rfds);
      
      for(i = 0; i< MAX_PLUGINS; i++){
        if( fds[i] != NOPLUGIN_VALUE ){
          FD_SET(fds[i], &rfds);
          left++;
          if( fds[i] > maxfd )
            maxfd = fds[i];
        }
      }
      
      // printf("left: %d %d\n", left, left <= 0);
      
      if( !running || (0 == left) )
        break;
      
      // substract 20ms to stay below the loop delay
      fill_timeout(&tv, cycle_started_at, interval - 20);
      // printf("before select\n");
      n = select(maxfd + 1, &rfds, NULL, NULL, &tv);
      // printf("after select: %d\n", n);
      if( n > 0 ){
        // find out which pipes have data
        for(i = 0; i< MAX_PLUGINS; i++){
          if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){
            while (1){
              struct timeval answered_at;
              n = read(fds[i], buffer, sizeof(buffer));
              if( n == -1 ){
                if( errno != EAGAIN )
                  perror("read");
                break;
              }
              
              if( n == PIPE_BUFFER_SIZE ){
                printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE);
                continue;
              }
              
              gettimeofday(&answered_at, NULL);
              // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud,
              //     (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 +
              //     (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000)
              //   );
              
              buffer[n] = 0x00;
              
              ai = mrb_gc_arena_save(mrb);
              r_buffer = mrb_str_buf_new(mrb, n);
              mrb_str_buf_cat(mrb, r_buffer, buffer, n);
              
              // mrb_funcall(mrb, r_output, "tick", 0);
              mrb_funcall(mrb, r_output, "add", 1, r_buffer);
              check_exception("add", mrb);
              
              // pp(mrb, r_output, 0);
              
              mrb_gc_arena_restore(mrb, ai);
            }
            
            fds[i] = 0;
          }
        }
      }
      else if( n == 0 )  {
        printf("no responses received from %d plugins.\n", left);
        break;
        // timeout
      }
      else {
        perror("select");
      }
    }
    
    int idx = mrb_gc_arena_save(mrb);
    mrb_funcall(mrb, r_output, "flush", 0);
    check_exception("flush", mrb);
    mrb_gc_arena_restore(mrb, idx);
    
    // and now sleep until the next cycle
    gettimeofday(&cycle_completed_at, NULL);
    
  #ifdef _MEM_PROFILER
    if( checkpoint_set ){
      print_allocations();
    }
  #endif
    
    // force a gc run at the end of each cycle
    mrb_full_gc(mrb);
    // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa);
    // for(i= 0; i< plugins_count; i++){
    //   printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa);
    // }
  
  #ifdef _MEM_PROFILER
    checkpoint_set = 1;
    // and set starting point
    profiler_set_checkpoint();
  #endif

    
  #ifdef _MEM_PROFILER_RUBY
    // dump VMS state
    dump_state(mrb);
    for(i= 0; i< plugins_count; i++){
      dump_state(plugins[i].mrb);
    }
  #endif
    
    fflush(stdout);
    sleep_delay(&cycle_started_at, &cycle_completed_at, interval);
  }
  
  printf("Sending exit signal to all plugins...\n");
  strcpy(buffer, "exit");
  for(i= 0; i< plugins_count; i++){
    C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) );
  }
  
  printf("Giving some time for threads to exit...\n\n");
  really_sleep(2000);
  
  
  for(i= 0; i< plugins_count; i++){
    int ret = pthread_kill(plugins[i].thread, 0);
    
    // if a success is returned then the thread is still alive
    // which means the thread did not acknoledged the exit message
    // kill it.
    if( ret == 0 ){
      printf("    - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud);
      pthread_cancel(plugins[i].thread);
    }
    else {
      printf("    - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud);
    }
    
    if( pthread_join(plugins[i].thread, NULL) < 0){
      fprintf(stderr, "join failed\n");
    }
    
    mrb_close(plugins[i].mrb);
  }
  
  mrb_close(mrb);
  
  printf("Exited !\n");
  return 0;
}