Extract util function to build a local file path

Finding a local file in the scrcpy directory may be useful for files
other than scrcpy-server in the future.
This commit is contained in:
Romain Vimont 2021-10-22 18:51:20 +02:00
parent a7e41b0f85
commit 7229e3cce0
3 changed files with 49 additions and 38 deletions

View file

@ -3,7 +3,6 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <libgen.h>
#include <stdio.h> #include <stdio.h>
#include <SDL2/SDL_timer.h> #include <SDL2/SDL_timer.h>
#include <SDL2/SDL_platform.h> #include <SDL2/SDL_platform.h>
@ -51,48 +50,13 @@ get_server_path(void) {
// the absolute path is hardcoded // the absolute path is hardcoded
return server_path; return server_path;
#else #else
char *server_path = get_local_file_path(SERVER_FILENAME);
// use scrcpy-server in the same directory as the executable
char *executable_path = get_executable_path();
if (!executable_path) {
LOGE("Could not get executable path, "
"using " SERVER_FILENAME " from current directory");
// not found, use current directory
return strdup(SERVER_FILENAME);
}
// dirname() does not work correctly everywhere, so get the parent
// directory manually.
// See <https://github.com/Genymobile/scrcpy/issues/2619>
char *p = strrchr(executable_path, PATH_SEPARATOR);
if (!p) {
LOGE("Unexpected executable path: \"%s\" (it should contain a '%c')",
executable_path, PATH_SEPARATOR);
free(executable_path);
return strdup(SERVER_FILENAME);
}
*p = '\0'; // modify executable_path in place
char *dir = executable_path;
size_t dirlen = strlen(dir);
// sizeof(SERVER_FILENAME) gives statically the size including the null byte
size_t len = dirlen + 1 + sizeof(SERVER_FILENAME);
char *server_path = malloc(len);
if (!server_path) { if (!server_path) {
LOGE("Could not alloc server path string, " LOGE("Could not get local file path, "
"using " SERVER_FILENAME " from current directory"); "using " SERVER_FILENAME " from current directory");
free(executable_path);
return strdup(SERVER_FILENAME); return strdup(SERVER_FILENAME);
} }
memcpy(server_path, dir, dirlen);
server_path[dirlen] = PATH_SEPARATOR;
memcpy(&server_path[dirlen + 1], SERVER_FILENAME, sizeof(SERVER_FILENAME));
// the final null byte has been copied with SERVER_FILENAME
free(executable_path);
LOGD("Using server (portable): %s", server_path); LOGD("Using server (portable): %s", server_path);
return server_path; return server_path;
#endif #endif

View file

@ -1,5 +1,6 @@
#include "process.h" #include "process.h"
#include <libgen.h>
#include "log.h" #include "log.h"
bool bool
@ -19,3 +20,44 @@ process_check_success(process_t proc, const char *name, bool close) {
} }
return true; return true;
} }
char *
get_local_file_path(const char *name) {
char *executable_path = get_executable_path();
if (!executable_path) {
return NULL;
}
// dirname() does not work correctly everywhere, so get the parent
// directory manually.
// See <https://github.com/Genymobile/scrcpy/issues/2619>
char *p = strrchr(executable_path, PATH_SEPARATOR);
if (!p) {
LOGE("Unexpected executable path: \"%s\" (it should contain a '%c')",
executable_path, PATH_SEPARATOR);
free(executable_path);
return NULL;
}
*p = '\0'; // modify executable_path in place
char *dir = executable_path;
size_t dirlen = strlen(dir);
size_t namelen = strlen(name);
size_t len = dirlen + namelen + 2; // +2: '/' and '\0'
char *file_path = malloc(len);
if (!file_path) {
LOGE("Could not alloc path");
free(executable_path);
return NULL;
}
memcpy(file_path, dir, dirlen);
file_path[dirlen] = PATH_SEPARATOR;
// namelen + 1 to copy the final '\0'
memcpy(&file_path[dirlen + 1], name, namelen + 1);
free(executable_path);
return file_path;
}

View file

@ -74,6 +74,11 @@ search_executable(const char *file);
char * char *
get_executable_path(void); get_executable_path(void);
// Return the absolute path of a file in the same directory as he executable.
// May be NULL on error. To be freed by free().
char *
get_local_file_path(const char *name);
// returns true if the file exists and is not a directory // returns true if the file exists and is not a directory
bool bool
is_regular_file(const char *path); is_regular_file(const char *path);