Skip to content
Snippets Groups Projects

Add executable that identifies the ABI of libraries

Merged Ludovico de Nittis requested to merge wip/denittis/t28814 into master
@@ -87,7 +87,8 @@ list_libraries_helper (const char *fpath,
static void
print_library_details (const gchar *library_path,
const gchar separator)
const gchar separator,
FILE *original_stdout)
{
glnx_autofd int fd = -1;
g_autoptr(Elf) elf = NULL;
@@ -99,21 +100,21 @@ print_library_details (const gchar *library_path,
if ((fd = open (library_path, O_RDONLY | O_CLOEXEC, 0)) < 0)
{
int saved_errno = errno;
printf ("Error reading \"%s\": %s\n",
library_path, strerror (saved_errno));
g_debug ("Error reading \"%s\": %s\n",
library_path, strerror (saved_errno));
return;
}
if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL)
{
printf ("Error reading the library ELF: %s", elf_errmsg (elf_errno ()));
g_debug ("Error reading the library ELF: %s", elf_errmsg (elf_errno ()));
return;
}
if (gelf_getehdr(elf, &eh) == NULL)
{
printf ("Error reading the library ELF header: %s",
elf_errmsg (elf_errno ()));
g_debug ("Error reading the library ELF header: %s",
elf_errmsg (elf_errno ()));
return;
}
@@ -128,32 +129,30 @@ print_library_details (const gchar *library_path,
else
identifier = "other";
fprintf (stderr, "%s=%s%c", library_path, identifier, separator);
fprintf (original_stdout, "%s=%s%c", library_path, identifier, separator);
}
int
main (int argc,
char **argv)
static gboolean
run (int argc,
char **argv,
GError **error)
{
char separator = '\n';
g_autoptr(FILE) original_stdout = NULL;
g_autoptr(GOptionContext) option_context = NULL;
g_autofree gchar *output = NULL;
g_autoptr(GError) error = NULL;
gint wait_status = 0;
gsize i;
const gchar *ldconfig_argv[] =
{
"ldconfig", "-XNv", NULL,
};
gsize i;
char separator = '\n';
option_context = g_option_context_new ("");
g_option_context_add_main_entries (option_context, option_entries, NULL);
if (!g_option_context_parse (option_context, &argc, &argv, NULL))
return 2;
if (!g_option_context_parse (option_context, &argc, &argv, error))
return FALSE;
if (opt_print_version)
{
@@ -162,18 +161,28 @@ main (int argc,
g_print ("%s:\n"
" Package: steam-runtime-tools\n"
" Version: %s\n",
argv[0], VERSION);
return EXIT_SUCCESS;
g_get_prgname (), VERSION);
return TRUE;
}
/* stdout is reserved for machine-readable output, so avoid having
* things like g_debug() pollute it. */
original_stdout = _srt_divert_stdout_to_stderr (error);
if (original_stdout == NULL)
return FALSE;
if (opt_ldconfig && opt_directory != NULL)
return glnx_throw (error, "--ldconfig and --directory cannot both be used");
if (!opt_ldconfig && opt_directory == NULL)
return glnx_throw (error, "Either --ldconfig or --directory are required");
if (opt_print0)
separator = '\0';
if (elf_version (EV_CURRENT) == EV_NONE)
{
g_debug ("elf_version(EV_CURRENT): %s", elf_errmsg (elf_errno ()));
return EXIT_FAILURE;
}
return glnx_throw (error, "elf_version(EV_CURRENT): %s", elf_errmsg (elf_errno ()));
if (opt_ldconfig)
{
@@ -189,25 +198,21 @@ main (int argc,
&output, /* stdout */
NULL, /* stderr */
&wait_status,
&error))
error))
{
g_debug ("An error occurred calling ldconfig: %s", error->message);
return EXIT_FAILURE;
return FALSE;
}
if (wait_status != 0)
{
g_debug ("... wait status %d", wait_status);
return EXIT_FAILURE;
}
return glnx_throw (error, "Cannot run ldconfig: wait status %d", wait_status);
if (output == NULL)
return EXIT_FAILURE;
return glnx_throw (error, "ldconfig didn't produce anything in output");
ldconfig_entries = g_strsplit (output, "\n", -1);
if (ldconfig_entries == NULL)
return EXIT_FAILURE;
return glnx_throw (error, "ldconfig didn't produce anything in output");
for (i = 0; ldconfig_entries[i] != NULL; i++)
{
@@ -231,7 +236,7 @@ main (int argc,
library = g_strstrip (line_elements[0]);
library_path = g_build_filename (library_prefix, library, NULL);
print_library_details (library_path, separator);
print_library_details (library_path, separator, original_stdout);
}
}
else if (opt_directory != NULL)
@@ -241,16 +246,29 @@ main (int argc,
if (nftw (opt_directory, list_libraries_helper, 10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
{
g_ptr_array_free (nftw_libraries, TRUE);
return EXIT_FAILURE;
return glnx_throw_errno_prefix (error, "Unable to iterate through \"%s\"", opt_directory);
}
for (i = 0; i < nftw_libraries->len; i++)
{
print_library_details (g_ptr_array_index (nftw_libraries, i), separator);
}
print_library_details (g_ptr_array_index (nftw_libraries, i), separator,
original_stdout);
g_ptr_array_free (nftw_libraries, TRUE);
}
return EXIT_SUCCESS;
return TRUE;
}
int
main (int argc,
char **argv)
{
g_autoptr(GError) error = NULL;
if (run (argc, argv, &error))
return 0;
g_printerr ("%s: %s\n", g_get_prgname (), error->message);
return 1;
}
Loading