From 336f8872897986cdd6975ccb4d6ecb09ac4be52c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 30 Aug 2018 22:10:36 -0400 Subject: [PATCH 1/3] Add an instance api This is made to let gnome-software enumerate all running instances and get the same information about them that flatpak ps provides. For now, we keep it private. It will become library api once we open new development --- common/Makefile.am.inc | 2 + common/flatpak-instance-private.h | 68 ++++++ common/flatpak-instance.c | 353 ++++++++++++++++++++++++++++++ 3 files changed, 423 insertions(+) create mode 100644 common/flatpak-instance-private.h create mode 100644 common/flatpak-instance.c diff --git a/common/Makefile.am.inc b/common/Makefile.am.inc index d39d6513..f3966903 100644 --- a/common/Makefile.am.inc +++ b/common/Makefile.am.inc @@ -120,6 +120,8 @@ libflatpak_common_la_SOURCES = \ common/flatpak-error.c \ common/flatpak-installation-private.h \ common/flatpak-installation.c \ + common/flatpak-instance-private.h \ + common/flatpak-instance.c \ common/valgrind-private.h \ $(NULL) diff --git a/common/flatpak-instance-private.h b/common/flatpak-instance-private.h new file mode 100644 index 00000000..f9a27108 --- /dev/null +++ b/common/flatpak-instance-private.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2018 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 . + * + * Authors: + * Matthias Clasen + */ + +#if !defined(__FLATPAK_H_INSIDE__) && !defined(FLATPAK_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __FLATPAK_INSTANCE_H__ +#define __FLATPAK_INSTANCE_H__ + +typedef struct _FlatpakInstance FlatpakInstance; + +#include + +#define FLATPAK_TYPE_INSTANCE flatpak_instance_get_type () +#define FLATPAK_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FLATPAK_TYPE_INSTANCE, FlatpakInstance)) +#define FLATPAK_IS_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FLATPAK_TYPE_INSTANCE)) + +FLATPAK_EXTERN GType flatpak_instance_get_type (void); + +struct _FlatpakInstance +{ + GObject parent; +}; + +typedef struct +{ + GObjectClass parent_class; +} FlatpakInstanceClass; + + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakInstance, g_object_unref) +#endif + +FLATPAK_EXTERN GPtrArray * flatpak_instance_get_all (void); + +FLATPAK_EXTERN const char * flatpak_instance_get_id (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_app (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_arch (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_branch (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_commit (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_runtime (FlatpakInstance *self); +FLATPAK_EXTERN const char * flatpak_instance_get_runtime_commit (FlatpakInstance *self); +FLATPAK_EXTERN int flatpak_instance_get_pid (FlatpakInstance *self); +FLATPAK_EXTERN int flatpak_instance_get_child_pid (FlatpakInstance *self); +FLATPAK_EXTERN GKeyFile * flatpak_instance_get_info (FlatpakInstance *self); + +FLATPAK_EXTERN gboolean flatpak_instance_is_running (FlatpakInstance *self); + +#endif /* __FLATPAK_INSTANCE_H__ */ diff --git a/common/flatpak-instance.c b/common/flatpak-instance.c new file mode 100644 index 00000000..1f15776f --- /dev/null +++ b/common/flatpak-instance.c @@ -0,0 +1,353 @@ +/* + * Copyright © 2018 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 . + * + * Authors: + * Matthias Clasen + */ + +#include "config.h" + +#include "flatpak-utils-private.h" +#include "flatpak-run-private.h" +#include "flatpak-instance-private.h" +#include "flatpak-enum-types.h" + + +typedef struct _FlatpakInstancePrivate FlatpakInstancePrivate; + +struct _FlatpakInstancePrivate +{ + char *id; + char *dir; + + GKeyFile *info; + char *app; + char *arch; + char *branch; + char *commit; + char *runtime; + char *runtime_commit; + + int pid; + int child_pid; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (FlatpakInstance, flatpak_instance, G_TYPE_OBJECT) + +static void +flatpak_instance_finalize (GObject *object) +{ + FlatpakInstance *self = FLATPAK_INSTANCE (object); + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + g_free (priv->id); + g_free (priv->dir); + g_free (priv->app); + g_free (priv->arch); + g_free (priv->branch); + g_free (priv->commit); + g_free (priv->runtime); + g_free (priv->runtime_commit); + + if (priv->info) + g_key_file_unref (priv->info); + + G_OBJECT_CLASS (flatpak_instance_parent_class)->finalize (object); +} + +static void +flatpak_instance_class_init (FlatpakInstanceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = flatpak_instance_finalize; +} + +static void +flatpak_instance_init (FlatpakInstance *self) +{ +} + +const char * +flatpak_instance_get_id (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->id; +} + +const char * +flatpak_instance_get_app (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->app; +} + +const char * +flatpak_instance_get_arch (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->arch; +} + +const char * +flatpak_instance_get_branch (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->branch; +} + +const char * +flatpak_instance_get_commit (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->commit; +} + +const char * +flatpak_instance_get_runtime (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->runtime; +} + +const char * +flatpak_instance_get_runtime_commit (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->runtime_commit; +} + +int +flatpak_instance_get_pid (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->pid; +} + +int +flatpak_instance_get_child_pid (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->child_pid; +} + +GKeyFile * +flatpak_instance_get_info (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + return priv->info; +} + +static GKeyFile * +get_instance_info (const char *dir) +{ + g_autofree char *file = NULL; + g_autoptr(GKeyFile) key_file = NULL; + g_autoptr(GError) error = NULL; + + file = g_build_filename (dir, "info", NULL); + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, file, G_KEY_FILE_NONE, &error)) + { + g_debug ("Failed to load instance info file '%s': %s", file, error->message); + return NULL; + } + + return g_steal_pointer (&key_file); +} + +static int +get_child_pid (const char *dir) +{ + g_autofree char *file = NULL; + g_autofree char *contents = NULL; + gsize length; + g_autoptr(GError) error = NULL; + g_autoptr(JsonParser) parser = NULL; + JsonNode *node; + JsonObject *obj; + + file = g_build_filename (dir, "bwrapinfo.json", NULL); + + if (!g_file_get_contents (file, &contents, &length, &error)) + { + g_debug ("Failed to load bwrapinfo.json file '%s': %s", file, error->message); + return 0; + } + + parser = json_parser_new (); + if (!json_parser_load_from_data (parser, contents, length, &error)) + { + g_debug ("Failed to parse bwrapinfo.json file '%s': %s", file, error->message); + return 0; + } + + node = json_parser_get_root (parser); + obj = json_node_get_object (node); + + return json_object_get_int_member (obj, "child-pid"); +} + +static int +get_pid (const char *dir) +{ + g_autofree char *file = NULL; + g_autofree char *contents = NULL; + g_autoptr(GError) error = NULL; + + file = g_build_filename (dir, "pid", NULL); + + if (!g_file_get_contents (file, &contents, NULL, &error)) + { + g_debug ("Failed to load pid file '%s': %s", file, error->message); + return 0; + } + + return (int) g_ascii_strtoll (contents, NULL, 10); +} + +static FlatpakInstance * +flatpak_instance_new (const char *id) +{ + FlatpakInstance *self = g_object_new (flatpak_instance_get_type (), NULL); + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + priv->id = g_strdup (id); + + priv->dir = g_build_filename (g_get_user_runtime_dir (), ".flatpak", id, NULL); + + priv->pid = get_pid (priv->dir); + priv->child_pid = get_child_pid (priv->dir); + priv->info = get_instance_info (priv->dir); + + if (priv->info) + { + priv->app = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_APPLICATION, FLATPAK_METADATA_KEY_NAME, NULL); + priv->runtime = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_APPLICATION, FLATPAK_METADATA_KEY_RUNTIME, NULL); + + priv->arch = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_ARCH, NULL); + priv->branch = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_BRANCH, NULL); + priv->commit = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_APP_COMMIT, NULL); + priv->runtime_commit = g_key_file_get_string (priv->info, + FLATPAK_METADATA_GROUP_INSTANCE, FLATPAK_METADATA_KEY_RUNTIME_COMMIT, NULL); + } + + return self; +} + +GPtrArray * +flatpak_instance_get_all (void) +{ + g_autoptr(GPtrArray) instances = NULL; + g_autofree char *base_dir = NULL; + g_auto(GLnxDirFdIterator) iter = { 0 }; + struct dirent *dent; + + instances = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + base_dir = g_build_filename (g_get_user_runtime_dir (), ".flatpak", NULL); + + if (!glnx_dirfd_iterator_init_at (AT_FDCWD, base_dir, FALSE, &iter, NULL)) + return g_steal_pointer (&instances); + + while (TRUE) + { + if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, NULL, NULL)) + break; + + if (dent == NULL) + break; + + if (dent->d_type == DT_DIR) + { + g_autofree char *ref_file = g_strconcat (dent->d_name, "/.ref", NULL); + struct stat statbuf; + struct flock l = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0 + }; + glnx_autofd int lock_fd = openat (iter.fd, ref_file, O_RDWR | O_CLOEXEC); + if (lock_fd != -1 && + fstat (lock_fd, &statbuf) == 0 && + /* Only gc if created at least 3 secs ago, to work around race mentioned in flatpak_run_allocate_id() */ + statbuf.st_mtime + 3 < time (NULL) && + fcntl (lock_fd, F_GETLK, &l) == 0 && + l.l_type == F_UNLCK) + { + /* The instance is not used, remove it */ + g_debug ("Cleaning up unused container id %s", dent->d_name); + glnx_shutil_rm_rf_at (iter.fd, dent->d_name, NULL, NULL); + continue; + } + + g_ptr_array_add (instances, flatpak_instance_new (dent->d_name)); + } + } + + return g_steal_pointer (&instances); +} + +gboolean +flatpak_instance_is_running (FlatpakInstance *self) +{ + FlatpakInstancePrivate *priv = flatpak_instance_get_instance_private (self); + + if (priv->dir) + { + g_autofree char *ref_file = g_strconcat (priv->dir, "/.ref", NULL); + struct stat statbuf; + struct flock l = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0 + }; + glnx_autofd int lock_fd = open (ref_file, O_RDWR | O_CLOEXEC); + if (lock_fd != -1 && + fstat (lock_fd, &statbuf) == 0 && + /* Only gc if created at least 3 secs ago, to work around race mentioned in flatpak_run_allocate_id() */ + statbuf.st_mtime + 3 < time (NULL) && + fcntl (lock_fd, F_GETLK, &l) == 0 && + l.l_type == F_UNLCK) + { + /* The instance is not used, remove it */ + g_debug ("Cleaning up unused container id %s", priv->id); + glnx_shutil_rm_rf_at (-1, priv->dir, NULL, NULL); + + g_clear_pointer (&priv->dir, g_free); + } + } + + return priv->dir != NULL; +} + From ef30ef4e88750c1866398e23b7d017da2083a776 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 31 Aug 2018 09:55:05 -0400 Subject: [PATCH 2/3] flatpak ps: port to FlatpakInstance FlatpakInstance is a new api for representing running instances, its made just for cases like flatpak ps, so lets use it. --- app/flatpak-builtins-ps.c | 230 ++++++++++++-------------------------- 1 file changed, 69 insertions(+), 161 deletions(-) diff --git a/app/flatpak-builtins-ps.c b/app/flatpak-builtins-ps.c index fa9ebfcf..760a97f1 100644 --- a/app/flatpak-builtins-ps.c +++ b/app/flatpak-builtins-ps.c @@ -33,7 +33,7 @@ #include "flatpak-builtins.h" #include "flatpak-table-printer.h" -#include "flatpak-run-private.h" +#include "flatpak-instance-private.h" static gboolean opt_show_cols; static const char **opt_cols; @@ -129,121 +129,16 @@ show_columns (void) g_print ("%s", col_help); } -static char * -get_instance_pid (const char *instance) -{ - g_autofree char *path = NULL; - char *pid; - g_autoptr(GError) error = NULL; - - path = g_build_filename (g_get_user_runtime_dir (), ".flatpak", instance, "pid", NULL); - - if (!g_file_get_contents (path, &pid, NULL, &error)) - { - g_debug ("Failed to load pid file for instance '%s': %s", instance, error->message); - return NULL; - } - - return pid; -} - -static int -get_child_pid (const char *instance) -{ - g_autofree char *path = NULL; - g_autofree char *contents = NULL; - gsize length; - g_autoptr(GError) error = NULL; - g_autoptr(JsonParser) parser = NULL; - g_autoptr(JsonNode) node = NULL; - g_autoptr(JsonObject) obj = NULL; - - path = g_build_filename (g_get_user_runtime_dir (), ".flatpak", instance, "bwrapinfo.json", NULL); - - if (!g_file_get_contents (path, &contents, &length, &error)) - { - g_debug ("Failed to load bwrapinfo.json file for instance '%s': %s", instance, error->message); - return 0; - } - - parser = json_parser_new (); - if (!json_parser_load_from_data (parser, contents, length, &error)) - { - g_debug ("Failed to parse bwrapinfo.json file for instance '%s': %s", instance, error->message); - return 0; - } - - node = json_parser_get_root (parser); - obj = json_node_get_object (node); - - return json_object_get_int_member (obj, "child-pid"); -} - -static GKeyFile * -get_instance_info (const char *instance) -{ - g_autofree char *path = NULL; - GKeyFile *key_file = NULL; - g_autoptr(GError) error = NULL; - - path = g_build_filename (g_get_user_runtime_dir (), ".flatpak", instance, "info", NULL); - - key_file = g_key_file_new (); - if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error)) - { - g_debug ("Failed to load info file for instance '%s': %s", instance, error->message); - return NULL; - } - - return key_file; -} - -static char * -get_instance_column (GKeyFile *info, - const char *name) -{ - if (info == NULL) - return NULL; - - if (strcmp (name, "application") == 0) - return g_key_file_get_string (info, "Application", "name", NULL); - if (strcmp (name, "arch") == 0) - return g_key_file_get_string (info, "Instance", "arch", NULL); - if (strcmp (name, "branch") == 0) - return g_key_file_get_string (info, "Instance", "branch", NULL); - else if (strcmp (name, "commit") == 0) - return g_key_file_get_string (info, "Instance", "app-commit", NULL); - else if (strcmp (name, "runtime") == 0) - { - g_autofree char *full_ref = g_key_file_get_string (info, "Application", "runtime", NULL); - g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); - return g_strdup (ref[1]); - } - else if (strcmp (name, "runtime-branch") == 0) - { - g_autofree char *full_ref = g_key_file_get_string (info, "Application", "runtime", NULL); - g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); - return g_strdup (ref[3]); - } - else if (strcmp (name, "runtime-commit") == 0) - return g_key_file_get_string (info, "Instance", "runtime-commit", NULL); - - return NULL; -} - static gboolean enumerate_instances (const char *columns, GError **error) { - g_autofree char *base_dir = NULL; - g_autoptr(GFile) file = NULL; - g_autoptr(GFileEnumerator) enumerator = NULL; - GFileInfo *dir_info; + g_autoptr(GPtrArray) instances = NULL; FlatpakTablePrinter *printer; g_auto(GStrv) cols = NULL; g_autofree int *col_idx = NULL; int n_cols; - int i; + int i, j; cols = g_strsplit (columns, ",", 0); n_cols = g_strv_length (cols); @@ -263,40 +158,58 @@ enumerate_instances (const char *columns, for (i = 0; i < n_cols; i++) flatpak_table_printer_set_column_title (printer, i + 1, all_columns[col_idx[i]].title); - base_dir = g_build_filename (g_get_user_runtime_dir (), ".flatpak", NULL); - file = g_file_new_for_path (base_dir); - enumerator = g_file_enumerate_children (file, "standard::name", G_FILE_QUERY_INFO_NONE, NULL, error); - if (enumerator == NULL) + instances = flatpak_instance_get_all (); + if (instances->len == 0) { - if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - /* nothing to show */ - g_clear_error (error); - return TRUE; - } - return FALSE; + /* nothing to show */ + return TRUE; } - while ((dir_info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) + for (j = 0; j < instances->len; j++) { - g_autofree char *instance = g_file_info_get_attribute_as_string (dir_info, "standard::name"); - g_autoptr(GKeyFile) info = get_instance_info (instance); + FlatpakInstance *instance = (FlatpakInstance *)g_ptr_array_index (instances, j); - flatpak_table_printer_add_column (printer, instance); + flatpak_table_printer_add_column (printer, flatpak_instance_get_id (instance)); for (i = 0; i < n_cols; i++) { - g_autofree char *col = NULL; + g_autofree char *freeme = NULL; + const char *col = NULL; + int idx = col_idx[i]; int len; - if (strcmp (all_columns[col_idx[i]].name, "pid") == 0) - col = get_instance_pid (instance); - else if (strcmp (all_columns[col_idx[i]].name, "child-pid") == 0) - col = g_strdup_printf ("%d", get_child_pid (instance)); - else - col = get_instance_column (info, all_columns[col_idx[i]].name); + if (strcmp (all_columns[idx].name, "pid") == 0) + col = freeme = g_strdup_printf ("%d", flatpak_instance_get_pid (instance)); + else if (strcmp (all_columns[idx].name, "child-pid") == 0) + col = freeme = g_strdup_printf ("%d", flatpak_instance_get_child_pid (instance)); + else if (strcmp (all_columns[idx].name, "application") == 0) + col = flatpak_instance_get_app (instance); + else if (strcmp (all_columns[idx].name, "arch") == 0) + col = flatpak_instance_get_arch (instance); + else if (strcmp (all_columns[idx].name, "commit") == 0) + col = flatpak_instance_get_commit (instance); + else if (strcmp (all_columns[idx].name, "runtime") == 0) + { + const char *full_ref = flatpak_instance_get_runtime (instance); + if (full_ref != NULL) + { + g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); + col = freeme = g_strdup (ref[1]); + } + } + else if (strcmp (all_columns[idx].name, "runtime-branch") == 0) + { + const char *full_ref = flatpak_instance_get_runtime (instance); + if (full_ref != NULL) + { + g_auto(GStrv) ref = flatpak_decompose_ref (full_ref, NULL); + col = freeme = g_strdup (ref[3]); + } + } + else if (strcmp (all_columns[idx].name, "runtime-commit") == 0) + col = flatpak_instance_get_runtime_commit (instance); - len = all_columns[col_idx[i]].len; + len = all_columns[idx].len; if (len == 0) flatpak_table_printer_add_column (printer, col); else @@ -304,24 +217,35 @@ enumerate_instances (const char *columns, } flatpak_table_printer_finish_row (printer); - - g_object_unref (dir_info); } flatpak_table_printer_print (printer); flatpak_table_printer_free (printer); - if (*error) - return FALSE; - return TRUE; } +static gboolean +list_has (const char *list, + const char *term) +{ + const char *p; + int len; + + p = strstr (list, term); + len = strlen (term); + if (p && + (p == list || p[-1] == ',') && + (p[len] == '\0' || p[len] == ',')) + return TRUE; + return FALSE; +} + gboolean -flatpak_builtin_ps (int argc, - char **argv, - GCancellable *cancellable, - GError **error) +flatpak_builtin_ps (int argc, + char **argv, + GCancellable *cancellable, + GError **error) { g_autoptr(GOptionContext) context = NULL; g_autofree char *col_help = NULL; @@ -341,8 +265,6 @@ flatpak_builtin_ps (int argc, return FALSE; } - flatpak_run_gc_ids (); - if (opt_show_cols) { show_columns (); @@ -351,38 +273,24 @@ flatpak_builtin_ps (int argc, if (opt_cols) { - gboolean show_help = FALSE; gboolean show_all = FALSE; int i; for (i = 0; opt_cols[i]; i++) { - const char *p; - p = strstr (opt_cols[i], "help"); - if (p && - (p == opt_cols[i] || p[-1] == ',') && - (p[strlen("help")] == '\0' || p[strlen("help")] == ',')) + if (list_has (opt_cols[i], "help")) { - show_help = TRUE; - break; + show_columns (); + return TRUE; } - - p = strstr (opt_cols[i], "all"); - if (p && - (p == opt_cols[i] || p[-1] == ',') && - (p[strlen("all")] == '\0' || p[strlen("all")] == ',')) + if (list_has (opt_cols[i], "all")) { show_all = TRUE; break; } } - if (show_help) - { - show_columns (); - return TRUE; - } - else if (show_all) + if (show_all) { cols = g_strdup (ALL_COLUMNS); } From 129031a2e266a1e986e61793217135760d0636dc Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 3 Sep 2018 11:53:53 -0400 Subject: [PATCH 3/3] Stop exporting flatpak_run_gc_ids() No longer used outside flatpak-run.c --- common/flatpak-run-private.h | 2 -- common/flatpak-run.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/common/flatpak-run-private.h b/common/flatpak-run-private.h index 4fd762e6..90073c51 100644 --- a/common/flatpak-run-private.h +++ b/common/flatpak-run-private.h @@ -173,6 +173,4 @@ gboolean flatpak_run_app (const char *app_ref, GCancellable *cancellable, GError **error); -void flatpak_run_gc_ids (void); - #endif /* __FLATPAK_RUN_H__ */ diff --git a/common/flatpak-run.c b/common/flatpak-run.c index c7e477cc..6ab466af 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -1571,7 +1571,7 @@ flatpak_app_compute_permissions (GKeyFile *app_metadata, return g_steal_pointer (&app_context); } -void +static void flatpak_run_gc_ids (void) { g_autofree char *base_dir = g_build_filename (g_get_user_runtime_dir (), ".flatpak", NULL);