Example #1
0
void LLPumpIO::pump()
{
	pump(DEFAULT_POLL_TIMEOUT);
}
Example #2
0
int connect_daemon(int argc, char *argv[]) {
    char errfile[PATH_MAX];
    char outfile[PATH_MAX];
    char infile[PATH_MAX];
    int uid = getuid();
    sprintf(outfile, "%s/%d.stdout", REQUESTOR_DAEMON_PATH, getpid());
    sprintf(errfile, "%s/%d.stderr", REQUESTOR_DAEMON_PATH, getpid());
    sprintf(infile, "%s/%d.stdin", REQUESTOR_DAEMON_PATH, getpid());
    unlink(errfile);
    unlink(infile);
    unlink(outfile);

    struct sockaddr_un sun;

    int socketfd = socket(AF_LOCAL, SOCK_STREAM, 0);
    if (socketfd < 0) {
        PLOGE("socket");
        exit(-1);
    }
    if (fcntl(socketfd, F_SETFD, FD_CLOEXEC)) {
        PLOGE("fcntl FD_CLOEXEC");
        exit(-1);
    }

    memset(&sun, 0, sizeof(sun));
    sun.sun_family = AF_LOCAL;
    sprintf(sun.sun_path, "%s/server", REQUESTOR_DAEMON_PATH);

    if (0 != connect(socketfd, (struct sockaddr*)&sun, sizeof(sun))) {
        PLOGE("connect");
        exit(-1);
    }

    LOGD("connecting client %d", getpid());

    int mount_storage = getenv("MOUNT_EMULATED_STORAGE") != NULL;

    write_int(socketfd, getpid());
    write_int(socketfd, isatty(STDIN_FILENO));
    write_int(socketfd, uid);
    write_int(socketfd, getppid());
    write_int(socketfd, mount_storage);
    write_int(socketfd, mount_storage ? argc - 1 : argc);

    int i;
    for (i = 0; i < argc; i++) {
        if (i == 1 && mount_storage) {
            continue;
        }
        write_string(socketfd, argv[i]);
    }

    // ack
    read_int(socketfd);

    int outfd = open(outfile, O_RDONLY);
    if (outfd <= 0) {
        PLOGE("outfd %s ", outfile);
        exit(-1);
    }
    int errfd = open(errfile, O_RDONLY);
    if (errfd <= 0) {
        PLOGE("errfd %s", errfile);
        exit(-1);
    }
    int infd = open(infile, O_WRONLY);
    if (infd <= 0) {
        PLOGE("infd %s", infile);
        exit(-1);
    }

    pump_async(STDIN_FILENO, infd);
    pump_async(errfd, STDERR_FILENO);
    pump(outfd, STDOUT_FILENO);

    int code = read_int(socketfd);
    LOGD("client exited %d", code);
    return code;
}
Example #3
0
void Pillow::HttpHandlerProxyPipe::proxiedReply_readyRead()
{
	sendHeaders();
	if (!_broken) pump(_proxiedReply->readAll());
}
Example #4
0
static int daemon_accept(int fd) {
    is_daemon = 1;
    int pid = read_int(fd);
    LOGD("remote pid: %d", pid);
    int atty = read_int(fd);
    LOGD("remote atty: %d", atty);
    daemon_from_uid = read_int(fd);
    LOGD("remote uid: %d", daemon_from_uid);
    daemon_from_pid = read_int(fd);
    LOGD("remote req pid: %d", daemon_from_pid);

    struct ucred credentials;
    int ucred_length = sizeof(struct ucred);
    /* fill in the user data structure */
    if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) {
        LOGE("could obtain credentials from unix domain socket");
        exit(-1);
    }
    // if the credentials on the other side of the wire are NOT root,
    // we can't trust anything being sent.
    if (credentials.uid != 0) {
        daemon_from_uid = credentials.uid;
        pid = credentials.pid;
        daemon_from_pid = credentials.pid;
    }

    int mount_storage = read_int(fd);
    int argc = read_int(fd);
    if (argc < 0 || argc > 512) {
        LOGE("unable to allocate args: %d", argc);
        exit(-1);
    }
    LOGD("remote args: %d", argc);
    char** argv = (char**)malloc(sizeof(char*) * (argc + 1));
    argv[argc] = NULL;
    int i;
    for (i = 0; i < argc; i++) {
        argv[i] = read_string(fd);
    }

    char errfile[PATH_MAX];
    char outfile[PATH_MAX];
    char infile[PATH_MAX];
    sprintf(outfile, "%s/%d.stdout", REQUESTOR_DAEMON_PATH, pid);
    sprintf(errfile, "%s/%d.stderr", REQUESTOR_DAEMON_PATH, pid);
    sprintf(infile, "%s/%d.stdin", REQUESTOR_DAEMON_PATH, pid);

    if (mkfifo(outfile, 0660) != 0) {
        PLOGE("mkfifo %s", outfile);
        exit(-1);
    }
    if (mkfifo(errfile, 0660) != 0) {
        PLOGE("mkfifo %s", errfile);
        exit(-1);
    }
    if (mkfifo(infile, 0660) != 0) {
        PLOGE("mkfifo %s", infile);
        exit(-1);
    }

    chown(outfile, daemon_from_uid, 0);
    chown(infile, daemon_from_uid, 0);
    chown(errfile, daemon_from_uid, 0);
    chmod(outfile, 0660);
    chmod(infile, 0660);
    chmod(errfile, 0660);

    // ack
    write_int(fd, 1);

    int ptm = -1;
    char* devname = NULL;
    if (atty) {
        ptm = open("/dev/ptmx", O_RDWR);
        if (ptm <= 0) {
            PLOGE("ptm");
            exit(-1);
        }
        if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)) {
            PLOGE("ptm setup");
            close(ptm);
            exit(-1);
        }
        LOGD("devname: %s", devname);
    }

    int outfd = open(outfile, O_WRONLY);
    if (outfd <= 0) {
        PLOGE("outfd daemon %s", outfile);
        goto done;
    }
    int errfd = open(errfile, O_WRONLY);
    if (errfd <= 0) {
        PLOGE("errfd daemon %s", errfile);
        goto done;
    }
    int infd = open(infile, O_RDONLY);
    if (infd <= 0) {
        PLOGE("infd daemon %s", infile);
        goto done;
    }

    int code;
    // now fork and run main, watch for the child pid exit, and send that
    // across the control channel as the response.
    int child = fork();
    if (child < 0) {
        code = child;
        goto done;
    }

    // if this is the child, open the fifo streams
    // and dup2 them with stdin/stdout, and run main, which execs
    // the target.
    if (child == 0) {
        close(fd);

        if (devname != NULL) {
            int pts = open(devname, O_RDWR);
            if(pts < 0) {
                PLOGE("pts");
                exit(-1);
            }

            struct termios slave_orig_term_settings; // Saved terminal settings 
            tcgetattr(pts, &slave_orig_term_settings);

            struct termios new_term_settings;
            new_term_settings = slave_orig_term_settings; 
            cfmakeraw(&new_term_settings);
            // WHY DOESN'T THIS WORK, FUUUUU
            new_term_settings.c_lflag &= ~(ECHO);
            tcsetattr(pts, TCSANOW, &new_term_settings);

            setsid();
            ioctl(pts, TIOCSCTTY, 1);

            close(infd);
            close(outfd);
            close(errfd);
            close(ptm);

            errfd = pts;
            infd = pts;
            outfd = pts;
        }

#ifdef SUPERUSER_EMBEDEDED
        if (mount_storage) {
            mount_emulated_storage(multiuser_get_user_id(daemon_from_uid));
        }
#endif

        return run_daemon_child(infd, outfd, errfd, argc, argv);
    }

    if (devname != NULL) {
        // pump ptm across the socket
        pump_async(infd, ptm);
        pump(ptm, outfd);
    }
    else {
        close(infd);
        close(outfd);
        close(errfd);
    }

    // wait for the child to exit, and send the exit code
    // across the wire.
    int status;
    LOGD("waiting for child exit");
    if (waitpid(child, &status, 0) > 0) {
        code = WEXITSTATUS(status);
    }
    else {
        code = -1;
    }

