diff --git a/src/program/Context.h b/src/program/Context.h index 40f59e0a7..90ec473ec 100644 --- a/src/program/Context.h +++ b/src/program/Context.h @@ -147,6 +147,9 @@ struct Context { /* Indicate if at least one savestate was performed, for backtrack savestate */ bool didASavestate = false; + + /* Socket filename */ + std::string socket_filename; }; #endif diff --git a/src/program/GameLoop.cpp b/src/program/GameLoop.cpp index d76e09a4c..c9e0f0e45 100644 --- a/src/program/GameLoop.cpp +++ b/src/program/GameLoop.cpp @@ -184,9 +184,9 @@ void GameLoop::init() remove_savestates(context); /* Remove the file socket */ - int err = removeSocket(); + int err = removeSocket(context->socket_filename); if (err != 0) - emit alertToShow(QString("Could not remove socket file /tmp/libTAS.socket: %2").arg(strerror(err))); + emit alertToShow(QString("Could not remove socket file %1: %2").arg(context->socket_filename.c_str(), strerror(err))); /* Init savestate list */ SaveStateList::init(context); @@ -268,7 +268,7 @@ void GameLoop::init() void GameLoop::initProcessMessages() { /* Connect to the socket between the program and the game */ - initSocketProgram(); + initSocketProgram(context->socket_filename); /* Receive informations from the game */ int message = receiveMessage(); diff --git a/src/program/GameThread.cpp b/src/program/GameThread.cpp index 39e7ab2ee..0ad0e2923 100644 --- a/src/program/GameThread.cpp +++ b/src/program/GameThread.cpp @@ -67,6 +67,11 @@ void GameThread::launch(Context *context) */ setenv("PWD", newdir.c_str(), 1); + /* Set the LIBTAS_SOCKET environment variable to context->socket_filename + * so that the game knows what the socket is called + */ + setenv("LIBTAS_SOCKET", context->socket_filename.c_str(), 1); + /* Set where stderr of the game is redirected */ int fd; std::string logfile = context->gamepath + ".log"; diff --git a/src/program/main.cpp b/src/program/main.cpp index f1e772818..5471b5fe0 100644 --- a/src/program/main.cpp +++ b/src/program/main.cpp @@ -260,6 +260,11 @@ int main(int argc, char **argv) } } + /* Randomize socket filename */ + char templ[] = "/tmp/libTAS-XXXXXX"; + context.socket_filename = mkdtemp(templ); + context.socket_filename += "/socket"; + /* Create the working directories */ char *path = getenv("XDG_CONFIG_HOME"); if (path) { diff --git a/src/shared/sockethelpers.cpp b/src/shared/sockethelpers.cpp index b89445a47..760635e1a 100644 --- a/src/shared/sockethelpers.cpp +++ b/src/shared/sockethelpers.cpp @@ -35,8 +35,6 @@ #include #endif -#define SOCKET_FILENAME "/tmp/libTAS.socket" - #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif @@ -48,20 +46,21 @@ static int socket_fd = 0; static std::mutex mutex; -int removeSocket(void) { - int ret = unlink(SOCKET_FILENAME); +int removeSocket(const std::string& socket_filename) { + int ret = unlink(socket_filename.c_str()); if ((ret == -1) && (errno != ENOENT)) return errno; return 0; } -bool initSocketProgram(void) +bool initSocketProgram(const std::string& socket_filename) { #ifdef __unix__ - const struct sockaddr_un addr = { AF_UNIX, SOCKET_FILENAME }; + struct sockaddr_un addr = { AF_UNIX }; #elif defined(__APPLE__) && defined(__MACH__) - const struct sockaddr_un addr = { sizeof(struct sockaddr_un), AF_UNIX, SOCKET_FILENAME }; + struct sockaddr_un addr = { sizeof(struct sockaddr_un), AF_UNIX }; #endif + strncpy(addr.sun_path, socket_filename.c_str(), sizeof(addr.sun_path)); socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); struct timespec tim = {0, 500L*1000L*1000L}; @@ -85,22 +84,30 @@ bool initSocketProgram(void) return true; } +std::string getSocketFilenameGame(void) +{ + return getenv("LIBTAS_SOCKET"); +} + bool initSocketGame(void) { + std::string socket_filename = getSocketFilenameGame(); + /* Check if socket file already exists. If so, it is probably because * the link is already done in another process of the game. * In this case, we just return immediately. */ struct stat st; - int result = stat(SOCKET_FILENAME, &st); + int result = stat(socket_filename.c_str(), &st); if (result == 0) return false; #ifdef __unix__ - const struct sockaddr_un addr = { AF_UNIX, SOCKET_FILENAME }; + struct sockaddr_un addr = { AF_UNIX }; #elif defined(__APPLE__) && defined(__MACH__) - const struct sockaddr_un addr = { sizeof(struct sockaddr_un), AF_UNIX, SOCKET_FILENAME }; + struct sockaddr_un addr = { sizeof(struct sockaddr_un), AF_UNIX }; #endif + strncpy(addr.sun_path, socket_filename.c_str(), sizeof(addr.sun_path)); const int tmp_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (bind(tmp_fd, reinterpret_cast(&addr), sizeof(struct sockaddr_un))) { diff --git a/src/shared/sockethelpers.h b/src/shared/sockethelpers.h index 366ee767f..3847b3ef8 100644 --- a/src/shared/sockethelpers.h +++ b/src/shared/sockethelpers.h @@ -24,10 +24,15 @@ #include /* Remove the socket file and return error */ -int removeSocket(); +int removeSocket(const std::string& socket_filename); + +/* Returns the socket filename from environment variable (in the game, for + * program use context->socket_filename) + */ +std::string getSocketFilenameGame(void); /* Initiate a socket connection with the game */ -bool initSocketProgram(void); +bool initSocketProgram(const std::string& socket_filename); /* Initiate a socket connection with libTAS */ bool initSocketGame(void);