Improve error message if creating socket parent directory fails, from
authornicm <nicm@openbsd.org>
Fri, 12 Jan 2018 10:22:02 +0000 (10:22 +0000)
committernicm <nicm@openbsd.org>
Fri, 12 Jan 2018 10:22:02 +0000 (10:22 +0000)
Thomas Adam for GitHub issue 1215.

usr.bin/tmux/tmux.c

index 4f9718e..84d801c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.c,v 1.185 2018/01/01 11:19:08 nicm Exp $ */
+/* $OpenBSD: tmux.c,v 1.186 2018/01/12 10:22:02 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -47,7 +47,7 @@ int            ptm_fd = -1;
 const char     *shell_command;
 
 static __dead void      usage(void);
-static char            *make_label(const char *);
+static char            *make_label(const char *, char **);
 
 static const char      *getshell(void);
 static int              checkshell(const char *);
@@ -109,12 +109,13 @@ areshell(const char *shell)
 }
 
 static char *
-make_label(const char *label)
+make_label(const char *label, char **cause)
 {
        char            *base, resolved[PATH_MAX], *path, *s;
        struct stat      sb;
        uid_t            uid;
-       int              saved_errno;
+
+       *cause = NULL;
 
        if (label == NULL)
                label = "default";
@@ -124,11 +125,16 @@ make_label(const char *label)
                xasprintf(&base, "%s/tmux-%ld", s, (long)uid);
        else
                xasprintf(&base, "%s/tmux-%ld", _PATH_TMP, (long)uid);
-
-       if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST)
+       if (realpath(base, resolved) == NULL &&
+           strlcpy(resolved, base, sizeof resolved) >= sizeof resolved) {
+               errno = ERANGE;
+               free(base);
                goto fail;
+       }
 
-       if (lstat(base, &sb) != 0)
+       if (mkdir(resolved, S_IRWXU) != 0 && errno != EEXIST)
+               goto fail;
+       if (lstat(resolved, &sb) != 0)
                goto fail;
        if (!S_ISDIR(sb.st_mode)) {
                errno = ENOTDIR;
@@ -138,18 +144,11 @@ make_label(const char *label)
                errno = EACCES;
                goto fail;
        }
-
-       if (realpath(base, resolved) == NULL)
-               strlcpy(resolved, base, sizeof resolved);
        xasprintf(&path, "%s/%s", resolved, label);
-
-       free(base);
        return (path);
 
 fail:
-       saved_errno = errno;
-       free(base);
-       errno = saved_errno;
+       xasprintf(cause, "error creating %s (%s)", resolved, strerror(errno));
        return (NULL);
 }
 
@@ -191,7 +190,7 @@ find_home(void)
 int
 main(int argc, char **argv)
 {
-       char                                    *path, *label, **var;
+       char                                    *path, *label, *cause, **var;
        char                                     tmp[PATH_MAX];
        const char                              *s, *shell, *cwd;
        int                                      opt, flags, keys;
@@ -341,8 +340,11 @@ main(int argc, char **argv)
                        path[strcspn(path, ",")] = '\0';
                }
        }
-       if (path == NULL && (path = make_label(label)) == NULL) {
-               fprintf(stderr, "can't create socket: %s\n", strerror(errno));
+       if (path == NULL && (path = make_label(label, &cause)) == NULL) {
+               if (cause != NULL) {
+                       fprintf(stderr, "%s\n", cause);
+                       free(cause);
+               }
                exit(1);
        }
        socket_path = path;