After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 773880 - terminal: !linux fails because ptsname_r
terminal: !linux fails because ptsname_r
Status: RESOLVED FIXED
Product: gnome-builder
Classification: Other
Component: plugins
3.22.x
Other OpenBSD
: Normal normal
: ---
Assigned To: GNOME Builder Maintainers
GNOME Builder Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-11-03 08:59 UTC by Antoine Jacoutot
Modified: 2016-11-15 11:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
terminal: fallback to ptsname() if ptsname_r() is not available (2.59 KB, patch)
2016-11-03 21:29 UTC, Christian Hergert
committed Details | Review
setup TIOCSCTTY ioctl on tty fd (693 bytes, patch)
2016-11-04 19:46 UTC, Christian Hergert
reviewed Details | Review
subprocess-launcher: setup IOCSCTTY on stdin_fd after setsid() (1.87 KB, patch)
2016-11-11 23:26 UTC, Christian Hergert
none Details | Review
subprocess: use proper fileno for ioctl() (1.94 KB, patch)
2016-11-14 21:32 UTC, Christian Hergert
none Details | Review

Description Antoine Jacoutot 2016-11-03 08:59:39 UTC
Hi.

This commit https://git.gnome.org/browse/gnome-builder/commit/plugins/terminal?id=0d2ebaadd2b194a6f956271ec177751af6bd44a9 added a call to ptsname_r which is a Linux extension.
Any chance we could use ptsname(3) instead which is portable?

Thanks.
Comment 1 Christian Hergert 2016-11-03 10:14:29 UTC
Yeah, it looks like we only use ptsname_r() from the main loop, so we should be re-entrant safe. Mind cooking up a patch for me?
Comment 2 Christian Hergert 2016-11-03 21:29:27 UTC
Created attachment 339078 [details] [review]
terminal: fallback to ptsname() if ptsname_r() is not available

We are technically safe from race-conditions here in Builder specific
code today, as we only call ptsname_r() from the main loop. So switching
to the MT-unsafe ptsname() is fine. However, I'd like to always use the
re-entrant safe POSIX functions when possible.

This falls back to ptsname() when ptsname_r() isn't available, such as on
BSD variants.
Comment 3 Christian Hergert 2016-11-03 21:31:11 UTC
Attachment 339078 [details] pushed as 6e03588 - terminal: fallback to ptsname() if ptsname_r() is not available
Comment 4 Antoine Jacoutot 2016-11-04 14:36:47 UTC
Hi Christian.

I totally missed your second message and actually came up with a similar patch as well...
Anyway, I did not answer before because while the terminal works, it outputs this:

/bin/ksh: No controlling tty (open /dev/tty: Device not configured)
/bin/ksh: warning: won't have full job control
Comment 5 Christian Hergert 2016-11-04 19:39:50 UTC
Does posix_openpt() work on BSD? I see in Vte's configure.ac it checks for both posix_openpt() and BSD's openpty(). However, I don't see openpty() being used during pty master creation. We rely on Vte to create the pty master for us, so we only do the grantpt(), unlockpt(), ptsname() dance.

I don't have a BSD machine available, so I'll need you to do some digging in gb-terminal-view.c:gb_terminal_respawn() to see where the error is in the flow. Although if we actually spawn the process, that means we didn't detect a failure in our setup pty flow. So perhaps we are just missing something else that is needed on various BSDs.
Comment 6 Christian Hergert 2016-11-04 19:46:25 UTC
Created attachment 339137 [details] [review]
setup TIOCSCTTY ioctl on tty fd

