在Linux中找到会话负责人或进程组的控制TTY的方法有哪些?

This is not a language specific question, although I am using golang at the moment.

I am writing a command line program, and I wanted to find the real UID of the program.(By realUID, I meant, if the user did a sudo, the effective uid changes, but the real uid would be the same as the user's.)

  • I've read that finding the owner of the controlling tty is one way to find this, and on linux, we can use "tty" command, that will return the filename of the terminal connected to STDINPUT. Checking its ownership is one way.

  • Another way is to find the session leader process, and who owns it.

I tried the first way, using

cmdOut []byte
cmdOut, _ = exec.Command("tty").Output()

but it returns the output not a tty, when I run the program from my shell. Chances are that this might be getting executed in a separate forked shell that is detached from a tty (again, just a wild guess).

I tried the second way using os.Getppid() to get the parent pid, but in reality, when running sudo, it forks again, and it is giving the parent pid of the sudo process(16031 in the below case, whereas I am looking to grab 3393 instead.). (Pasting the process hierarchy from pstree output) /usr/bin/termin(3383)-+-bash(3393)---sudo(16031)---Myprogram(16032), so effectively I am not able to get the session leader process, but just the parent pid.

Can someone guide me on how do I implement this functionality using either of this method?

Edit: sudo set's $SUDO_USER environment variable, but it will help just with one sudo, i.e. if there was something like sudo sudo -u nobody your-program, $SUDO_USER will be set to "root". And there is $SUDO_UID too.

Old answer: How about exec.Command("who am i").Output() ? (won't work, still needs a tty).