Sunday, September 28, 2014

Unix Prog: Controlling Terminal

1. Controlling Terminal
1) A session can have one controlling terminal. It may be terminal device(terminal login) or pseudo-terminal device(network login)
2) The session leader that establishes the connection to the controlling terminal is called the controlling process.
3) The process groups in the session can be divided into one foreground process group and one or more background process groups
4) Whenever we type one interrupt key(DELETE or Ctrl - C) or quit key, this causes the signal be sent to all processes in the foreground process groups
5) If a modem(or network) disconnect is detected by the terminal interface, the hang-up signal is sent to the controlling process(the session leader)

The way a program guarantees that it is talking to the controlling terminal is to open the file /dev/tty. If the program doesn't have one controlling terminal, open will fail.

2. tcgetpgrp, tcsetpgrp, tcgetsid

System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Return the foreground process group ID of FD. */  
 extern __pid_t tcgetpgrp (int __fd) __THROW;  
   
 /* Set the foreground process group ID of FD set PGRP_ID. */  
 extern int tcsetpgrp (int __fd, __pid_t __pgrp_id) __THROW;  
 ......  
 ubuntu@ip-172-31-23-227:~$ less /usr/include/termios.h  
 ......  
 /* Get process group ID for session leader for controlling terminal FD. */  
 extern __pid_t tcgetsid (int __fd) __THROW;  
 ......  

session.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<termios.h>  
 #include<fcntl.h>  
   
 int main(int argc, char* argv[])  
 {  
  int fd;  
   
  if((fd = open("/dev/tty", O_RDONLY)) < 0) {  
   printf("open error!\n");  
   exit(1);  
  }  
   
  printf("controlling terminal fd: %d\n", fd);  
  printf("current process id: %d\n", getpid());  
  printf("current process group id: %d\n", getpgrp());  
  printf("current process session id: %d\n", getsid(0));  
  printf("foreground group id with controlling terminal: %d\n", tcgetpgrp(fd));  
  printf("foreground group id with terminal 0: %d\n", tcgetpgrp(0));  
  printf("session leader group id with controlling terminal: %d\n", tcgetsid(fd));  
   
  // Change the foreground process group to the session leader group  
  if(tcsetpgrp(fd, getsid(0)) < 0) {  
   printf("tcsetgrp error!\n");  
   exit(2);  
  }  
   
  printf("After changing the foreground process group to the session leader group:\n");  
  printf("foreground group id with controlling terminal: %d\n", tcgetpgrp(fd));  
   
  exit(0);  
 }  

shell:
1) run the ps to display current running process, our bash shell is running, process id is 12478
2) Run the session.out,
By opening the "/dev/tty" its controlling terminal file descriptor is 3
Its current process id is 12585, it is the process group leader of group 12585
getsid(0) indicates that current process belong to the session with session leader 12478, bash shell process
tcgetpgrp indicates that current foreground process group is 12585, current process
And then we can tcsetpgrp to change the foreground process group to session leader group, bash shell
At this time, tcgetpgrp indicates that the foreground process group is already changed to bash shell: 12478.
 ubuntu@ip-172-31-23-227:~$ ps  
  PID TTY     TIME CMD  
 12478 pts/2  00:00:00 bash  
 12584 pts/2  00:00:00 ps  
 ubuntu@ip-172-31-23-227:~$ ./session.out  
 controlling terminal fd: 3  
 current process id: 12585  
 current process group id: 12585  
 current process session id: 12478  
 foreground group id with controlling terminal: 12585  
 foreground group id with terminal 0: 12585  
 session leader group id with controlling terminal: 12478  
 After changing the foreground process group to the session leader group:  
 foreground group id with controlling terminal: 12478  

No comments:

Post a Comment