Move config file path expansion much earlier, keep the list of paths
authornicm <nicm@openbsd.org>
Mon, 22 Feb 2021 08:18:13 +0000 (08:18 +0000)
committernicm <nicm@openbsd.org>
Mon, 22 Feb 2021 08:18:13 +0000 (08:18 +0000)
around rather than freeing later, and add a config_files format variable
containing it. Suggested by kn@ a while back.

usr.bin/tmux/cfg.c
usr.bin/tmux/format.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.c
usr.bin/tmux/tmux.h

index e0bd9a3..204a3ab 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cfg.c,v 1.81 2020/05/16 14:26:33 nicm Exp $ */
+/* $OpenBSD: cfg.c,v 1.82 2021/02/22 08:18:13 nicm Exp $ */
 
 /*
  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
 #include "tmux.h"
 
 struct client           *cfg_client;
-static char             *cfg_file;
 int                      cfg_finished;
 static char            **cfg_causes;
 static u_int             cfg_ncauses;
 static struct cmdq_item         *cfg_item;
 
+int                       cfg_quiet = 1;
+char                    **cfg_files;
+u_int                     cfg_nfiles;
+
 static enum cmd_retval
 cfg_client_done(__unused struct cmdq_item *item, __unused void *data)
 {
@@ -60,19 +63,11 @@ cfg_done(__unused struct cmdq_item *item, __unused void *data)
        return (CMD_RETURN_NORMAL);
 }
 
-void
-set_cfg_file(const char *path)
-{
-       free(cfg_file);
-       cfg_file = xstrdup(path);
-}
-
 void
 start_cfg(void)
 {
        struct client    *c;
-       char            **paths;
-       u_int             i, n;
+       u_int             i;
 
        /*
         * Configuration files are loaded without a client, so commands are run
@@ -90,15 +85,12 @@ start_cfg(void)
                cmdq_append(c, cfg_item);
        }
 
-       if (cfg_file == NULL) {
-               expand_paths(TMUX_CONF, &paths, &n);
-               for (i = 0; i < n; i++) {
-                       load_cfg(paths[i], c, NULL, CMD_PARSE_QUIET, NULL);
-                       free(paths[i]);
-               }
-               free(paths);
-       } else
-               load_cfg(cfg_file, c, NULL, 0, NULL);
+       for (i = 0; i < cfg_nfiles; i++) {
+               if (cfg_quiet)
+                       load_cfg(cfg_files[i], c, NULL, CMD_PARSE_QUIET, NULL);
+               else
+                       load_cfg(cfg_files[i], c, NULL, 0, NULL);
+       }
 
        cmdq_append(NULL, cmdq_get_callback(cfg_done, NULL));
 }
index d15c0cc..98bf7b0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.275 2021/02/22 07:09:06 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.276 2021/02/22 08:18:13 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1412,6 +1412,26 @@ format_cb_client_written(struct format_tree *ft)
        return (NULL);
 }
 
+/* Callback for config_files. */
+static void *
+format_cb_config_files(__unused struct format_tree *ft)
+{
+       char    *s = NULL;
+       size_t   slen = 0;
+       u_int    i;
+       size_t   n;
+
+       for (i = 0; i < cfg_nfiles; i++) {
+               n = strlen(cfg_files[i]) + 1;
+               s = xrealloc(s, slen + n + 1);
+               slen += xsnprintf(s + slen, n + 1, "%s,", cfg_files[i]);
+       }
+       if (s == NULL)
+               return (xstrdup(""));
+       s[slen - 1] = '\0';
+       return (s);
+}
+
 /* Callback for cursor_flag. */
 static void *
 format_cb_cursor_flag(struct format_tree *ft)