done:
    write(fd, &code, sizeof(int));
    close(fd);
    LOGD("child exited");
    return code;
}
LEVEL_RESULT playsingle_controller::play_scenario(const config& level)
{
	LOG_NG << "in playsingle_controller::play_scenario()...\n";

	// Start music.
	BOOST_FOREACH(const config &m, level.child_range("music")) {
		sound::play_music_config(m);
	}
	sound::commit_music_changes();

	if(!this->is_skipping_replay()) {
		show_story(gui_->video(), get_scenario_name(), level.child_range("story"));
	}
	gui_->labels().read(level);

	// Read sound sources
	assert(soundsources_manager_ != NULL);
	BOOST_FOREACH(const config &s, level.child_range("sound_source")) {
		try {
			soundsource::sourcespec spec(s);
			soundsources_manager_->add(spec);
		} catch (bad_lexical_cast &) {
			ERR_NG << "Error when parsing sound_source config: bad lexical cast." << std::endl;
			ERR_NG << "sound_source config was: " << s.debug() << std::endl;
			ERR_NG << "Skipping this sound source..." << std::endl;
		}
	}
	LOG_NG << "entering try... " << (SDL_GetTicks() - ticks()) << "\n";
	try {
		play_scenario_init();
		// clears level config;
		this->saved_game_.remove_snapshot();

		if (!is_regular_game_end() && !linger_) {
			play_scenario_main_loop();
		}
		if (game_config::exit_at_end) {
			exit(0);
		}
		const bool is_victory = get_end_level_data_const().is_victory;

		if(gamestate().gamedata_.phase() <= game_data::PRESTART) {
			sdl::draw_solid_tinted_rectangle(
				0, 0, gui_->video().getx(), gui_->video().gety(), 0, 0, 0, 1.0,
				gui_->video().getSurface()
				);
			update_rect(0, 0, gui_->video().getx(), gui_->video().gety());
		}

		ai_testing::log_game_end();

		const end_level_data& end_level = get_end_level_data_const();
		if (!end_level.transient.custom_endlevel_music.empty()) {
			if (!is_victory) {
				set_defeat_music_list(end_level.transient.custom_endlevel_music);
			} else {
				set_victory_music_list(end_level.transient.custom_endlevel_music);
			}
		}

		if (gamestate().board_.teams().empty())
		{
			//store persistent teams
			saved_game_.set_snapshot(config());

			return LEVEL_RESULT::VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event
		}
		if(linger_) {
			LOG_NG << "resuming from loaded linger state...\n";
			//as carryover information is stored in the snapshot, we have to re-store it after loading a linger state
			saved_game_.set_snapshot(config());
			if(!is_observer()) {
				persist_.end_transaction();
			}
			return LEVEL_RESULT::VICTORY;
		}
		pump().fire(is_victory ? "victory" : "defeat");
		{ // Block for set_scontext_synced_base
			set_scontext_synced_base sync;
			pump().fire("scenario end");
		}
		if(end_level.proceed_to_next_level) {
			gamestate().board_.heal_all_survivors();
		}
		if(is_observer()) {
			gui2::show_transient_message(gui_->video(), _("Game Over"), _("The game is over."));
			return LEVEL_RESULT::OBSERVER_END;
		}
		// If we're a player, and the result is victory/defeat, then send
		// a message to notify the server of the reason for the game ending.
		network::send_data(config_of
			("info", config_of
				("type", "termination")
				("condition", "game over")
				("result", is_victory ? "victory" : "defeat")
			));
		// Play victory music once all victory events
		// are finished, if we aren't observers.
		//
		// Some scenario authors may use 'continue'
		// result for something that is not story-wise
		// a victory, so let them use [music] tags
		// instead should they want special music.
		const std::string& end_music = is_victory ? select_victory_music() : select_defeat_music();
		if(end_music.empty() != true) {
			sound::play_music_once(end_music);
		}
		persist_.end_transaction();
		return is_victory ? LEVEL_RESULT::VICTORY : LEVEL_RESULT::DEFEAT;
	} catch(const game::load_game_exception &) {
		// Loading a new game is effectively a quit.
		//
		if ( game::load_game_exception::game != "" ) {
			saved_game_ = saved_game();
		}
		throw;
	} catch(network::error& e) {
		bool disconnect = false;
		if(e.socket) {
			e.disconnect();
			disconnect = true;
		}

		scoped_savegame_snapshot snapshot(*this);
		savegame::ingame_savegame save(saved_game_, *gui_, preferences::save_compression_format());
		save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO);
		if(disconnect) {
			throw network::error();
		} else {
			return LEVEL_RESULT::QUIT;
		}
	}

	return LEVEL_RESULT::QUIT;
}