Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tcgetpgrp() behavior and tmux #1063

Closed
whorfin opened this issue Sep 7, 2016 · 17 comments
Closed

tcgetpgrp() behavior and tmux #1063

whorfin opened this issue Sep 7, 2016 · 17 comments

Comments

@whorfin
Copy link

whorfin commented Sep 7, 2016

Please use the following bug reporting template to help produce actionable and reproducible issues. Please try to ensure that the reproduction is minimal so that the team can go through more bugs!

  • A brief description
    pane_current_path, in either the apt-get install version [1.8] or "download and build" [2.2] version of tmux is always NULL. This is because tcgetpgrp(fd) in osdep-linux.c always returns -1 error.
    Using the code path from the sunos or aix versions instead, which uses ptsname(fd) to find the /dev/pts version of the tty, opens it, and then calls tcgetpgrp on that fd instead, works as expected.
  • Expected results
    use tmux, enjoy {pane_current_path} behavior, such as the common
    bind c new-window -c "#{pane_current_path}"
    which opens a new window, in the current directory
  • Actual results (with terminal output if applicable)
    use tmux, note that pane_current_path is not usable [always NULL]
  • Your Windows build number
    Version 1607 (OS Build 14393.82)
  • Steps / commands required to reproduce the error
    see above
  • Strace of the failing command
  • Required packages and commands to install
    tmux, and/or download latest tmux [2.2] and build from source

This patch to osdep-linux.c will fix it, and should clearly reveal the problem:

char *
osdep_get_cwd(int fd)
{
        static char      target[MAXPATHLEN + 1];
        char            *path;
        pid_t            pgrp, sid;
        ssize_t          n;

#define WIN10_PATCH
#ifdef WIN10_PATCH
        {
            const char      *ttypath;
            ssize_t          n;
            int              retval, ttyfd;

            if ((ttypath = ptsname(fd)) == NULL)
                    return (NULL);
            if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1)
                    return (NULL);

            fd = ttyfd;
        }
#endif
        if ((pgrp = tcgetpgrp(fd)) == 0)
                return (NULL);

        xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
        n = readlink(path, target, MAXPATHLEN);
        free(path);

        if (n == -1 && ioctl(fd, TIOCGSID, &sid) != -1) {
                xasprintf(&path, "/proc/%lld/cwd", (long long) sid);
                n = readlink(path, target, MAXPATHLEN);
                free(path);
        }

        if (n > 0) {
                target[n] = '\0';
                return (target);
        }
        return (NULL);
}
@crzidea
Copy link

crzidea commented Sep 25, 2016

+1 for this. I am tracking the exactly the same issue all the day. Now I am sure it is an issue of WSL.

@aspyrx
Copy link

aspyrx commented Jan 10, 2017

+1, still broken with tmux (from git, tag 2.3) on Ubuntu 16.04.1 LTS on Windows Version 1607 (OS Build 14986.1001).

The following patch works for me:

diff --git a/osdep-linux.c b/osdep-linux.c
index 42712de..6b31931 100644
--- a/osdep-linux.c
+++ b/osdep-linux.c
@@ -20,6 +20,12 @@
 #include <sys/stat.h>
 #include <sys/param.h>

+// https://github.com/Microsoft/BashOnWindows/issues/1063
+#define WIN10_PATCH
+#ifdef WIN10_PATCH
+#include <fcntl.h>
+#endif
+
 #include <event.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -69,9 +75,29 @@ osdep_get_cwd(int fd)
        pid_t            pgrp, sid;
        ssize_t          n;

+// https://github.com/Microsoft/BashOnWindows/issues/1063
+#ifdef WIN10_PATCH
+       char            ttypath[MAXPATHLEN + 1];
+       int                     ttyfd;
+
+       if (ptsname_r(fd, ttypath, sizeof(ttypath))) {
+               return (NULL);
+       }
+
+       if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1) {
+               return (NULL);
+       }
+
+       fd = ttyfd;
+#endif
+
        if ((pgrp = tcgetpgrp(fd)) == -1)
                return (NULL);

+#ifdef WIN10_PATCH
+       close(ttyfd);
+#endif
+
        xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
        n = readlink(path, target, MAXPATHLEN);
        free(path);

@sunilmut
Copy link
Member

Can someone collect a strace of the failing command on WSL and share it out? There does not seem to be a syscall called 'tcgetpgrp`

strace -o <strace_file> -ff <failing_cmd>

@nessss
Copy link

nessss commented Mar 29, 2017

