	void sendStartupRequest(StartupDetails &details) {
		TRACE_POINT();
		try {
			writeExact(details.adminSocket,
				"You have control 1.0\n"
				"passenger_root: " + resourceLocator.getRoot() + "\n"
				"ruby_libdir: " + resourceLocator.getRubyLibDir() + "\n"
				"passenger_version: " PASSENGER_VERSION "\n"
				"generation_dir: " + generation->getPath() + "\n",
				&details.timeout);

			vector<string> args;
			vector<string>::const_iterator it, end;
			details.options->toVector(args, resourceLocator);
			for (it = args.begin(); it != args.end(); it++) {
				const string &key = *it;
				it++;
				const string &value = *it;
				writeExact(details.adminSocket,
					key + ": " + value + "\n",
					&details.timeout);
			}
			writeExact(details.adminSocket, "\n", &details.timeout);
		} catch (const SystemException &e) {
			if (e.code() == EPIPE) {
				/* Ignore this. Process might have written an
				 * error response before reading the arguments,
				 * in which case we'll want to show that instead.
				 */
			} else {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader. There was an I/O error while "
					"sending the startup request message to it: " +
					e.sys(),
					SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
					details);
			}
		} catch (const TimeoutException &) {
			throwPreloaderSpawnException("An error occurred while starting up the "
				"preloader: it did not read the startup request message in time.",
				SpawnException::PRELOADER_STARTUP_TIMEOUT,
				details);
		}
	}
	void sendStartupRequest(StartupDetails &details) {
		TRACE_POINT();
		try {
			writeExact(details.adminSocket,
				"You have control 1.0\n"
				"passenger_root: " + resourceLocator.getRoot() + "\n"
				"ruby_libdir: " + resourceLocator.getRubyLibDir() + "\n"
				"passenger_version: " PASSENGER_VERSION "\n"
				"generation_dir: " + generation->getPath() + "\n",
				&details.timeout);

			vector<string> args;
			vector<string>::const_iterator it, end;
			details.options->toVector(args, resourceLocator);
			for (it = args.begin(); it != args.end(); it++) {
				const string &key = *it;
				it++;
				const string &value = *it;
				writeExact(details.adminSocket,
					key + ": " + value + "\n",
					&details.timeout);
			}
			writeExact(details.adminSocket, "\n", &details.timeout);
		} catch (const SystemException &e) {
			if (e.code() == EPIPE) {
				 
			} else {
				throwPreloaderSpawnException("An error occurred while starting up "
					"the preloader. There was an I/O error while "
					"sending the startup request message to it: " +
					e.sys(),
					SpawnException::PRELOADER_STARTUP_PROTOCOL_ERROR,
					details);
			}
		} catch (const TimeoutException &) {
			throwPreloaderSpawnException("An error occurred while starting up the "
				"preloader: it did not read the startup request message in time.",
				SpawnException::PRELOADER_STARTUP_TIMEOUT,
				details);
		}
	}