diff --git a/meson.build b/meson.build index 217500ef0156641262042d29fb8bee29e7d599e6..906d63c2712a57c85e0255628eee07ba647630e8 100644 --- a/meson.build +++ b/meson.build @@ -171,6 +171,8 @@ executable( 'src/bwrap-lock.h', 'src/glib-backports.c', 'src/glib-backports.h', + 'src/flatpak-utils-base.c', + 'src/flatpak-utils-base-private.h', 'src/flatpak-utils.c', 'src/flatpak-utils-private.h', 'src/utils.c', @@ -203,6 +205,8 @@ executable( 'src/flatpak-bwrap-private.h', 'src/flatpak-run.c', 'src/flatpak-run-private.h', + 'src/flatpak-utils-base.c', + 'src/flatpak-utils-base-private.h', 'src/flatpak-utils.c', 'src/flatpak-utils-private.h', 'src/utils.c', diff --git a/src/flatpak-bwrap.c b/src/flatpak-bwrap.c index 626e8eaa060393f43c0c589171cdbf005c9704ce..7356a97dc6093eae2ec8152713d06bf75b1afc2d 100644 --- a/src/flatpak-bwrap.c +++ b/src/flatpak-bwrap.c @@ -34,6 +34,7 @@ #include "libglnx.h" #include "flatpak-bwrap-private.h" +#include "flatpak-utils-base-private.h" #include "flatpak-utils-private.h" #include "glib-backports.h" diff --git a/src/flatpak-run.c b/src/flatpak-run.c index 20c4fbcd997d5e4c8d31ca19efd349c0a4e46776..e4ccd6c8dadcc96691d9746ed7f741101a25b0ea 100644 --- a/src/flatpak-run.c +++ b/src/flatpak-run.c @@ -27,6 +27,7 @@ #include <X11/Xauth.h> #include <gio/gio.h> +#include "flatpak-utils-base-private.h" #include "flatpak-utils-private.h" /* In Flatpak this is optional, in pressure-vessel not so much */ diff --git a/src/flatpak-utils-base-private.h b/src/flatpak-utils-base-private.h new file mode 100644 index 0000000000000000000000000000000000000000..181a0c9587f95368693a38c8b4fa5157595f3077 --- /dev/null +++ b/src/flatpak-utils-base-private.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Alexander Larsson <alexl@redhat.com> + */ + +#ifndef __FLATPAK_UTILS_BASE_H__ +#define __FLATPAK_UTILS_BASE_H__ + +#include <glib.h> + +char *flatpak_get_timezone (void); + +char * flatpak_readlink (const char *path, + GError **error); +char * flatpak_resolve_link (const char *path, + GError **error); +char * flatpak_canonicalize_filename (const char *path); +void flatpak_close_fds_workaround (int start_fd); + +#endif /* __FLATPAK_UTILS_BASE_H__ */ diff --git a/src/flatpak-utils-base.c b/src/flatpak-utils-base.c new file mode 100644 index 0000000000000000000000000000000000000000..aa535a4a4cdebca8a459980012f9da77b37191ba --- /dev/null +++ b/src/flatpak-utils-base.c @@ -0,0 +1,115 @@ +/* + * Taken from Flatpak + * Copyright © 2019 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Alexander Larsson <alexl@redhat.com> + */ + +#include "flatpak-utils-base-private.h" + +#include <stdlib.h> +#include <string.h> + +#include <gio/gio.h> +#include "libglnx.h" + +char * +flatpak_get_timezone (void) +{ + g_autofree gchar *symlink = NULL; + gchar *etc_timezone = NULL; + const gchar *tzdir; + + tzdir = getenv ("TZDIR"); + if (tzdir == NULL) + tzdir = "/usr/share/zoneinfo"; + + symlink = flatpak_resolve_link ("/etc/localtime", NULL); + if (symlink != NULL) + { + /* Resolve relative path */ + g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink); + char *canonical_suffix; + + /* Strip the prefix and slashes if possible. */ + if (g_str_has_prefix (canonical, tzdir)) + { + canonical_suffix = canonical + strlen (tzdir); + while (*canonical_suffix == '/') + canonical_suffix++; + + return g_strdup (canonical_suffix); + } + } + + if (g_file_get_contents ("/etc/timezeone", &etc_timezone, + NULL, NULL)) + { + g_strchomp (etc_timezone); + return etc_timezone; + } + + /* Final fall-back is UTC */ + return g_strdup ("UTC"); +} + +char * +flatpak_readlink (const char *path, + GError **error) +{ + return glnx_readlinkat_malloc (-1, path, NULL, error); +} + +char * +flatpak_resolve_link (const char *path, + GError **error) +{ + g_autofree char *link = flatpak_readlink (path, error); + g_autofree char *dirname = NULL; + + if (link == NULL) + return NULL; + + if (g_path_is_absolute (link)) + return g_steal_pointer (&link); + + dirname = g_path_get_dirname (path); + return g_build_filename (dirname, link, NULL); +} + +char * +flatpak_canonicalize_filename (const char *path) +{ + g_autoptr(GFile) file = g_file_new_for_path (path); + return g_file_get_path (file); +} + +/* There is a dead-lock in glib versions before 2.60 when it closes + * the fds. See: https://gitlab.gnome.org/GNOME/glib/merge_requests/490 + * This was hitting the test-suite a lot, so we work around it by using + * the G_SPAWN_LEAVE_DESCRIPTORS_OPEN/G_SUBPROCESS_FLAGS_INHERIT_FDS flag + * and setting CLOEXEC ourselves. + */ +void +flatpak_close_fds_workaround (int start_fd) +{ + int max_open_fds = sysconf (_SC_OPEN_MAX); + int fd; + + for (fd = start_fd; fd < max_open_fds; fd++) + fcntl (fd, F_SETFD, FD_CLOEXEC); +} diff --git a/src/flatpak-utils-private.h b/src/flatpak-utils-private.h index 736cca1a7248d0cb360797f06c97ebdbfacd7b40..2c7cbf4a954d7b26e4f9b9668ff20a91a1fd5de6 100644 --- a/src/flatpak-utils-private.h +++ b/src/flatpak-utils-private.h @@ -37,17 +37,10 @@ * it as a path into the sandbox */ char * flatpak_get_real_xdg_runtime_dir (void); -char *flatpak_get_timezone (void); char * flatpak_quote_argv (const char *argv[], gssize len); -char * flatpak_readlink (const char *path, - GError **error); -char * flatpak_resolve_link (const char *path, - GError **error); -char * flatpak_canonicalize_filename (const char *path); - gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf, const char *name, const char *str, diff --git a/src/flatpak-utils.c b/src/flatpak-utils.c index 04112cdac1074a85614f1a5f6ef2a70078d83d9e..fbea468e8754bab96a0a65ba83bce9828fe31ee1 100644 --- a/src/flatpak-utils.c +++ b/src/flatpak-utils.c @@ -1,7 +1,7 @@ /* * A cut-down version of common/flatpak-utils from Flatpak * - * Copyright © 2014 Red Hat, Inc + * Copyright © 2014-2019 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,9 @@ #include <sys/ioctl.h> #include <termios.h> +#include <glib.h> +#include "flatpak-utils-base-private.h" + /* To keep this more similar to the original file, we explicitly disable * this warning rather than fixing it */ #pragma GCC diagnostic ignored "-Wshadow" @@ -51,46 +54,6 @@ flatpak_get_real_xdg_runtime_dir (void) return realpath (g_get_user_runtime_dir (), NULL); } -char * -flatpak_get_timezone (void) -{ - g_autofree gchar *symlink = NULL; - gchar *etc_timezone = NULL; - const gchar *tzdir; - - tzdir = getenv ("TZDIR"); - if (tzdir == NULL) - tzdir = "/usr/share/zoneinfo"; - - symlink = flatpak_resolve_link ("/etc/localtime", NULL); - if (symlink != NULL) - { - /* Resolve relative path */ - g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink); - char *canonical_suffix; - - /* Strip the prefix and slashes if possible. */ - if (g_str_has_prefix (canonical, tzdir)) - { - canonical_suffix = canonical + strlen (tzdir); - while (*canonical_suffix == '/') - canonical_suffix++; - - return g_strdup (canonical_suffix); - } - } - - if (g_file_get_contents ("/etc/timezeone", &etc_timezone, - NULL, NULL)) - { - g_strchomp (etc_timezone); - return etc_timezone; - } - - /* Final fall-back is UTC */ - return g_strdup ("UTC"); -} - static gboolean needs_quoting (const char *arg) { @@ -134,37 +97,6 @@ flatpak_quote_argv (const char *argv[], return g_string_free (res, FALSE); } -char * -flatpak_readlink (const char *path, - GError **error) -{ - return glnx_readlinkat_malloc (-1, path, NULL, error); -} - -char * -flatpak_resolve_link (const char *path, - GError **error) -{ - g_autofree char *link = flatpak_readlink (path, error); - g_autofree char *dirname = NULL; - - if (link == NULL) - return NULL; - - if (g_path_is_absolute (link)) - return g_steal_pointer (&link); - - dirname = g_path_get_dirname (path); - return g_build_filename (dirname, link, NULL); -} - -char * -flatpak_canonicalize_filename (const char *path) -{ - g_autoptr(GFile) file = g_file_new_for_path (path); - return g_file_get_path (file); -} - /* If memfd_create() is available, generate a sealed memfd with contents of * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to * @tmpf, and lseek() back to the start. See also similar uses in e.g. diff --git a/src/utils.c b/src/utils.c index 1076a78ecbf001d3732a7f59be449f477815808f..bf7e537147d31f20038b5a89f9250ce2b855db66 100644 --- a/src/utils.c +++ b/src/utils.c @@ -30,6 +30,7 @@ #include "glib-backports.h" #include "flatpak-bwrap-private.h" +#include "flatpak-utils-base-private.h" #include "flatpak-utils-private.h" /** diff --git a/src/wrap.c b/src/wrap.c index 7d0c864490433ea5c4ff2922ac7441444c808318..85cf36e1809d59ffaa542423d5fd9d46a8a113f4 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -41,6 +41,7 @@ #include "bwrap-lock.h" #include "flatpak-bwrap-private.h" #include "flatpak-run-private.h" +#include "flatpak-utils-base-private.h" #include "flatpak-utils-private.h" #include "utils.h" #include "wrap-interactive.h"