Thanks @aspyrx, that patch fixed #{pane_current_path} for me as well. In addition, modifying osdep_get_name in the same way as osdep_get_cwd fixed another issue I was having, namely #{pane_current_command} always returning null.

Here's the updated patch:

diff --git a/osdep-linux.c b/osdep-linux.c
index 42712de..943490a 100644
--- a/osdep-linux.c
+++ b/osdep-linux.c
@@ -20,6 +20,12 @@
 #include <sys/stat.h>
 #include <sys/param.h>

+// https://github.com/Microsoft/BashOnWindows/issues/1063
+#define WIN10_PATCH
+#ifdef WIN10_PATCH
+#include <fcntl.h>
+#endif
+
 #include <event.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,9 +42,29 @@ osdep_get_name(int fd, __unused char *tty)
        int      ch;
        pid_t    pgrp;

+// https://github.com/Microsoft/BashOnWindows/issues/1063
+#ifdef WIN10_PATCH
+    char            ttypath[MAXPATHLEN + 1];
+    int                     ttyfd;
+
+    if (ptsname_r(fd, ttypath, sizeof(ttypath))) {
+        return (NULL);
+    }
+
+    if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1) {
+        return (NULL);
+    }
+
+    fd = ttyfd;
+#endif
+
        if ((pgrp = tcgetpgrp(fd)) == -1)
                return (NULL);

+#ifdef WIN10_PATCH
+    close(ttyfd);
+#endif
+
        xasprintf(&path, "/proc/%lld/cmdline", (long long) pgrp);
        if ((f = fopen(path, "r")) == NULL) {
                free(path);
@@ -69,9 +95,29 @@ osdep_get_cwd(int fd)
        pid_t            pgrp, sid;
        ssize_t          n;

+// https://github.com/Microsoft/BashOnWindows/issues/1063
+#ifdef WIN10_PATCH
+    char            ttypath[MAXPATHLEN + 1];
+    int                     ttyfd;
+
+    if (ptsname_r(fd, ttypath, sizeof(ttypath))) {
+        return (NULL);
+    }
+
+    if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1) {
+        return (NULL);
+    }
+
+    fd = ttyfd;
+#endif
+
        if ((pgrp = tcgetpgrp(fd)) == -1)
                return (NULL);

+#ifdef WIN10_PATCH
+       close(ttyfd);
+#endif
+
        xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
        n = readlink(path, target, MAXPATHLEN);
        free(path);

@mmarchini
Copy link

mmarchini commented May 19, 2017

@sunilmut here is the full stace file

The failing call to tcgetpgrp happens on line 41252:

[pid  3667] ioctl(16, TIOCGPGRP, 0x7fffc5c1409c) = -1 EINVAL (Invalid argument)

According to this, that call is equivalent to: *argp = tcgetpgrp(16), where argp points to 0x7fffc5c1409c.

And as this call returned -1, it fails again on line 41282 and then fall back to chdir("/") on line 41283:

[pid  3844] fchdir(-1)                  = -1 EBADF (Bad file descriptor)
[pid  3844] chdir("/")                  = 0

If you need more information I'm glad to help.

@gpakosz
Copy link

gpakosz commented Jun 18, 2017

Reproduced with tmux HEAD

@sunilmut
Copy link
Member

@mmarchini - Thanks for the trace and the analysis, and sorry for the delayed response. I have marked it as a bug, which should automatically put it in our backlog of bugs.

@gpakosz
Copy link

gpakosz commented Jun 22, 2017

Yep too bad it went untagged for so long, could have been in creators update since a lot of focus was given to tmux etc

@benhillis
Copy link
Member

I believe this should be fixed in 16257.

@Victor-Savu
Copy link

@benhillis could you provide a link to the PR you are referring to please? I'd really love to see this fix :)

@benhillis
Copy link
Member

Unfortunately it's on our internal Microsoft VSTS so I can't share it

@Victor-Savu
Copy link

Oh, I see. Thanks anyway! I suppose the PR number from you comment will not match the PR number from GitHub so it will be a bit confusing for future readers.

@benhillis
Copy link
Member

That number is a Windows build number not PR number.

@gpakosz
Copy link

gpakosz commented Aug 7, 2017

@benhillis Just tried 16257.rs3_release.170728-1700 and I confirm tmux display -p '#{pane_current_path}' works now.

@benhillis
Copy link
Member

Awesome, thanks for confirming.

@williscool
Copy link

How / when do I get the version of windows this is fixed in?

@Brian-Perkins
Copy link

This fix is available in the Fall Creators Update: https://binged.it/2zBdP2f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests