gamemode: Add executable to initializer

This allows to initialize the GameModeClient later and cleans up the
error path.

Signed-off-by: Kai Krakow <kai@kaishome.de>
This commit is contained in:
Kai Krakow 2018-10-03 14:37:22 +02:00
parent 8214f93630
commit bd811c6646

View File

@ -103,7 +103,7 @@ static GameModeContext instance = { 0 };
*/ */
static volatile bool had_context_init = false; static volatile bool had_context_init = false;
static GameModeClient *game_mode_client_new(pid_t pid); static GameModeClient *game_mode_client_new(pid_t pid, char *exe);
static void game_mode_client_free(GameModeClient *client); static void game_mode_client_free(GameModeClient *client);
static bool game_mode_context_has_client(GameModeContext *self, pid_t client); static bool game_mode_context_has_client(GameModeContext *self, pid_t client);
static int game_mode_context_num_clients(GameModeContext *self); static int game_mode_context_num_clients(GameModeContext *self);
@ -442,6 +442,7 @@ bool game_mode_context_register(GameModeContext *self, pid_t client)
{ {
/* Construct a new client if we can */ /* Construct a new client if we can */
GameModeClient *cl = NULL; GameModeClient *cl = NULL;
char *executable = NULL;
/* Cap the total number of active clients */ /* Cap the total number of active clients */
if (game_mode_context_num_clients(self) + 1 > MAX_GAMES) { if (game_mode_context_num_clients(self) + 1 > MAX_GAMES) {
@ -449,11 +450,7 @@ bool game_mode_context_register(GameModeContext *self, pid_t client)
return false; return false;
} }
cl = game_mode_client_new(client); errno = 0;
if (!cl) {
fputs("OOM\n", stderr);
return false;
}
/* Check the PID first to spare a potentially expensive lookup for the exe */ /* Check the PID first to spare a potentially expensive lookup for the exe */
if (game_mode_context_has_client(self, client)) { if (game_mode_context_has_client(self, client)) {
@ -461,20 +458,27 @@ bool game_mode_context_register(GameModeContext *self, pid_t client)
goto error_cleanup; goto error_cleanup;
} }
/* Lookup the executable */ /* Lookup the executable first */
cl->executable = game_mode_context_find_exe(client); executable = game_mode_context_find_exe(client);
if (!cl->executable) if (!executable)
goto error_cleanup; goto error_cleanup;
/* Check our blacklist and whitelist */ /* Check our blacklist and whitelist */
if (!config_get_client_whitelisted(self->config, cl->executable)) { if (!config_get_client_whitelisted(self->config, executable)) {
LOG_MSG("Client [%s] was rejected (not in whitelist)\n", cl->executable); LOG_MSG("Client [%s] was rejected (not in whitelist)\n", executable);
goto error_cleanup; goto error_cleanup;
} else if (config_get_client_blacklisted(self->config, cl->executable)) { } else if (config_get_client_blacklisted(self->config, executable)) {
LOG_MSG("Client [%s] was rejected (in blacklist)\n", cl->executable); LOG_MSG("Client [%s] was rejected (in blacklist)\n", executable);
goto error_cleanup; goto error_cleanup;
} }
/* From now on we depend on the client, initialize it */
cl = game_mode_client_new(client, executable);
if (cl)
executable = NULL; // ownership has been delegated
else
goto error_cleanup;
/* Begin a write lock now to insert our new client at list start */ /* Begin a write lock now to insert our new client at list start */
pthread_rwlock_wrlock(&self->rwlock); pthread_rwlock_wrlock(&self->rwlock);
@ -497,7 +501,11 @@ bool game_mode_context_register(GameModeContext *self, pid_t client)
game_mode_apply_ioprio(self, client); game_mode_apply_ioprio(self, client);
return true; return true;
error_cleanup: error_cleanup:
if (errno != 0)
LOG_ERROR("Failed to register client [%d]: %s\n", client, strerror(errno));
free(executable);
game_mode_client_free(cl); game_mode_client_free(cl);
return false; return false;
} }
@ -585,9 +593,10 @@ int game_mode_context_query_status(GameModeContext *self, pid_t client)
* *
* This is deliberately OOM safe * This is deliberately OOM safe
*/ */
static GameModeClient *game_mode_client_new(pid_t pid) static GameModeClient *game_mode_client_new(pid_t pid, char *executable)
{ {
GameModeClient c = { GameModeClient c = {
.executable = executable,
.next = NULL, .next = NULL,
.pid = pid, .pid = pid,
}; };