Can you check and see if this fixes job control? If so, we will add plumbing to IdeSubprocessLauncher to setup TTY plumbing (as we need to do it differently with Flatpak vs pain subprocesses).
Comment 7 Antoine Jacoutot 2016-11-05 11:04:34 UTC
(In reply to Christian Hergert from comment #5)
> Does posix_openpt() work on BSD? I see in Vte's configure.ac it checks for

Yes it does work.
AFAIK Vte3 on BSD uses posix_openpt/grantpt/... and not openpty by default.
All are supported.

> both posix_openpt() and BSD's openpty(). However, I don't see openpty()
> being used during pty master creation. We rely on Vte to create the pty
> master for us, so we only do the grantpt(), unlockpt(), ptsname() dance.
> 
> I don't have a BSD machine available, so I'll need you to do some digging in
> gb-terminal-view.c:gb_terminal_respawn() to see where the error is in the
> flow. Although if we actually spawn the process, that means we didn't detect
> a failure in our setup pty flow. So perhaps we are just missing something
> else that is needed on various BSDs.

Ack, I'll have a look.
Thanks Christian.
Comment 8 Antoine Jacoutot 2016-11-05 11:05:01 UTC
(In reply to Christian Hergert from comment #6)
> Created attachment 339137 [details] [review] [review]
> setup TIOCSCTTY ioctl on tty fd
> 
> Can you check and see if this fixes job control? If so, we will add plumbing
> to IdeSubprocessLauncher to setup TTY plumbing (as we need to do it
> differently with Flatpak vs pain subprocesses).

Unfortunately, adding the TIOCSCTTY ioctl did not help...
Comment 9 Ray Strode [halfline] 2016-11-11 19:26:54 UTC
Review of attachment 339137 [details] [review]:

::: plugins/terminal/gb-terminal-view.c
@@ +272,3 @@
     IDE_GOTO (failure);
 
+  ioctl (tty_fd, TIOCSCTTY, tty_fd);

two things:

1) this ioctl is in the wrong place. presumably you're calling setsid() somewhere if there's no controlling terminal.  It's got to be after the setsid() call

2) the third argument is a boolean (something like steal_ctty_from_someone_else). it should be FALSE, since TRUE only works for root.
Comment 10 Christian Hergert 2016-11-11 23:18:30 UTC
We do call setsid() so that we can more reliably kill all of the grandchildren if we force_exit() the parent. (Ideally we'd have some cgroup for this to be more reliable in the future, but this is the best we can do for now).

I guess we can do something similar to what flatpak is doing in the session helper. If isatty(stdin), then call the ioctl() after we have setsid().
Comment 11 Christian Hergert 2016-11-11 23:26:59 UTC
Created attachment 339675 [details] [review]
subprocess-launcher: setup IOCSCTTY on stdin_fd after setsid()

This ensures that after our forked process becomes the session leader we
setup the TTY with an ioctl() of TIOCSCTTY ensuring the terminal the
controlling terminal.

This only affects processes that are spawned as children of our process,
as the Flatpak process helper deals with this in the session helper.
Comment 12 Christian Hergert 2016-11-11 23:30:20 UTC
Antoine, mind giving master a test (which has commit 7b68bdcb3e2925dff94c1fea555557e2e5470662)?
Comment 13 Antoine Jacoutot 2016-11-12 09:25:56 UTC
Hi Christian. Thanks for following on this, unfortunately that did not fix the issue. I'm still getting a non controlling tty.
Comment 14 Christian Hergert 2016-11-12 20:11:47 UTC
It looks like we weren't calling setpgid() after our setsid(), which could potentially be an issue on BSD. I think it was fine on Linux due to how tasks are implemented.

If this doesn't work, is there a *BSD VM somewhere with GNOME included that I could use build/test?
Comment 15 Antoine Jacoutot 2016-11-13 15:39:15 UTC
I already tried that as well but that did not help either :-/
I must say I am a bit puzzled...
I could set you up with a VM but the problem is that GNOME will not work on it since there's no accelerated display on !bare-metal.
Comment 16 Ray Strode [halfline] 2016-11-14 14:30:01 UTC
can you see if the TIOCSCTTY ioctl 

1) is running
2) if yes, is failing?
3) if yes, what the error code is?
Comment 17 Ray Strode [halfline] 2016-11-14 14:31:31 UTC
Review of attachment 339675 [details] [review]:

::: libide/subprocess/ide-subprocess-launcher.c
@@ +80,3 @@
+
+  if (isatty (priv->stdin_fd))
+    ioctl (priv->stdin_fd, TIOCSCTTY, 0);

wait if this is in the child, shouldn't that just STDIN_FILENO ?
Comment 18 Christian Hergert 2016-11-14 21:24:54 UTC
Ah yes, because GSpawnChildSetupFunc should not be called until right before exec(), which means that we've already remapped stdin_fd to STDIN_FILENO.
Comment 19 Christian Hergert 2016-11-14 21:32:19 UTC
Created attachment 339835 [details] [review]
subprocess: use proper fileno for ioctl()

We were trying to setup the TTY on stdin_fd which is no longer valid since
our child setup func is called after all the fd remapping has occurred
(and right before exec()).
Comment 20 Ray Strode [halfline] 2016-11-14 21:40:17 UTC
seems plausible to me, Antoine, does this one work?
Comment 21 Antoine Jacoutot 2016-11-15 06:53:37 UTC
\o/ Yes we have a winner :-)
Thanks a lot guys.
Comment 22 Christian Hergert 2016-11-15 11:00:19 UTC
great!