@@ -2569,6 +2589,9 @@ static const struct format_table_entry format_table[] = {
        { "client_written", FORMAT_TABLE_STRING,
          format_cb_client_written
        },
+       { "config_files", FORMAT_TABLE_STRING,
+         format_cb_config_files
+       },
        { "cursor_character", FORMAT_TABLE_STRING,
          format_cb_cursor_character
        },
index 04ecb10..cf5a390 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.822 2021/02/15 09:39:38 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.823 2021/02/22 08:18:13 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: February 15 2021 $
+.Dd $Mdocdate: February 22 2021 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -4763,6 +4763,7 @@ The following variables are available, where appropriate:
 .It Li "buffer_name" Ta "" Ta "Name of buffer"
 .It Li "buffer_sample" Ta "" Ta "Sample of start of buffer"
 .It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
+.It Li "config_files" Ta "" Ta "List of configuration files loaded"
 .It Li "client_activity" Ta "" Ta "Time client last had activity"
 .It Li "client_cell_height" Ta "" Ta "Height of each client cell in pixels"
 .It Li "client_cell_width" Ta "" Ta "Width of each client cell in pixels"
index 518d784..91c0e5d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.c,v 1.204 2021/01/17 16:17:41 nicm Exp $ */
+/* $OpenBSD: tmux.c,v 1.205 2021/02/22 08:18:13 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -142,11 +142,12 @@ expand_path(const char *path, const char *home)
        return (xstrdup(path));
 }
 
-void
-expand_paths(const char *s, char ***paths, u_int *n)
+static void
+expand_paths(const char *s, char ***paths, u_int *n, int ignore_errors)
 {
        const char      *home = find_home();
        char            *copy, *next, *tmp, resolved[PATH_MAX], *expanded;
+       char            *path;
        u_int            i;
 
        *paths = NULL;
@@ -162,20 +163,26 @@ expand_paths(const char *s, char ***paths, u_int *n)
                if (realpath(expanded, resolved) == NULL) {
                        log_debug("%s: realpath(\"%s\") failed: %s", __func__,
                            expanded, strerror(errno));
+                       if (ignore_errors) {
+                               free(expanded);
+                               continue;
+                       }
+                       path = expanded;
+               } else {
+                       path = xstrdup(resolved);
                        free(expanded);
-                       continue;
                }
-               free(expanded);
                for (i = 0; i < *n; i++) {
-                       if (strcmp(resolved, (*paths)[i]) == 0)
+                       if (strcmp(path, (*paths)[i]) == 0)
                                break;
                }
                if (i != *n) {
-                       log_debug("%s: duplicate path: %s", __func__, resolved);
+                       log_debug("%s: duplicate path: %s", __func__, path);
+                       free(path);
                        continue;
                }
                *paths = xreallocarray(*paths, (*n) + 1, sizeof *paths);
-               (*paths)[(*n)++] = xstrdup(resolved);
+               (*paths)[(*n)++] = path;
        }
        free(copy);
 }
@@ -193,7 +200,7 @@ make_label(const char *label, char **cause)
                label = "default";
        uid = getuid();
 
-       expand_paths(TMUX_SOCK, &paths, &n);
+       expand_paths(TMUX_SOCK, &paths, &n, 1);
        if (n == 0) {
                xasprintf(cause, "no suitable socket path");
                return (NULL);
@@ -330,10 +337,11 @@ main(int argc, char **argv)
 {
        char                                    *path = NULL, *label = NULL;
        char                                    *cause, **var;
-       const char                              *s, *shell, *cwd;
+       const char                              *s, *cwd;
        int                                      opt, keys, feat = 0;
        uint64_t                                 flags = 0;
        const struct options_table_entry        *oe;
+       u_int                                    i;
 
        if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
            setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
@@ -349,6 +357,7 @@ main(int argc, char **argv)
 
        if (**argv == '-')
                flags = CLIENT_LOGIN;
+       expand_paths(TMUX_CONF, &cfg_files, &cfg_nfiles, 1);
 
        while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
                switch (opt) {
@@ -368,7 +377,11 @@ main(int argc, char **argv)
                                flags |= CLIENT_CONTROL;
                        break;
                case 'f':
-                       set_cfg_file(optarg);
+                       for (i = 0; i < cfg_nfiles; i++)
+                               free(cfg_files[i]);
+                       free(cfg_files);
+                       expand_paths(optarg, &cfg_files, &cfg_nfiles, 0);
+                       cfg_quiet = 0;
                        break;
                case 'V':
                        printf("%s %s\n", getprogname(), getversion());
@@ -460,8 +473,8 @@ main(int argc, char **argv)
         * The default shell comes from SHELL or from the user's passwd entry
         * if available.
         */
-       shell = getshell();
-       options_set_string(global_s_options, "default-shell", 0, "%s", shell);
+       options_set_string(global_s_options, "default-shell", 0, "%s",
+           getshell());
 
        /* Override keys to vi if VISUAL or EDITOR are set. */
        if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
index 48bb0b7..49cf210 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1094 2021/02/22 07:09:06 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1095 2021/02/22 08:18:13 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1887,7 +1887,6 @@ const char        *sig2name(int);
 const char     *find_cwd(void);
 const char     *find_home(void);
 const char     *getversion(void);
-void            expand_paths(const char *, char ***, u_int *);
 
 /* proc.c */
 struct imsg;
@@ -1907,13 +1906,14 @@ pid_t   proc_fork_and_daemon(int *);
 /* cfg.c */
 extern int cfg_finished;
 extern struct client *cfg_client;
+extern char **cfg_files;
+extern u_int cfg_nfiles;
+extern int cfg_quiet;
 void   start_cfg(void);
 int    load_cfg(const char *, struct client *, struct cmdq_item *, int,
            struct cmdq_item **);
 int    load_cfg_from_buffer(const void *, size_t, const char *,
            struct client *, struct cmdq_item *, int, struct cmdq_item **);
-void   set_cfg_file(const char *);
-const char *get_cfg_file(void);
 void printflike(1, 2) cfg_add_cause(const char *, ...);
 void   cfg_print_causes(struct cmdq_item *);
 void   cfg_show_causes(struct session *);