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

proposal: x/term: get terminal name (or some unique id) #58543

Closed
xtaixe opened this issue Feb 15, 2023 · 9 comments
Closed

proposal: x/term: get terminal name (or some unique id) #58543

xtaixe opened this issue Feb 15, 2023 · 9 comments

Comments

@xtaixe
Copy link

xtaixe commented Feb 15, 2023

Add a way in golang.org/x/term to get the terminal name or some terminal unique identifier for a given file descriptor.

Otherwise, I don't think it's possible to determine if stdout and stderr go to the same terminal or a different one, so that CLI tools/libraries that provide rich output (spinners, etc.) can repaint correctly.

@gopherbot gopherbot added this to the Proposal milestone Feb 15, 2023
@seankhliao
Copy link
Member

is this a native thing that terminals provide or should one be synthesized from... something?

@xtaixe
Copy link
Author

xtaixe commented Feb 15, 2023

Honestly, I don't know what's the best way to go about this...

For Linux there's https://man7.org/linux/man-pages/man3/ttyname.3.html

In case it helps, this is what Jansi provides for Java through JNI and C: https://github.com/fusesource/jansi/tree/master/src/main/native

@ianlancetaylor
Copy link
Contributor

Can you write a proposed API with a doc comment? Thanks.

@xtaixe
Copy link
Author

xtaixe commented Feb 15, 2023

I'm currently very unfamiliar with the language, so apologies in advance if this is not what you are looking for, but looking at the current API, I think it would something like:

//GetName returns the name of the given terminal.
func GetName(fd int) string

If the given file descriptor is not a terminal, it could return empty or an error, according to what's considered best practice or following other similar cases in the package.

Then for example, assuming the current terminal is /dev/ttys001 and there is another terminal /dev/ttys002 and given a command my-command that prints to stdout the result of calling that method for stdin, stout and stderr, it would behave like this:

$my-command 2> /dev/ttys002
STDIN:  /dev/ttys001
STDOUT: /dev/ttys001
STDERR: /dev/ttys002

@ianlancetaylor
Copy link
Contributor

Go rarely uses file descriptors, so it seems odd to pass a file descriptor to a function like this. I mean, file descriptors do exist, of course, but Go programs don't use them routinely.

If the goal is only to check whether os.Stdout and os.Stderr are going to different files, then I don't think ttyname is the right approach at all. Instead, use the Stat method and compare the Dev and Ino fields of stat.Sys().(*syscall.Stat_t). Note that that is Unix-specific, but then so is ttyname.

@rittneje
Copy link

You can also use os.SameFile, which basically does what @ianlancetaylor suggested for you.

@xtaixe
Copy link
Author

xtaixe commented Feb 16, 2023

Go rarely uses file descriptors, so it seems odd to pass a file descriptor to a function like this.

I was basing on the GetSize existing function: func GetSize(fd int) (width, height int, err error)

I'll check the options mentioned with someone on my team though to try to test if that would work for us. Thanks.

@xtaixe
Copy link
Author

xtaixe commented Apr 13, 2023

Using os.SameFile worked for us. Thanks.

@ianlancetaylor
Copy link
Contributor

OK, closing this proposal. Please comment if you disagree. Thanks.

@ianlancetaylor ianlancetaylor closed this as not planned Won't fix, can't repro, duplicate, stale Apr 13, 2023
@golang golang locked and limited conversation to collaborators Apr 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants