Tcgetpgrp returns 0 - consequences?

Context:

I am working on an application that needs to determine if a pseudo terminal opened by a process is its controlling terminal. I am trying to use tcgetpgrp()

libc / system call to achieve this.

Notes:

1) I noticed that it tcgetpgrp()

returns 0 for the main pseudo terminal in the simple application below. I am running Glibc 2.25 on Linux 4.10.3.

int main()
{
  int master_fd = open("/dev/ptmx", O_RDWR);
  grantpt(master_fd);
  unlockpt(master_fd);
  char *slave_pty = ptsname(master_fd);
  int slave_fd = open(slave_pty, O_RDWR);
  struct termios term;
  tcgetattr(slave_fd, &term);
  term.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
  tcsetattr(slave_fd, TCSANOW, &term);
  if (fork()) {
    // parent
    close(slave_fd);
    while (1) {
      pid_t pgrp = tcgetpgrp(master_fd);
      // tcgetpgrp on master_fd returns 0
      printf("tcgetpgrp returned: %d\n", pgrp);
      sleep(1);
    }
  } else {
    // child
    close(master_fd);
    while (1) {
      pid_t pgrp = tcgetpgrp(slave_fd);
      // tcgetpgrp on slave_fd returns -1
      printf("tcgetpgrp returned: %d\n", pgrp);
      sleep(1);
    }
  }
  return 0;
}

      

2) The Linux man page for tcgetpgrp()

says that:

When fd refers to the controlling terminal of the calling process, the tcgetpgrp () function will return the foreground process's group ID for that terminal, if any, and another value greater than 1, which is not currently a process group ID. when fd is not the controlling terminal of the calling process, -1, and errno is set appropriately.

3) The POSIX man page for tcgetpgrp()

says that:

Upon successful completion, tcgetpgrp () returns the process group ID of the associated foreground process with the terminal. Otherwise -1 is returned and errno is set to indicate an error.

4) Looking at the libc source, I found that the only wrapper tcgetpgrp()

is to call into the kernel using ioctl(TIOCGPGRP)

and send the return value to the caller.

Questions:

  • If I misinterpret it, the Linux man seems to be ambiguous as to what happens when the fd passed to tcgetpgrp is not the controlling terminal of the calling process. While the first sentence seems to say that a value> 1 will be returned, the second sentence says that -1 will be returned.

  • When the man page says that a value> 1 will be returned that is not a process group, does that mean I have to go through the list of the entire process group on the system to find out if the return value is for a valid process group?

  • What is the meaning of the return value 0? Is this a valid process group?

  • Is there something I am missing in my program?

I'm still trying to trace it through kernel sources ... but does anyone know the history behind this?

(I understand that the wizard shouldn't normally be the controlling terminal, but the system call behavior and the explanation in the man page still seems strange.)

Thank.

+3


source to share





All Articles