Unix 是1971年开始的吧,但是这个terminal login的机制最起码30年没变过。。。非常成熟的机制
?Change to our home directory(chdir)
?Change the ownership of our terminal device (chown) so we own it
?Change the access permissions for our terminal device so we have permission to read from and write to it
?Set our group IDs by calling setgid and initgroups
?Initialize the environment with all the information that loginhas: our home directory (HOME), shell(SHELL), user name (USER and LOGNAME), and a default path (PATH)
?Change to our user ID ( setuid)and invoke our login shell, as in execl("/bin/sh", "-sh", (char *)0);
the connection between the terminal and the computer isn’t point-to-point. In this case, loginis simply a service available, just like any other network service, such as FTP or SMTP.
In addition to having a process ID, each process belongs to a process group.Each process group has a unique process group ID.
#include <unistd.h> pid_t getpgrp(void); Returns: process group ID of calling process #include <unistd.h> pid_t getpgid(pid_t pid); Returns: process group ID if OK, ?1 on error
If pid is 0, the process group ID of the calling process is returned. Thus
getpgid(0);
is equivalent to
getpgrp();
特别注意这两个API的名称。。。被坑10分钟debug
Each process group can have a process group leader.The leader is identified by its process group ID being equal to its process ID.
The process group still exists, as long as at least one process is in the group, regardless of whether the group leader terminates. This is called the process group lifetime—the period of time that begins when the group is created and ends when the last remaining process leaves the group.
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t temp = 0;
//test pid_t getpgrp(void);
printf("The group ID of current process : %d\n",getpgrp());
//test pid_t getpgrp(pid_t pid);
printf("The group ID of current process : %d\n",getpgid(getpid()));
return 0;
}
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid = 0; printf("Current process ID:%d\n",getpid()); if((pid = fork()) < 0) { printf("fork error\n"); } else if(pid == 0) { printf("Current process group of child process ID: %d\n",getpgrp()); exit(0); } else if(pid > 0) { waitpid(pid,NULL,0); printf("Current process group of child process ID : %d\n",getpgrp()); } return 0; }test result:
#include <unistd.h> int setpgid(pid_t pid,pid_t pgid ); Returns: 0 if OK,?1 on error
This function sets the process group ID to pgid in the process whose process ID equals pid.If the two arguments are equal, the process specified by pid becomes a process group leader .If pid is 0, the process ID of the caller is used. Also, if pgid is 0, the process ID specified by pid is used as the process group ID。
Furthermore, it can’t change the process group ID of one of its children after that child has called one of the exec functions.
#include <unistd.h> pid_t setsid(void); Returns: process group ID if OK, ?1 on error
1. The process becomes the session leader of this new session. (A session leader is the process that creates a session.) The process is the only process in this new session.
2. The process becomes the process group leader of a new process group. The new process group ID is the process ID of the calling process.
3. The process has no controlling terminal. (We’ll discuss controlling terminals in the next section.) If the process had a controlling terminal before calling setsid, that association is broken.
#include <unistd.h> pid_t getsid(pid_t pid); Returns: session leader’s process group ID if OK, ?1 on error
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid = 0; printf("Current process -- parent process ID:%d\n",getpid()); printf("Current process group of parent process ID : %d\n",getpgrp()); if((pid = fork()) < 0) { printf("fork error\n"); } else if(pid == 0) { pid_t pgrp; printf("child process ID:%d\n",getpid()); printf("Current process group of child process ID: %d\n",getpgrp()); printf("after set new group\n"); setsid(); printf("Current process group of child process ID: %d\n",getpgrp()); printf("Current sessions ID :%d\n",getsid(getpid())); exit(0); } else if(pid > 0) { waitpid(pid,NULL,0); printf("Current process group of parent process ID : %d\n",getpgrp()); printf("Current session ID of parent process : %d\n",getsid(getpid())); } return 0; }
?A session can have a single controlling terminal.This is usually the terminal device (in the case of a terminal login) or pseudo terminal device (in the case of a network login) on which we log in.
?The session leader that establishes the connection to the controlling terminal is called the controlling process.
?The process groups within a session can be divided into a single foreground process group and one or more background process groups .
?If a session has a controlling terminal, it has a single foreground process group and all other process groups in the session are background process groups.这就意味着有且只有一个foreground group,允许多个background group。
?Whenever we press the terminal’s interrupt key (often DELETE or Control-C), the interrupt signal is sent to all processes in the foreground process group.
?Whenever we press the terminal’s quit key (often Control-backslash), the quit signal is sent to all processes in the foreground process group.
?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).
#include <unistd.h> pid_t tcgetpgrp(int fd ); Returns: process group ID of foreground process group if OK,?1 on error int tcsetpgrp(int fd ,pid_t pgrpid ); Returns: 0 if OK,?1 on error #include <termios.h> pid_t tcgetsid(int fd ); Returns: session leader’s process group ID if OK, ?1 on error
#include <stdio.h> #include <unistd.h> int main() { int file_descriptor = 0; if((file_descriptor = open("/dev/tty","r")) < 0) { printf("open error\n"); } printf("foreground ID:%d\n",tcgetpgrp(file_descriptor)); close(file_descriptor); return 0; }
#include"apue.h" #include"myerr.h" #include"errno.h" #include"stdio.h" static void sig_hup(int signo) { printf("SIGHUP received,pid = %d\n",getpid()); } static void pr_ids(char* name) { printf("%s: pid = %d,ppid = %d,pgrp = %d,tppgrp = %d,\n",name,getpid(),getppid(),getpgrp(),tcgetpgrp(STDIN_FILENO)); fflush(stdout); } int main(int argc,char* argv[]) { char c; pid_t pid; pr_ids("parent"); if((pid = fork()) < 0) { err_sys("fork error\n"); } else if(pid > 0) { sleep(5); exit(0); } else { pr_ids("child"); signal(SIGHUP,sig_hup); kill(getpid(),SIGTSTP); pr_ids("child"); if(read(STDIN_FILENO,&c,1) != 1) { printf("read error from controlling TTY,errno = %d\n",errno); } exit(0); } }
《APUE》Chapter 9 Process relationships (学习笔记加上自己的代码),布布扣,bubuko.com
《APUE》Chapter 9 Process relationships (学习笔记加上自己的代码)
原文:http://blog.csdn.net/cinmyheart/article/details/22476983