Exemplo n.º 1
0
static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	nd_set_link(nd, read_link(dentry));
	return NULL;
}
Exemplo n.º 2
0
static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	nd_set_link(nd, read_link(dentry));
	return 0;
}
Exemplo n.º 3
0
void update_links( void )
{
  char_data*            ch;
  link_data*          link;
  text_data*       receive;
  fd_set          read_set;
  fd_set         write_set;
  fd_set          exec_set;
  struct timeval     start;  
  struct timeval   timeout;  

  gettimeofday( &start, NULL );

  timeout.tv_sec  = 1;
  timeout.tv_usec = 0;

  FD_ZERO( &read_set );
  FD_ZERO( &write_set );
  FD_ZERO( &exec_set );

  FD_SET( socket_one, &read_set );
  FD_SET( socket_two, &read_set );

  for( link = link_list; link != NULL; link = link->next ) {
    FD_SET( link->channel, &read_set  );
    FD_SET( link->channel, &write_set );
    FD_SET( link->channel, &exec_set );
    }

  if( (int) select( FD_SETSIZE, &read_set, &write_set, &exec_set,
    &timeout ) < 0 ) 
    panic( "Update links: select" );

  if( FD_ISSET( socket_one, &read_set ) )
    open_link( socket_one );

  if( FD_ISSET( socket_two, &read_set ) )
    open_link( socket_two );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
  
    if( FD_ISSET( link->channel, &exec_set ) ) {
      write( link->player );
      close_socket( link );
      continue;
      }
  
    if( FD_ISSET( link->channel, &read_set ) ) {
      link->idle = 0;
      if( link->player != NULL )
        link->player->timer = current_time;
      if( !read_link( link ) ) {
        write( link->player );
        close_socket( link );
        continue;
        }
      }

    if( link->idle++ > 10000 && link->connected != CON_PLAYING ) {
      send( link, "\n\r\n\r-- CONNECTION TIMEOUT --\n\r" );
      close_socket( link, TRUE );
      }
    }

  pulse_time[ TIME_READ_INPUT ] = stop_clock( start );  
  gettimeofday( &start, NULL );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
    if( link->command = ( ( receive = link->receive ) != NULL ) ) {
      ampersand( receive );
      link->receive  = receive->next;
      link->idle     = 0; 
      if( link->connected == CON_PLAYING ) {
        stop_idling( ch = link->character );
        interpret( link->character, receive->message.text );
        }  
      else
        nanny( link, receive->message.text );
      delete receive;
      }
    }

  pulse_time[ TIME_COMMANDS ] = stop_clock( start );  
  gettimeofday( &start, NULL );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
    if( link->idle%25 == 0 && FD_ISSET( link->channel, &write_set )
      && !process_output( link ) ) {
      write( link->player );
      close_socket( link );
      }
    }  
  
  pulse_time[ TIME_WRITE_OUTPUT ] = stop_clock( start );  

  return;
}
Exemplo n.º 4
0
void
impl_init(void)
{
    const char* mode_env = getenv("HUPTIME_MODE");
    const char* multi_env = getenv("HUPTIME_MULTI");
    const char* revive_env = getenv("HUPTIME_REVIVE");
    const char* debug_env = getenv("HUPTIME_DEBUG");
    const char* pipe_env = getenv("HUPTIME_PIPE");
    const char* wait_env = getenv("HUPTIME_WAIT");

    if( debug_env != NULL && strlen(debug_env) > 0 )
    {
        debug_enabled = !strcasecmp(debug_env, "true") ? TRUE: FALSE;
    }

    DEBUG("Initializing...");

    /* Initialize our lock. */
    impl_init_lock();

    /* Save this pid as our master pid.
     * This is done to handle processes that use
     * process pools. We remember the master pid and
     * will do the full fork()/exec() only when we are
     * the master. Otherwise, we will simply shutdown
     * gracefully, and all the master to restart. */
    master_pid = getpid();

    /* Grab our exit strategy. */
    if( mode_env != NULL && strlen(mode_env) > 0 )
    {
        if( !strcasecmp(mode_env, "fork") )
        {
            exit_strategy = FORK;
            DEBUG("Exit strategy is fork.");
        }
        else if( !strcasecmp(mode_env, "exec") )
        {
            exit_strategy = EXEC;
            DEBUG("Exit strategy is exec.");
        }
        else
        {
            fprintf(stderr, "Unknown exit strategy.");
            libc.exit(1);
        }
    }

    /* Check if we have something to unlink. */
    to_unlink = getenv("HUPTIME_UNLINK");
    if( to_unlink != NULL && strlen(to_unlink) > 0 )
    {
        DEBUG("Unlink is '%s'.", to_unlink);
    }

    /* Clear up any outstanding child processes.
     * Because we may have exited before the process
     * could do appropriate waitpid()'s, we try to
     * clean up children here. Note that we may have
     * some zombies that hang around during the life
     * of the program, but at every restart they will
     * be cleaned up (so at least they won't grow
     * without bound). */
    int status = 0;
    while( waitpid((pid_t)-1, &status, WNOHANG) > 0 );

    /* Check if we're in multi mode. */
    if( multi_env != NULL && strlen(multi_env) > 0 )
    {
        multi_mode = !strcasecmp(multi_env, "true") ? TRUE: FALSE;
    }
#ifndef SO_REUSEPORT
    if( multi_mode == TRUE )
    {
        fprintf(stderr, "WARNING: Multi mode not supported.\n");
        fprintf(stderr, "(Requires at least Linux 3.9 and recent headers).\n");
    } 
#endif

    /* Check if we're in revive mode. */
    if( revive_env != NULL && strlen(revive_env) > 0 )
    {
        revive_mode = !strcasecmp(revive_env, "true") ? TRUE : FALSE;
    }

    /* Check if we are in wait mode. */
    if( wait_env != NULL && strlen(wait_env) > 0 )
    {
        wait_mode = !strcasecmp(wait_env, "true") ? TRUE : FALSE;
    }

    /* Check if we're a respawn. */
    if( pipe_env != NULL && strlen(pipe_env) > 0 )
    {
        int fd = -1;
        fdinfo_t *info = NULL;
        int pipefd = strtol(pipe_env, NULL, 10);

        DEBUG("Loading all file descriptors.");

        /* Decode all passed information. */
        while( !info_decode(pipefd, &fd, &info) )
        {
            fd_save(fd, info);
            DEBUG("Decoded fd %d (type %d).", fd, info->type);
            info = NULL;
        }
        if( info != NULL )
        {
            dec_ref(info);
        }

        /* Finished with the pipe. */
        libc.close(pipefd);
        unsetenv("HUPTIME_PIPE");
        DEBUG("Finished decoding.");

        /* Close all non-encoded descriptors. */
        for( fd = 0; fd < fd_max(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info == NULL )
            {
                DEBUG("Closing fd %d.", fd);
                libc.close(fd);
            }
        }

        /* Restore all given file descriptors. */
        for( fd = 0; fd < fd_limit(); fd += 1 )
        {
            info = fd_lookup(fd);
            if( info != NULL && info->type == SAVED )
            {
                fdinfo_t *orig_info = fd_lookup(info->saved.fd);
                if( orig_info != NULL )
                {
                    /* Uh-oh, conflict. Move the original (best effort). */
                    do_dup(info->saved.fd);
                    do_close(info->saved.fd);
                }

                /* Return the offset (ignore failure). */
                if( info->saved.offset != (off_t)-1 )
                {
                    lseek(fd, info->saved.offset, SEEK_SET);
                }

                /* Move the SAVED fd back. */
                libc.dup2(fd, info->saved.fd);
                DEBUG("Restored fd %d.", info->saved.fd);
            }
        }
    }
    else
    {
        DEBUG("Saving all initial file descriptors.");

        /* Save all of our initial files. These are used
         * for re-execing the process. These are persisted
         * effectively forever, and on restarts we close
         * everything that is not a BOUND socket or a SAVED
         * file descriptor. */
        for( int fd = 0; fd < fd_max(); fd += 1 )
        {
            fdinfo_t *info = fd_lookup(fd);
            if( info != NULL )
            {
                /* Encoded earlier. */
                continue;
            }

            /* Make a new SAVED FD. */
            int newfd = libc.dup(fd);
            if( newfd >= 0 )
            {
                fdinfo_t *saved_info = alloc_info(SAVED);

                if( saved_info != NULL )
                {
                    saved_info->saved.fd = fd;
                    saved_info->saved.offset = lseek(fd, 0, SEEK_CUR);
                    fd_save(newfd, saved_info);
                    DEBUG("Saved fd %d (offset %lld).",
                        fd, (long long int)saved_info->saved.offset);
                }
            }
        }
    }

    /* Save the environment.
     *
     * NOTE: We reserve extra space in the environment
     * for our special start-up parameters, which will be added
     * in impl_exec() below. (The encoded BOUND/SAVED sockets).
     *
     * We also filter out the special variables above that were
     * used to pass in information about sockets that were bound. */
    free(environ_copy);
    environ_copy = (char**)read_nul_sep("/proc/self/environ");
    DEBUG("Saved environment.");

    /* Save the arguments. */
    free(args_copy);
    args_copy = (char**)read_nul_sep("/proc/self/cmdline");
    DEBUG("Saved args.");
    for( int i = 0; args_copy[i] != NULL; i += 1 )
    {
        DEBUG(" arg%d=%s", i, args_copy[i]);
    }

    /* Save the cwd & exe. */
    free(cwd_copy);
    cwd_copy = (char*)read_link("/proc/self/cwd");
    DEBUG("Saved cwd.");
    free(exe_copy);
    exe_copy = (char*)read_link("/proc/self/exe");
    DEBUG("Saved exe.");

    /* Install our signal handlers. */
    impl_install_sighandlers();

    /* Initialize our thread. */
    impl_init_thread();

    /* Unblock our signals.
     * Note that we have specifically masked the
     * signals prior to the exec() below, to cover
     * the race between program start and having
     * installed the appropriate handlers. */
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGHUP);
    sigprocmask(SIG_UNBLOCK, &set, NULL);

    /* Done. */
    DEBUG("Initialization complete.");
}
Exemplo n.º 5
0
static mrb_value
read_value(MarshalContext *ctx)
{
	mrb_state *mrb = ctx->mrb;

	char type = ctx->readByte();

	mrb_value value;
	if (mrb->arena_idx > maxArena)
		maxArena = mrb->arena_idx;

	int arena = mrb_gc_arena_save(mrb);

	switch (type)
	{
	case TYPE_NIL :
		value = mrb_nil_value();
		break;

	case TYPE_TRUE :
		value = mrb_true_value();
		break;

	case TYPE_FALSE :
		value = mrb_false_value();
		break;
	case TYPE_FIXNUM :
		value = mrb_fixnum_value(read_fixnum(ctx));
		break;

	case TYPE_BIGNUM :
		value = mrb_fixnum_value(read_bignum(ctx));
		break;
	case TYPE_FLOAT :
		value = mrb_float_value(mrb, read_float(ctx));
		ctx->objects.add(value);
		break;

	case TYPE_STRING :
		value = read_string_value(ctx);
		ctx->objects.add(value);
		break;

	case TYPE_ARRAY :
		value = read_array(ctx);
		break;

	case TYPE_HASH :
		value = read_hash(ctx);
		break;

	case TYPE_SYMBOL :
		value = mrb_symbol_value(read_symbol(ctx));
		break;

	case TYPE_SYMLINK :
		value = mrb_symbol_value(read_symlink(ctx));
		break;

	case TYPE_OBJECT :
		value = read_object(ctx);
		break;

	case TYPE_IVAR :
		value = read_instance_var(ctx);
		break;

	case TYPE_LINK :
		value = read_link(ctx);
		break;

	case TYPE_USERDEF :
		value = read_userdef(ctx);
		ctx->objects.add(value);
		break;

	default :
		CCLOG( "Marshal.load: unsupported value type '%c',gbufsize %d",type,g_buf_size);
		CCAssert(false,"f**k");
		//exit(0);
	}

	mrb_gc_arena_restore(mrb, arena);

	return value;
}