Explorar o código

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>
Kai Krakow %!s(int64=6) %!d(string=hai) anos
pai
achega
bd811c6646
Modificáronse 1 ficheiros con 23 adicións e 14 borrados
  1. 23 14
      daemon/gamemode.c

+ 23 - 14
daemon/gamemode.c

@@ -103,7 +103,7 @@ static GameModeContext instance = { 0 };
  */
 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 bool game_mode_context_has_client(GameModeContext *self, pid_t client);
 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 */
 	GameModeClient *cl = NULL;
+	char *executable = NULL;
 
 	/* Cap the total number of active clients */
 	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;
 	}
 
-	cl = game_mode_client_new(client);
-	if (!cl) {
-		fputs("OOM\n", stderr);
-		return false;
-	}
+	errno = 0;
 
 	/* Check the PID first to spare a potentially expensive lookup for the exe */
 	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;
 	}
 
-	/* Lookup the executable */
-	cl->executable = game_mode_context_find_exe(client);
-	if (!cl->executable)
+	/* Lookup the executable first */
+	executable = game_mode_context_find_exe(client);
+	if (!executable)
 		goto error_cleanup;
 
 	/* Check our blacklist and whitelist */
-	if (!config_get_client_whitelisted(self->config, cl->executable)) {
-		LOG_MSG("Client [%s] was rejected (not in whitelist)\n", cl->executable);
+	if (!config_get_client_whitelisted(self->config, executable)) {
+		LOG_MSG("Client [%s] was rejected (not in whitelist)\n", executable);
 		goto error_cleanup;
-	} else if (config_get_client_blacklisted(self->config, cl->executable)) {
-		LOG_MSG("Client [%s] was rejected (in blacklist)\n", cl->executable);
+	} else if (config_get_client_blacklisted(self->config, executable)) {
+		LOG_MSG("Client [%s] was rejected (in blacklist)\n", executable);
 		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 */
 	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);
 
 	return true;
+
 error_cleanup:
+	if (errno != 0)
+		LOG_ERROR("Failed to register client [%d]: %s\n", client, strerror(errno));
+	free(executable);
 	game_mode_client_free(cl);
 	return false;
 }
@@ -585,9 +593,10 @@ int game_mode_context_query_status(GameModeContext *self, pid_t client)
  *
  * 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 = {
+		.executable = executable,
 		.next = NULL,
 		.pid = pid,
 	};