mirror of
https://github.com/FeralInteractive/gamemode.git
synced 2025-06-06 23:57:22 +02:00
Apply clang format to files
Also add brackets for all scopes at the same time
This commit is contained in:
parent
ee1c51d0b0
commit
2bbaab129b
@ -30,55 +30,57 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define MAX_GOVERNORS 128
|
#define MAX_GOVERNORS 128
|
||||||
#define MAX_GOVERNOR_LENGTH PATH_MAX+1
|
#define MAX_GOVERNOR_LENGTH PATH_MAX + 1
|
||||||
|
|
||||||
// Governers are located at /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
// Governers are located at /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||||||
static int fetch_governors( char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] )
|
static int fetch_governors(char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH])
|
||||||
{
|
{
|
||||||
const char* cpu_base_path = "/sys/devices/system/cpu/";
|
const char *cpu_base_path = "/sys/devices/system/cpu/";
|
||||||
DIR* dir = opendir( cpu_base_path );
|
DIR *dir = opendir(cpu_base_path);
|
||||||
if( !dir )
|
if (!dir) {
|
||||||
FATAL_ERRORNO( "cpu device path not found" );
|
FATAL_ERRORNO("cpu device path not found");
|
||||||
|
}
|
||||||
|
|
||||||
int num_governors = 0;
|
int num_governors = 0;
|
||||||
|
|
||||||
// Explore the directory
|
// Explore the directory
|
||||||
struct dirent* ent;
|
struct dirent *ent;
|
||||||
while( ( ent = readdir(dir) ) && num_governors < MAX_GOVERNORS )
|
while ((ent = readdir(dir)) && num_governors < MAX_GOVERNORS) {
|
||||||
{
|
|
||||||
// CPU directories all start with "cpu"
|
// CPU directories all start with "cpu"
|
||||||
if( strncmp( ent->d_name, "cpu", 3 ) == 0 )
|
if (strncmp(ent->d_name, "cpu", 3) == 0) {
|
||||||
{
|
|
||||||
// Check if this matches "cpu\d+"
|
// Check if this matches "cpu\d+"
|
||||||
const int len = strlen( ent->d_name );
|
const int len = strlen(ent->d_name);
|
||||||
if( len > 3 && len < 5
|
if (len > 3 && len < 5 && isdigit(ent->d_name[3])) {
|
||||||
&& isdigit( ent->d_name[3] ) )
|
|
||||||
{
|
|
||||||
// Construct the full path
|
// Construct the full path
|
||||||
char path[PATH_MAX] = {};
|
char path[PATH_MAX] = {};
|
||||||
snprintf( path, sizeof(path), "%s%s/cpufreq/scaling_governor", cpu_base_path, ent->d_name );
|
snprintf(path,
|
||||||
|
sizeof(path),
|
||||||
|
"%s%s/cpufreq/scaling_governor",
|
||||||
|
cpu_base_path,
|
||||||
|
ent->d_name);
|
||||||
|
|
||||||
// Get the real path to the file
|
// Get the real path to the file
|
||||||
// Traditionally cpufreq symlinks to a policy directory that can be shared
|
// Traditionally cpufreq symlinks to a policy directory that can be
|
||||||
// So let's prevent duplicates
|
// shared So let's prevent duplicates
|
||||||
char fullpath[PATH_MAX] = {};
|
char fullpath[PATH_MAX] = {};
|
||||||
const char* ptr = realpath( path, fullpath );
|
const char *ptr = realpath(path, fullpath);
|
||||||
if( fullpath != ptr )
|
if (fullpath != ptr) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Only add if unique
|
|
||||||
for( int i = 0; i < num_governors; i++ )
|
|
||||||
{
|
|
||||||
if( strncmp( fullpath, governors[i], MAX_GOVERNOR_LENGTH ) == 0 )
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy( governors[num_governors], fullpath, MAX_GOVERNOR_LENGTH );
|
// Only add if unique
|
||||||
|
for (int i = 0; i < num_governors; i++) {
|
||||||
|
if (strncmp(fullpath, governors[i], MAX_GOVERNOR_LENGTH) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(governors[num_governors], fullpath, MAX_GOVERNOR_LENGTH);
|
||||||
num_governors++;
|
num_governors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,102 +91,87 @@ static int fetch_governors( char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the current governor state
|
// Get the current governor state
|
||||||
const char* get_gov_state()
|
const char *get_gov_state()
|
||||||
{
|
{
|
||||||
// To be returned
|
// To be returned
|
||||||
static char governor[64] = {0};
|
static char governor[64] = { 0 };
|
||||||
|
|
||||||
// State of all the overnors
|
// State of all the overnors
|
||||||
char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] = {{0}};
|
char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] = { { 0 } };
|
||||||
int num = fetch_governors( governors );
|
int num = fetch_governors(governors);
|
||||||
|
|
||||||
// Check the list
|
// Check the list
|
||||||
for( int i = 0; i < num; i++ )
|
for (int i = 0; i < num; i++) {
|
||||||
{
|
const char *gov = governors[i];
|
||||||
const char* gov = governors[i];
|
|
||||||
|
|
||||||
FILE* f = fopen( gov, "r" );
|
FILE *f = fopen(gov, "r");
|
||||||
if( !f )
|
if (!f) {
|
||||||
{
|
LOG_ERROR("Failed to open file for read %s\n", gov);
|
||||||
LOG_ERROR( "Failed to open file for read %s\n", gov );
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull out the file contents
|
// Pull out the file contents
|
||||||
fseek( f, 0, SEEK_END );
|
fseek(f, 0, SEEK_END);
|
||||||
int length = ftell(f);
|
int length = ftell(f);
|
||||||
fseek( f, 0, SEEK_SET );
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
char contents[length];
|
char contents[length];
|
||||||
|
|
||||||
if( fread(contents, 1, length, f) > 0 )
|
if (fread(contents, 1, length, f) > 0) {
|
||||||
{
|
|
||||||
// Files have a newline
|
// Files have a newline
|
||||||
strtok(contents, "\n");
|
strtok(contents, "\n");
|
||||||
if( strlen(governor) > 0 && strncmp( governor, contents, 64 ) != 0 )
|
if (strlen(governor) > 0 && strncmp(governor, contents, 64) != 0) {
|
||||||
{
|
|
||||||
// Don't handle the mixed case, this shouldn't ever happen
|
// Don't handle the mixed case, this shouldn't ever happen
|
||||||
// But it is a clear sign we shouldn't carry on
|
// But it is a clear sign we shouldn't carry on
|
||||||
LOG_ERROR( "Governors malformed: got \"%s\", expected \"%s\"", contents, governor );
|
LOG_ERROR("Governors malformed: got \"%s\", expected \"%s\"", contents, governor);
|
||||||
return "malformed";
|
return "malformed";
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy( governor, contents, sizeof(governor) );
|
strncpy(governor, contents, sizeof(governor));
|
||||||
}
|
} else {
|
||||||
else
|
LOG_ERROR("Failed to read contents of %s\n", gov);
|
||||||
{
|
|
||||||
LOG_ERROR( "Failed to read contents of %s\n", gov );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose( f );
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return governor;
|
return governor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets all governors to a value
|
// Sets all governors to a value
|
||||||
void set_gov_state( const char* value )
|
void set_gov_state(const char *value)
|
||||||
{
|
{
|
||||||
char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] = {{0}};
|
char governors[MAX_GOVERNORS][MAX_GOVERNOR_LENGTH] = { { 0 } };
|
||||||
int num = fetch_governors( governors );
|
int num = fetch_governors(governors);
|
||||||
|
|
||||||
LOG_MSG( "Setting governors to %s\n", value );
|
LOG_MSG("Setting governors to %s\n", value);
|
||||||
for( int i = 0; i < num; i++ )
|
for (int i = 0; i < num; i++) {
|
||||||
{
|
const char *gov = governors[i];
|
||||||
const char* gov = governors[i];
|
FILE *f = fopen(gov, "w");
|
||||||
FILE* f = fopen( gov, "w" );
|
if (!f) {
|
||||||
if( !f )
|
LOG_ERROR("Failed to open file for write %s\n", gov);
|
||||||
{
|
|
||||||
LOG_ERROR( "Failed to open file for write %s\n", gov );
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( f, "%s\n", value );
|
fprintf(f, "%s\n", value);
|
||||||
fclose( f );
|
fclose(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main entry point
|
// Main entry point
|
||||||
int main( int argc, char *argv[] )
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if( argc < 2 )
|
if (argc < 2) {
|
||||||
{
|
fprintf(stderr, "usage: cpugovctl [get] [set VALUE]\n");
|
||||||
fprintf( stderr, "usage: cpugovctl [get] [set VALUE]\n" );
|
exit(EXIT_FAILURE);
|
||||||
exit( EXIT_FAILURE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( strncmp( argv[1], "get", 3 ) == 0 )
|
if (strncmp(argv[1], "get", 3) == 0) {
|
||||||
{
|
printf("%s", get_gov_state());
|
||||||
printf( "%s", get_gov_state() );
|
} else if (strncmp(argv[1], "set", 3) == 0) {
|
||||||
}
|
const char *value = argv[2];
|
||||||
else if( strncmp( argv[1], "set", 3 ) == 0 )
|
set_gov_state(value);
|
||||||
{
|
} else {
|
||||||
const char* value = argv[2];
|
exit(EXIT_FAILURE);
|
||||||
set_gov_state( value );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
exit( EXIT_FAILURE );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,33 +37,36 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// function to daemonize the process
|
// function to daemonize the process
|
||||||
void daemonize( char* name )
|
void daemonize(char *name)
|
||||||
{
|
{
|
||||||
// Fork once
|
// Fork once
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if( pid < 0 )
|
if (pid < 0) {
|
||||||
FATAL_ERRORNO( "Failed to fork" );
|
FATAL_ERRORNO("Failed to fork");
|
||||||
|
}
|
||||||
|
|
||||||
if( pid != 0 )
|
if (pid != 0) {
|
||||||
{
|
LOG_MSG("Daemon launched...\n");
|
||||||
LOG_MSG( "Daemon launched...\n" );
|
exit(EXIT_SUCCESS);
|
||||||
exit( EXIT_SUCCESS );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fork a second time
|
// Fork a second time
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if( pid < 0 )
|
if (pid < 0) {
|
||||||
FATAL_ERRORNO( "Failed to fork" );
|
FATAL_ERRORNO("Failed to fork");
|
||||||
else if( pid > 0 )
|
} else if (pid > 0) {
|
||||||
exit( EXIT_SUCCESS );
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
// Continue to set up as a daemon
|
// Continue to set up as a daemon
|
||||||
umask(0);
|
umask(0);
|
||||||
if ( setsid() < 0 )
|
if (setsid() < 0) {
|
||||||
FATAL_ERRORNO( "Failed to create process group\n" );
|
FATAL_ERRORNO("Failed to create process group\n");
|
||||||
if ( chdir( "/" ) < 0 )
|
}
|
||||||
FATAL_ERRORNO( "Failed to change to root directory\n" );
|
if (chdir("/") < 0) {
|
||||||
close( STDIN_FILENO );
|
FATAL_ERRORNO("Failed to change to root directory\n");
|
||||||
close( STDOUT_FILENO );
|
}
|
||||||
close( STDERR_FILENO );
|
close(STDIN_FILENO);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
// Function to daemonize the process
|
// Function to daemonize the process
|
||||||
// Exits with error in case of failure
|
// Exits with error in case of failure
|
||||||
void daemonize( char* name );
|
void daemonize(char *name);
|
||||||
|
|
||||||
#endif // _DAEMONIZE_GAMEMODE_H_
|
#endif // _DAEMONIZE_GAMEMODE_H_
|
||||||
|
@ -29,126 +29,125 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#include "dbus_messaging.h"
|
#include "dbus_messaging.h"
|
||||||
#include "logging.h"
|
#include "daemonize.h"
|
||||||
#include "gamemode.h"
|
#include "gamemode.h"
|
||||||
#include "governors.h"
|
#include "governors.h"
|
||||||
#include "daemonize.h"
|
#include "logging.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <systemd/sd-bus.h>
|
#include <systemd/sd-bus.h>
|
||||||
|
|
||||||
// sd-bus tracker values
|
// sd-bus tracker values
|
||||||
static sd_bus* bus = NULL;
|
static sd_bus *bus = NULL;
|
||||||
static sd_bus_slot* slot = NULL;
|
static sd_bus_slot *slot = NULL;
|
||||||
|
|
||||||
// Clean up any resources as needed
|
// Clean up any resources as needed
|
||||||
static void clean_up()
|
static void clean_up()
|
||||||
{
|
{
|
||||||
if( slot )
|
if (slot) {
|
||||||
sd_bus_slot_unref( slot );
|
sd_bus_slot_unref(slot);
|
||||||
|
}
|
||||||
slot = NULL;
|
slot = NULL;
|
||||||
if( bus )
|
if (bus) {
|
||||||
sd_bus_unref( bus );
|
sd_bus_unref(bus);
|
||||||
|
}
|
||||||
bus = NULL;
|
bus = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for RegisterGame
|
// Callback for RegisterGame
|
||||||
static int method_register_game( sd_bus_message *m,
|
static int method_register_game(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
|
||||||
void *userdata,
|
|
||||||
sd_bus_error *ret_error )
|
|
||||||
{
|
{
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
|
|
||||||
int ret = sd_bus_message_read( m, "i", &pid );
|
int ret = sd_bus_message_read(m, "i", &pid);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
{
|
LOG_ERROR("Failed to parse input parameters: %s\n", strerror(-ret));
|
||||||
LOG_ERROR( "Failed to parse input parameters: %s\n", strerror(-ret) );
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
register_game( pid );
|
register_game(pid);
|
||||||
|
|
||||||
return sd_bus_reply_method_return( m, "i", 0 );
|
return sd_bus_reply_method_return(m, "i", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for UnregisterGame
|
// Callback for UnregisterGame
|
||||||
static int method_unregister_game( sd_bus_message *m,
|
static int method_unregister_game(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
|
||||||
void *userdata,
|
|
||||||
sd_bus_error *ret_error )
|
|
||||||
{
|
{
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
|
|
||||||
int ret = sd_bus_message_read( m, "i", &pid );
|
int ret = sd_bus_message_read(m, "i", &pid);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
{
|
LOG_ERROR("Failed to parse input parameters: %s\n", strerror(-ret));
|
||||||
LOG_ERROR( "Failed to parse input parameters: %s\n", strerror(-ret) );
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unregister_game( pid );
|
unregister_game(pid);
|
||||||
|
|
||||||
return sd_bus_reply_method_return( m, "i", 0 );
|
return sd_bus_reply_method_return(m, "i", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vtable for function dispatch
|
// Vtable for function dispatch
|
||||||
static const sd_bus_vtable gamemode_vtable[] = {
|
static const sd_bus_vtable gamemode_vtable[] =
|
||||||
SD_BUS_VTABLE_START( 0 ),
|
{ SD_BUS_VTABLE_START(0),
|
||||||
SD_BUS_METHOD( "RegisterGame", "i", "i", method_register_game, SD_BUS_VTABLE_UNPRIVILEGED ),
|
SD_BUS_METHOD("RegisterGame", "i", "i", method_register_game, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD( "UnregisterGame", "i", "i", method_unregister_game, SD_BUS_VTABLE_UNPRIVILEGED ),
|
SD_BUS_METHOD("UnregisterGame", "i", "i", method_unregister_game, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END };
|
||||||
};
|
|
||||||
|
|
||||||
// Main loop, will not return until something request a quit
|
// Main loop, will not return until something request a quit
|
||||||
void run_dbus_main_loop( bool system_dbus )
|
void run_dbus_main_loop(bool system_dbus)
|
||||||
{
|
{
|
||||||
// Set up function to handle clean up of resources
|
// Set up function to handle clean up of resources
|
||||||
atexit( clean_up );
|
atexit(clean_up);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
// Connec to the desired bus
|
|
||||||
if( system_dbus )
|
|
||||||
ret = sd_bus_open_system( &bus );
|
|
||||||
else
|
|
||||||
ret = sd_bus_open_user( &bus );
|
|
||||||
|
|
||||||
if( ret < 0 )
|
// Connec to the desired bus
|
||||||
FATAL_ERROR( "Failed to connect to the bus: %s", strerror(-ret) );
|
if (system_dbus) {
|
||||||
|
ret = sd_bus_open_system(&bus);
|
||||||
|
} else {
|
||||||
|
ret = sd_bus_open_user(&bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
FATAL_ERROR("Failed to connect to the bus: %s", strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
// Create the object to allow connections
|
// Create the object to allow connections
|
||||||
ret = sd_bus_add_object_vtable( bus,
|
ret = sd_bus_add_object_vtable(bus,
|
||||||
&slot,
|
&slot,
|
||||||
"/com/feralinteractive/GameMode",
|
"/com/feralinteractive/GameMode",
|
||||||
"com.feralinteractive.GameMode",
|
"com.feralinteractive.GameMode",
|
||||||
gamemode_vtable,
|
gamemode_vtable,
|
||||||
NULL );
|
NULL);
|
||||||
|
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
FATAL_ERROR( "Failed to install GameMode object: %s", strerror(-ret) );
|
FATAL_ERROR("Failed to install GameMode object: %s", strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
// Request our name
|
// Request our name
|
||||||
ret = sd_bus_request_name( bus, "com.feralinteractive.GameMode", 0 );
|
ret = sd_bus_request_name(bus, "com.feralinteractive.GameMode", 0);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
FATAL_ERROR( "Failed to acquire service name: %s", strerror(-ret) );
|
FATAL_ERROR("Failed to acquire service name: %s", strerror(-ret));
|
||||||
|
}
|
||||||
|
|
||||||
LOG_MSG( "Successfully initialised bus with name [%s]...\n", "com.feralinteractive.GameMode" );
|
LOG_MSG("Successfully initialised bus with name [%s]...\n", "com.feralinteractive.GameMode");
|
||||||
|
|
||||||
// Now loop, waiting for callbacks
|
// Now loop, waiting for callbacks
|
||||||
for(;;)
|
for (;;) {
|
||||||
{
|
ret = sd_bus_process(bus, NULL);
|
||||||
ret = sd_bus_process( bus, NULL );
|
if (ret < 0) {
|
||||||
if( ret < 0 )
|
FATAL_ERROR("Failure when processing the bus: %s", strerror(-ret));
|
||||||
FATAL_ERROR( "Failure when processing the bus: %s", strerror(-ret) );
|
}
|
||||||
|
|
||||||
// We're done processing
|
// We're done processing
|
||||||
if( ret > 0 )
|
if (ret > 0) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for more
|
// Wait for more
|
||||||
ret = sd_bus_wait( bus, (uint64_t)-1 );
|
ret = sd_bus_wait(bus, (uint64_t)-1);
|
||||||
if( ret < 0 && -ret != EINTR )
|
if (ret < 0 && -ret != EINTR) {
|
||||||
FATAL_ERROR( "Failure when waiting on bus: %s", strerror(-ret) );
|
FATAL_ERROR("Failure when waiting on bus: %s", strerror(-ret));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
// Run the main dbus loop
|
// Run the main dbus loop
|
||||||
// Will not return until finished
|
// Will not return until finished
|
||||||
void run_dbus_main_loop( bool system_dbus );
|
void run_dbus_main_loop(bool system_dbus);
|
||||||
|
|
||||||
#endif // _DBUS_MESSAGING_GAMEMODE_H_
|
#endif // _DBUS_MESSAGING_GAMEMODE_H_
|
||||||
|
@ -29,8 +29,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#include "gamemode.h"
|
#include "gamemode.h"
|
||||||
#include "logging.h"
|
|
||||||
#include "governors.h"
|
#include "governors.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -49,8 +49,8 @@ static void start_alarm_timer();
|
|||||||
// Must be called after init_game_mode
|
// Must be called after init_game_mode
|
||||||
static void enter_game_mode()
|
static void enter_game_mode()
|
||||||
{
|
{
|
||||||
LOG_MSG( "Entering Game Mode...\n" );
|
LOG_MSG("Entering Game Mode...\n");
|
||||||
set_governors( "performance" );
|
set_governors("performance");
|
||||||
|
|
||||||
// Set up the alarm callback
|
// Set up the alarm callback
|
||||||
start_alarm_timer();
|
start_alarm_timer();
|
||||||
@ -60,45 +60,45 @@ static void enter_game_mode()
|
|||||||
// Must be called after an equivelant call to enter_game_mode
|
// Must be called after an equivelant call to enter_game_mode
|
||||||
static void leave_game_mode()
|
static void leave_game_mode()
|
||||||
{
|
{
|
||||||
LOG_MSG( "Leaving Game Mode...\n" );
|
LOG_MSG("Leaving Game Mode...\n");
|
||||||
set_governors( NULL );
|
set_governors(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up an alarm callback to check for current process ids
|
// Set up an alarm callback to check for current process ids
|
||||||
static void alarm_handler( int sig )
|
static void alarm_handler(int sig)
|
||||||
{
|
{
|
||||||
// Quick return if no games, and don't register another callback
|
// Quick return if no games, and don't register another callback
|
||||||
if( num_games == 0 )
|
if (num_games == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if games are alive at all
|
// Check if games are alive at all
|
||||||
for( int i = 0; i < num_games; )
|
for (int i = 0; i < num_games;) {
|
||||||
{
|
|
||||||
int game = game_pids[i];
|
int game = game_pids[i];
|
||||||
|
|
||||||
if( kill( game, 0 ) != 0 )
|
if (kill(game, 0) != 0) {
|
||||||
{
|
LOG_MSG("Removing expired game [%i]...\n", game);
|
||||||
LOG_MSG( "Removing expired game [%i]...\n", game );
|
memmove(&game_pids[i], &game_pids[i + 1], MAX_GAMES - (i + 1));
|
||||||
memmove( &game_pids[i], &game_pids[i+1], MAX_GAMES - (i+1) );
|
|
||||||
num_games--;
|
num_games--;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
i++;
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either trigger another alarm, or reset the governors
|
// Either trigger another alarm, or reset the governors
|
||||||
if( num_games )
|
if (num_games) {
|
||||||
start_alarm_timer();
|
start_alarm_timer();
|
||||||
else
|
} else {
|
||||||
leave_game_mode();
|
leave_game_mode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call to trigger starting the alarm timer for pid checks
|
// Call to trigger starting the alarm timer for pid checks
|
||||||
static void start_alarm_timer()
|
static void start_alarm_timer()
|
||||||
{
|
{
|
||||||
// Set up process check alarms
|
// Set up process check alarms
|
||||||
signal( SIGALRM, alarm_handler );
|
signal(SIGALRM, alarm_handler);
|
||||||
alarm( wakeup_timer );
|
alarm(wakeup_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intialise any game mode needs
|
// Intialise any game mode needs
|
||||||
@ -106,72 +106,68 @@ void init_game_mode()
|
|||||||
{
|
{
|
||||||
// Read current governer state before setting up any message handling
|
// Read current governer state before setting up any message handling
|
||||||
update_initial_gov_state();
|
update_initial_gov_state();
|
||||||
LOG_MSG( "governor is set to [%s]\n", get_initial_governor() );
|
LOG_MSG("governor is set to [%s]\n", get_initial_governor());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on exit to clean up the governors if appropriate
|
// Called on exit to clean up the governors if appropriate
|
||||||
void term_game_mode()
|
void term_game_mode()
|
||||||
{
|
{
|
||||||
if( num_games )
|
if (num_games) {
|
||||||
leave_game_mode();
|
leave_game_mode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a game pid with the game mode
|
// Register a game pid with the game mode
|
||||||
// Will trigger enter game mode if appropriate
|
// Will trigger enter game mode if appropriate
|
||||||
void register_game( int pid )
|
void register_game(int pid)
|
||||||
{
|
{
|
||||||
// Check for duplicates
|
// Check for duplicates
|
||||||
for( int i = 0; i < num_games; i++ )
|
for (int i = 0; i < num_games; i++) {
|
||||||
{
|
if (game_pids[i] == pid) {
|
||||||
if( game_pids[i] == pid )
|
LOG_ERROR("Addition requested for already known process [%i]\n", pid);
|
||||||
{
|
|
||||||
LOG_ERROR( "Addition requested for already known process [%i]\n", pid );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we've not already hit max
|
// Check we've not already hit max
|
||||||
if( num_games == MAX_GAMES )
|
if (num_games == MAX_GAMES) {
|
||||||
{
|
LOG_ERROR("Max games (%i) reached, could not add [%i]\n", MAX_GAMES, pid);
|
||||||
LOG_ERROR( "Max games (%i) reached, could not add [%i]\n", MAX_GAMES, pid );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the game to the database
|
// Add the game to the database
|
||||||
LOG_MSG( "Adding game: %i\n", pid );
|
LOG_MSG("Adding game: %i\n", pid);
|
||||||
game_pids[num_games] = pid;
|
game_pids[num_games] = pid;
|
||||||
num_games++;
|
num_games++;
|
||||||
|
|
||||||
if( num_games == 1 )
|
if (num_games == 1) {
|
||||||
enter_game_mode();
|
enter_game_mode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a game from game mode
|
// Remove a game from game mode
|
||||||
// Will exit game mode if appropriate
|
// Will exit game mode if appropriate
|
||||||
void unregister_game( int pid )
|
void unregister_game(int pid)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
// Check list even contains this entry
|
// Check list even contains this entry
|
||||||
for( int i = 0; i < num_games; i++ )
|
for (int i = 0; i < num_games; i++) {
|
||||||
{
|
if (game_pids[i] == pid) {
|
||||||
if( game_pids[i] == pid )
|
LOG_MSG("Removing game: %i\n", pid);
|
||||||
{
|
memmove(&game_pids[i], &game_pids[i + 1], MAX_GAMES - (i + 1));
|
||||||
LOG_MSG( "Removing game: %i\n", pid );
|
|
||||||
memmove( &game_pids[i], &game_pids[i+1], MAX_GAMES - (i+1) );
|
|
||||||
num_games--;
|
num_games--;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !found )
|
if (!found) {
|
||||||
{
|
LOG_ERROR("Removal requested for unknown process [%i]\n", pid);
|
||||||
LOG_ERROR( "Removal requested for unknown process [%i]\n", pid );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave game mode if needed
|
// Leave game mode if needed
|
||||||
if( num_games == 0 )
|
if (num_games == 0) {
|
||||||
leave_game_mode();
|
leave_game_mode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ void term_game_mode();
|
|||||||
|
|
||||||
// Add or remove games to the tracker
|
// Add or remove games to the tracker
|
||||||
// Tracker will automatically start and stop game mode as appropriate
|
// Tracker will automatically start and stop game mode as appropriate
|
||||||
void register_game( int pid );
|
void register_game(int pid);
|
||||||
void unregister_game( int pid );
|
void unregister_game(int pid);
|
||||||
|
|
||||||
#endif // _GAME_MODE_GAMEMODE_H_
|
#endif // _GAME_MODE_GAMEMODE_H_
|
||||||
|
@ -31,48 +31,50 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "governors.h"
|
#include "governors.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
#include <linux/limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/limits.h>
|
|
||||||
|
|
||||||
static char initial[32];
|
static char initial[32];
|
||||||
|
|
||||||
// Store the initial governor state to be referenced later
|
// Store the initial governor state to be referenced later
|
||||||
void update_initial_gov_state()
|
void update_initial_gov_state()
|
||||||
{
|
{
|
||||||
static char* command = "cpugovctl get";
|
static char *command = "cpugovctl get";
|
||||||
|
|
||||||
FILE* f = popen( command, "r" );
|
FILE *f = popen(command, "r");
|
||||||
if( !f )
|
if (!f) {
|
||||||
FATAL_ERRORNO( "Failed to launch \"%s\" script", command );
|
FATAL_ERRORNO("Failed to launch \"%s\" script", command);
|
||||||
|
}
|
||||||
|
|
||||||
if( !fgets( initial, sizeof(initial)-1, f ) )
|
if (!fgets(initial, sizeof(initial) - 1, f)) {
|
||||||
FATAL_ERROR( "Failed to get output from \"%s\"", command );
|
FATAL_ERROR("Failed to get output from \"%s\"", command);
|
||||||
|
}
|
||||||
|
|
||||||
pclose(f);
|
pclose(f);
|
||||||
|
|
||||||
strtok( initial, "\n" );
|
strtok(initial, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets all governors to a value, if NULL argument provided, will reset them back
|
// Sets all governors to a value, if NULL argument provided, will reset them back
|
||||||
void set_governors( const char* value )
|
void set_governors(const char *value)
|
||||||
{
|
{
|
||||||
const char* newval = value ? value : initial;
|
const char *newval = value ? value : initial;
|
||||||
LOG_MSG("Setting governors to %s\n", newval ? newval : "initial values");
|
LOG_MSG("Setting governors to %s\n", newval ? newval : "initial values");
|
||||||
|
|
||||||
char command[PATH_MAX] = {};
|
char command[PATH_MAX] = {};
|
||||||
snprintf( command, sizeof(command), "cpugovctl set %s", newval );
|
snprintf(command, sizeof(command), "cpugovctl set %s", newval);
|
||||||
|
|
||||||
FILE* f = popen( command, "r" );
|
FILE *f = popen(command, "r");
|
||||||
if( !f )
|
if (!f) {
|
||||||
FATAL_ERRORNO( "Failed to launch %s script", command );
|
FATAL_ERRORNO("Failed to launch %s script", command);
|
||||||
|
}
|
||||||
|
|
||||||
pclose(f);
|
pclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the initial governor
|
// Return the initial governor
|
||||||
const char* get_initial_governor()
|
const char *get_initial_governor()
|
||||||
{
|
{
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
void update_initial_gov_state();
|
void update_initial_gov_state();
|
||||||
|
|
||||||
// Get the initial governor state
|
// Get the initial governor state
|
||||||
const char* get_initial_governor();
|
const char *get_initial_governor();
|
||||||
|
|
||||||
// Sets all governors to a value, if null argument provided, will reset them back
|
// Sets all governors to a value, if null argument provided, will reset them back
|
||||||
void set_governors( const char* value );
|
void set_governors(const char *value);
|
||||||
|
|
||||||
#endif // _GOVERNORS_GAMEMODE_H_
|
#endif // _GOVERNORS_GAMEMODE_H_
|
||||||
|
@ -34,10 +34,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
static bool use_syslog = false;
|
static bool use_syslog = false;
|
||||||
|
|
||||||
// Control if we want to use the system logger
|
// Control if we want to use the system logger
|
||||||
void set_use_syslog( const char* name )
|
void set_use_syslog(const char *name)
|
||||||
{
|
{
|
||||||
// Open the syslog
|
// Open the syslog
|
||||||
openlog( name, LOG_PID, LOG_DAEMON );
|
openlog(name, LOG_PID, LOG_DAEMON);
|
||||||
use_syslog = true;
|
use_syslog = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,28 +32,50 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define _LOGGING_GAMEMODE_H_
|
#define _LOGGING_GAMEMODE_H_
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
// Logging helpers
|
// Logging helpers
|
||||||
#define PLOG_MSG( msg, ... ) printf( msg, ##__VA_ARGS__ )
|
#define PLOG_MSG(msg, ...) printf(msg, ##__VA_ARGS__)
|
||||||
#define SYSLOG_MSG( msg, ... ) syslog( LOG_INFO, msg, ##__VA_ARGS__ )
|
#define SYSLOG_MSG(msg, ...) syslog(LOG_INFO, msg, ##__VA_ARGS__)
|
||||||
#define LOG_MSG( msg, ... ) do { if( get_use_syslog() ) SYSLOG_MSG( msg, ##__VA_ARGS__ ); else PLOG_MSG( msg, ##__VA_ARGS__ ); } while(0)
|
#define LOG_MSG(msg, ...) \
|
||||||
|
do { \
|
||||||
|
if (get_use_syslog()) { \
|
||||||
|
SYSLOG_MSG(msg, ##__VA_ARGS__); \
|
||||||
|
} else { \
|
||||||
|
PLOG_MSG(msg, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define PLOG_ERROR( msg, ... ) fprintf( stderr, msg, ##__VA_ARGS__ )
|
#define PLOG_ERROR(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__)
|
||||||
#define SYSLOG_ERROR( msg, ... ) syslog( LOG_ERR, msg, ##__VA_ARGS__ )
|
#define SYSLOG_ERROR(msg, ...) syslog(LOG_ERR, msg, ##__VA_ARGS__)
|
||||||
#define LOG_ERROR( msg, ... ) do { if( get_use_syslog() ) SYSLOG_MSG( msg, ##__VA_ARGS__ ); else PLOG_MSG( msg, ##__VA_ARGS__ ); } while(0)
|
#define LOG_ERROR(msg, ...) \
|
||||||
|
do { \
|
||||||
|
if (get_use_syslog()) { \
|
||||||
|
SYSLOG_MSG(msg, ##__VA_ARGS__); \
|
||||||
|
} else { \
|
||||||
|
PLOG_MSG(msg, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Fatal errors trigger an exit
|
// Fatal errors trigger an exit
|
||||||
#define FATAL_ERRORNO( msg, ... ) do { LOG_ERROR( msg " (%s)\n", ##__VA_ARGS__, strerror(errno) ); exit(EXIT_FAILURE); } while(0)
|
#define FATAL_ERRORNO(msg, ...) \
|
||||||
#define FATAL_ERROR( msg, ... ) do { LOG_ERROR( msg, ##__VA_ARGS__ ); exit(EXIT_FAILURE); } while(0)
|
do { \
|
||||||
|
LOG_ERROR(msg " (%s)\n", ##__VA_ARGS__, strerror(errno)); \
|
||||||
|
exit(EXIT_FAILURE); \
|
||||||
|
} while (0)
|
||||||
|
#define FATAL_ERROR(msg, ...) \
|
||||||
|
do { \
|
||||||
|
LOG_ERROR(msg, ##__VA_ARGS__); \
|
||||||
|
exit(EXIT_FAILURE); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Control if we want to use the system logger
|
// Control if we want to use the system logger
|
||||||
void set_use_syslog( const char* name );
|
void set_use_syslog(const char *name);
|
||||||
bool get_use_syslog();
|
bool get_use_syslog();
|
||||||
|
|
||||||
#endif //_LOGGING_GAMEMODE_H_
|
#endif //_LOGGING_GAMEMODE_H_
|
||||||
|
@ -29,71 +29,72 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
// Simple daemon to allow user space programs to control the CPU governors
|
// Simple daemon to allow user space programs to control the CPU governors
|
||||||
#include "gamemode.h"
|
|
||||||
#include "dbus_messaging.h"
|
|
||||||
#include "logging.h"
|
|
||||||
#include "daemonize.h"
|
#include "daemonize.h"
|
||||||
|
#include "dbus_messaging.h"
|
||||||
|
#include "gamemode.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
static void sigint_handler(int signo)
|
static void sigint_handler(int signo)
|
||||||
{
|
{
|
||||||
LOG_MSG( "Quitting by request...\n" );
|
LOG_MSG("Quitting by request...\n");
|
||||||
|
|
||||||
// Terminate the game mode
|
// Terminate the game mode
|
||||||
term_game_mode();
|
term_game_mode();
|
||||||
|
|
||||||
exit( EXIT_SUCCESS );
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main entry point
|
// Main entry point
|
||||||
int main( int argc, char *argv[] )
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Gather command line options
|
// Gather command line options
|
||||||
bool daemon = false;
|
bool daemon = false;
|
||||||
bool system_dbus = false;
|
bool system_dbus = false;
|
||||||
bool use_syslog = false;
|
bool use_syslog = false;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
while( ( opt = getopt( argc, argv, "dsl") ) != -1 )
|
while ((opt = getopt(argc, argv, "dsl")) != -1) {
|
||||||
{
|
switch (opt) {
|
||||||
switch( opt )
|
case 'd':
|
||||||
{
|
daemon = true;
|
||||||
case 'd':
|
break;
|
||||||
daemon = true;
|
case 's':
|
||||||
break;
|
system_dbus = true;
|
||||||
case 's':
|
break;
|
||||||
system_dbus = true;
|
case 'l':
|
||||||
break;
|
use_syslog = true;
|
||||||
case 'l':
|
break;
|
||||||
use_syslog = true;
|
default:
|
||||||
break;
|
fprintf(stderr, "Usage: %s [-d] [-s] [-l]\n", argv[0]);
|
||||||
default:
|
exit(EXIT_FAILURE);
|
||||||
fprintf( stderr, "Usage: %s [-d] [-s] [-l]\n", argv[0] );
|
break;
|
||||||
exit( EXIT_FAILURE );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use syslog if requested
|
// Use syslog if requested
|
||||||
if( use_syslog )
|
if (use_syslog) {
|
||||||
set_use_syslog( argv[0] );
|
set_use_syslog(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// Daemonize ourselves first if asked
|
// Daemonize ourselves first if asked
|
||||||
if ( daemon )
|
if (daemon) {
|
||||||
daemonize( argv[0] );
|
daemonize(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the game mode
|
// Set up the game mode
|
||||||
init_game_mode();
|
init_game_mode();
|
||||||
|
|
||||||
// Set up the SIGINT handler
|
// Set up the SIGINT handler
|
||||||
if( signal( SIGINT, sigint_handler ) == SIG_ERR )
|
if (signal(SIGINT, sigint_handler) == SIG_ERR) {
|
||||||
FATAL_ERRORNO( "Could not catch SIGINT" );
|
FATAL_ERRORNO("Could not catch SIGINT");
|
||||||
|
}
|
||||||
|
|
||||||
// Run the main dbus message loop
|
// Run the main dbus message loop
|
||||||
run_dbus_main_loop( system_dbus );
|
run_dbus_main_loop(system_dbus);
|
||||||
|
|
||||||
// Log we're finished
|
// Log we're finished
|
||||||
LOG_MSG( "Quitting naturally...\n" );
|
LOG_MSG("Quitting naturally...\n");
|
||||||
}
|
}
|
||||||
|
@ -30,19 +30,21 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*/
|
*/
|
||||||
#include "gamemode_client.h"
|
#include "gamemode_client.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(){
|
int main()
|
||||||
|
{
|
||||||
// Request we start game mode
|
// Request we start game mode
|
||||||
if( gamemode_request_start() != 0 )
|
if (gamemode_request_start() != 0) {
|
||||||
printf( "Failed to request gamemode start: %s...\n", gamemode_error_string() );
|
printf("Failed to request gamemode start: %s...\n", gamemode_error_string());
|
||||||
|
}
|
||||||
|
|
||||||
// Simulate running a game
|
// Simulate running a game
|
||||||
sleep( 10 );
|
sleep(10);
|
||||||
|
|
||||||
// Request we end game mode (optional)
|
// Request we end game mode (optional)
|
||||||
if( gamemode_request_end() != 0 )
|
if (gamemode_request_end() != 0) {
|
||||||
printf( "Failed to request gamemode end: %s...\n", gamemode_error_string() );
|
printf("Failed to request gamemode end: %s...\n", gamemode_error_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,49 +28,57 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <systemd/sd-bus.h>
|
#include <systemd/sd-bus.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
// Storage for error strings
|
// Storage for error strings
|
||||||
static char error_string[512] = {};
|
static char error_string[512] = {};
|
||||||
|
|
||||||
// Simple requestor function for a gamemode
|
// Simple requestor function for a gamemode
|
||||||
static int gamemode_request( const char* function )
|
static int gamemode_request(const char *function)
|
||||||
{
|
{
|
||||||
sd_bus_message* msg = NULL;
|
sd_bus_message *msg = NULL;
|
||||||
sd_bus* bus = NULL;
|
sd_bus *bus = NULL;
|
||||||
|
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
// Open the user bus
|
// Open the user bus
|
||||||
int ret = sd_bus_open_user(&bus);
|
int ret = sd_bus_open_user(&bus);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
snprintf( error_string, sizeof(error_string), "Could not connect to bus: %s", strerror(-ret) );
|
snprintf(error_string,
|
||||||
else
|
sizeof(error_string),
|
||||||
{
|
"Could not connect to bus: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
} else {
|
||||||
// Attempt to send the requested function
|
// Attempt to send the requested function
|
||||||
ret = sd_bus_call_method( bus,
|
ret = sd_bus_call_method(bus,
|
||||||
"com.feralinteractive.GameMode",
|
"com.feralinteractive.GameMode",
|
||||||
"/com/feralinteractive/GameMode",
|
"/com/feralinteractive/GameMode",
|
||||||
"com.feralinteractive.GameMode",
|
"com.feralinteractive.GameMode",
|
||||||
function,
|
function,
|
||||||
NULL,
|
NULL,
|
||||||
&msg,
|
&msg,
|
||||||
"i",
|
"i",
|
||||||
getpid() );
|
getpid());
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
snprintf( error_string, sizeof(error_string), "Could not call method on bus: %s", strerror(-ret) );
|
snprintf(error_string,
|
||||||
else
|
sizeof(error_string),
|
||||||
{
|
"Could not call method on bus: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
} else {
|
||||||
// Read the reply
|
// Read the reply
|
||||||
ret = sd_bus_message_read( msg, "i", &result );
|
ret = sd_bus_message_read(msg, "i", &result);
|
||||||
if( ret < 0 )
|
if (ret < 0) {
|
||||||
snprintf( error_string, sizeof(error_string), "Failure to parse response: %s", strerror(-ret) );
|
snprintf(error_string,
|
||||||
|
sizeof(error_string),
|
||||||
|
"Failure to parse response: %s",
|
||||||
|
strerror(-ret));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +86,7 @@ static int gamemode_request( const char* function )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the error string
|
// Get the error string
|
||||||
extern const char* real_gamemode_error_string()
|
extern const char *real_gamemode_error_string()
|
||||||
{
|
{
|
||||||
return error_string;
|
return error_string;
|
||||||
}
|
}
|
||||||
@ -86,12 +94,11 @@ extern const char* real_gamemode_error_string()
|
|||||||
// Wrapper to call RegisterGame
|
// Wrapper to call RegisterGame
|
||||||
extern int real_gamemode_request_start()
|
extern int real_gamemode_request_start()
|
||||||
{
|
{
|
||||||
return gamemode_request( "RegisterGame" );
|
return gamemode_request("RegisterGame");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper to call UnregisterGame
|
// Wrapper to call UnregisterGame
|
||||||
extern int real_gamemode_request_end()
|
extern int real_gamemode_request_end()
|
||||||
{
|
{
|
||||||
return gamemode_request( "UnregisterGame" );
|
return gamemode_request("UnregisterGame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,44 +47,52 @@ char _client_error_string[512] = {};
|
|||||||
int _libgamemode_loaded = 1;
|
int _libgamemode_loaded = 1;
|
||||||
|
|
||||||
// Typedefs for the functions to load
|
// Typedefs for the functions to load
|
||||||
typedef int(*_gamemode_request_start)();
|
typedef int (*_gamemode_request_start)();
|
||||||
typedef int(*_gamemode_request_end)();
|
typedef int (*_gamemode_request_end)();
|
||||||
typedef const char*(*_gamemode_error_string)();
|
typedef const char *(*_gamemode_error_string)();
|
||||||
|
|
||||||
// Storage for functors
|
// Storage for functors
|
||||||
_gamemode_request_start _REAL_gamemode_request_start = NULL;
|
_gamemode_request_start _REAL_gamemode_request_start = NULL;
|
||||||
_gamemode_request_end _REAL_gamemode_request_end = NULL;
|
_gamemode_request_end _REAL_gamemode_request_end = NULL;
|
||||||
_gamemode_error_string _REAL_gamemode_error_string = NULL;
|
_gamemode_error_string _REAL_gamemode_error_string = NULL;
|
||||||
|
|
||||||
// Loads libgamemode and needed functions
|
// Loads libgamemode and needed functions
|
||||||
// returns 0 on success and -1 on failure
|
// returns 0 on success and -1 on failure
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline)) inline int _load_libgamemode()
|
||||||
inline int _load_libgamemode()
|
|
||||||
{
|
{
|
||||||
// We start at 1, 0 is a success and -1 is a fail
|
// We start at 1, 0 is a success and -1 is a fail
|
||||||
if ( _libgamemode_loaded != 1 )
|
if (_libgamemode_loaded != 1) {
|
||||||
return _libgamemode_loaded;
|
return _libgamemode_loaded;
|
||||||
|
}
|
||||||
|
|
||||||
void* libgamemode = NULL;
|
void *libgamemode = NULL;
|
||||||
|
|
||||||
// Try and load libgamemode
|
// Try and load libgamemode
|
||||||
libgamemode = dlopen( "libgamemode.so", RTLD_NOW );
|
libgamemode = dlopen("libgamemode.so", RTLD_NOW);
|
||||||
if( !libgamemode )
|
if (!libgamemode) {
|
||||||
snprintf( _client_error_string, sizeof(_client_error_string), "dylopen failed - %s", dlerror() );
|
snprintf(_client_error_string,
|
||||||
else
|
sizeof(_client_error_string),
|
||||||
{
|
"dylopen failed - %s",
|
||||||
_REAL_gamemode_request_start = (_gamemode_request_start)dlsym( libgamemode, "real_gamemode_request_start" );
|
dlerror());
|
||||||
_REAL_gamemode_request_end = (_gamemode_request_end) dlsym( libgamemode, "real_gamemode_request_end" );
|
} else {
|
||||||
_REAL_gamemode_error_string = (_gamemode_error_string) dlsym( libgamemode, "real_gamemode_error_string" );
|
_REAL_gamemode_request_start =
|
||||||
|
(_gamemode_request_start)dlsym(libgamemode, "real_gamemode_request_start");
|
||||||
|
_REAL_gamemode_request_end =
|
||||||
|
(_gamemode_request_end)dlsym(libgamemode, "real_gamemode_request_end");
|
||||||
|
_REAL_gamemode_error_string =
|
||||||
|
(_gamemode_error_string)dlsym(libgamemode, "real_gamemode_error_string");
|
||||||
|
|
||||||
// Verify we have the functions we want
|
// Verify we have the functions we want
|
||||||
if( _REAL_gamemode_request_start && _REAL_gamemode_request_end && _REAL_gamemode_error_string )
|
if (_REAL_gamemode_request_start && _REAL_gamemode_request_end &&
|
||||||
{
|
_REAL_gamemode_error_string) {
|
||||||
_libgamemode_loaded = 0;
|
_libgamemode_loaded = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
snprintf(_client_error_string,
|
||||||
|
sizeof(_client_error_string),
|
||||||
|
"dlsym failed - %s",
|
||||||
|
dlerror());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
snprintf( _client_error_string, sizeof(_client_error_string), "dlsym failed - %s", dlerror() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_libgamemode_loaded = -1;
|
_libgamemode_loaded = -1;
|
||||||
@ -92,12 +100,12 @@ inline int _load_libgamemode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Redirect to the real libgamemode
|
// Redirect to the real libgamemode
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline)) inline const char *gamemode_error_string()
|
||||||
inline const char* gamemode_error_string()
|
|
||||||
{
|
{
|
||||||
// If we fail to load the system gamemode, return our error string
|
// If we fail to load the system gamemode, return our error string
|
||||||
if( _load_libgamemode() < 0 )
|
if (_load_libgamemode() < 0) {
|
||||||
return _client_error_string;
|
return _client_error_string;
|
||||||
|
}
|
||||||
|
|
||||||
return _REAL_gamemode_error_string();
|
return _REAL_gamemode_error_string();
|
||||||
}
|
}
|
||||||
@ -108,24 +116,21 @@ inline const char* gamemode_error_string()
|
|||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
__attribute__((constructor))
|
__attribute__((constructor))
|
||||||
#else
|
#else
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline)) inline
|
||||||
inline
|
|
||||||
#endif
|
#endif
|
||||||
int gamemode_request_start()
|
int gamemode_request_start()
|
||||||
{
|
{
|
||||||
// Need to load gamemode
|
// Need to load gamemode
|
||||||
if( _load_libgamemode() < 0 )
|
if (_load_libgamemode() < 0) {
|
||||||
{
|
|
||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
fprintf( stderr, "gamemodeauto: %s\n", gamemode_error_string() );
|
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _REAL_gamemode_request_start() < 0 )
|
if (_REAL_gamemode_request_start() < 0) {
|
||||||
{
|
|
||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
fprintf( stderr, "gamemodeauto: %s\n", gamemode_error_string() );
|
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -137,24 +142,21 @@ int gamemode_request_start()
|
|||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
__attribute__((destructor))
|
__attribute__((destructor))
|
||||||
#else
|
#else
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline)) inline
|
||||||
inline
|
|
||||||
#endif
|
#endif
|
||||||
int gamemode_request_end()
|
int gamemode_request_end()
|
||||||
{
|
{
|
||||||
// Need to load gamemode
|
// Need to load gamemode
|
||||||
if( _load_libgamemode() < 0 )
|
if (_load_libgamemode() < 0) {
|
||||||
{
|
|
||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
fprintf( stderr, "gamemodeauto: %s\n", gamemode_error_string() );
|
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _REAL_gamemode_request_end() < 0 )
|
if (_REAL_gamemode_request_end() < 0) {
|
||||||
{
|
|
||||||
#ifdef GAMEMODE_AUTO
|
#ifdef GAMEMODE_AUTO
|
||||||
fprintf( stderr, "gamemodeauto: %s\n", gamemode_error_string() );
|
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user