Exemplo n.º 1
0
Arquivo: exit.c Projeto: gozfree/src
int do_exit(long code)
{
	int i;

	free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
	free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
	for (i=0 ; i<NR_TASKS ; i++)
		if (task[i] && task[i]->father == current->pid) {
			task[i]->father = 1;
			if (task[i]->state == TASK_ZOMBIE)
				/* assumption task[1] is always init */
				(void) send_sig(SIGCHLD, task[1], 1);
		}
	for (i=0 ; i<NR_OPEN ; i++)
		if (current->filp[i])
			sys_close(i);
	iput(current->pwd);
	current->pwd=NULL;
	iput(current->root);
	current->root=NULL;
	iput(current->executable);
	current->executable=NULL;
	if (current->leader && current->tty >= 0)
		tty_table[current->tty].pgrp = 0;
	if (last_task_used_math == current)
		last_task_used_math = NULL;
	if (current->leader)
		kill_session();
	current->state = TASK_ZOMBIE;
	current->exit_code = code;
	tell_father(current->father);
	schedule();
	return (-1);	/* just to suppress warnings */
}
Exemplo n.º 2
0
int do_exit(long code)
{
	int i;
	// TODO 待看页表
	free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
	free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
	/*
	 * 找出所有子进程,将它们的父亲设为 init 进程,将状态标记为僵尸
	 * 然后给 init 进程发送一个 SIGCHLD 信号,提醒 init 进程回收子进程
	 */
	for (i=0 ; i<NR_TASKS ; i++)
		if (task[i] && task[i]->father == current->pid) {
			task[i]->father = 1;
			if (task[i]->state == TASK_ZOMBIE)
				/* assumption task[1] is always init */
				// 最后一个参数 1 代表 privilege,此处为强制发送
				(void) send_sig(SIGCHLD, task[1], 1);
		}
	// TODO 关闭文件?
	/*
	 * NR_OPEN 是一个进程可以打开的最大文件数
	 * 而 NR_FILE 是系统在某时刻的限制文件总数
	 */
	for (i=0 ; i<NR_OPEN ; i++)
		if (current->filp[i])
			sys_close(i);
	// 进程的当前工作目录 inode
	iput(current->pwd);
	current->pwd=NULL;
	// 进程的根目录 inode
	iput(current->root);
	current->root=NULL;
	// 进程本身可执行文件的 inode
	iput(current->executable);
	current->executable=NULL;
	if (current->leader && current->tty >= 0)
		tty_table[current->tty].pgrp = 0;
	if (last_task_used_math == current)
		last_task_used_math = NULL;
	/*
	 * 如果是 session leader 会话领头进程,则向该会话所有进程发送 SIGHUP 信号
	 * PID, PPID, PGID, SID
	 * http://unix.stackexchange.com/questions/18166/what-are-session-leaders-in-ps
	 * 在同一次 ssh 会话中,用户对应的 shell 最先被启动,成为 session leader,
	 * 所有在同一次会话中产生的进程 session id 都等于这个 session leader 的 pid
	 * 当 session leader 退出时,它会向所有同一 session 中的进程发送 SIGHUP,
	 * 这个信号是可以被捕获的,如果进程忽略这个 SIGHUP,它则可以以一个孤儿进程继续执行
	 * http://www.firefoxbug.com/index.php/archives/2782/
	 */
	if (current->leader)
		kill_session();
	// 将自己设为僵尸,设置退出状态码,同时告诉父进程回收子进程
	current->state = TASK_ZOMBIE;
	current->exit_code = code;
	tell_father(current->father);
	// 如果 tell_father 中找不到父进程,自己把自己释放掉了,那也不会有机会继续执行下面代码了
	schedule();
	return (-1);	/* just to suppress warnings */
}
Exemplo n.º 3
0
//// 程序退出处理程序。在系统调用的中断处理程序中被调用。
int
do_exit (long code)		// code 是错误码。
{
  int i;

// 释放当前进程代码段和数据段所占的内存页(free_page_tables()在mm/memory.c,105 行)。
  free_page_tables (get_base (current->ldt[1]), get_limit (0x0f));
  free_page_tables (get_base (current->ldt[2]), get_limit (0x17));
// 如果当前进程有子进程,就将子进程的father 置为1(其父进程改为进程1)。如果该子进程已经
// 处于僵死(ZOMBIE)状态,则向进程1 发送子进程终止信号SIGCHLD。
  for (i = 0; i < NR_TASKS; i++)
    if (task[i] && task[i]->father == current->pid)
      {
	task[i]->father = 1;
	if (task[i]->state == TASK_ZOMBIE)
/* assumption task[1] is always init */
	  (void) send_sig (SIGCHLD, task[1], 1);
      }
// 关闭当前进程打开着的所有文件。
  for (i = 0; i < NR_OPEN; i++)
    if (current->filp[i])
      sys_close (i);
// 对当前进程工作目录pwd、根目录root 以及运行程序的i 节点进行同步操作,并分别置空。
  iput (current->pwd);
  current->pwd = NULL;
  iput (current->root);
  current->root = NULL;
  iput (current->executable);
  current->executable = NULL;
// 如果当前进程是领头(leader)进程并且其有控制的终端,则释放该终端。
  if (current->leader && current->tty >= 0)
    tty_table[current->tty].pgrp = 0;
// 如果当前进程上次使用过协处理器,则将last_task_used_math 置空。
  if (last_task_used_math == current)
    last_task_used_math = NULL;
// 如果当前进程是leader 进程,则终止所有相关进程。
  if (current->leader)
    kill_session ();
// 把当前进程置为僵死状态,并设置退出码。
  current->state = TASK_ZOMBIE;
  current->exit_code = code;
// 通知父进程,也即向父进程发送信号SIGCHLD -- 子进程将停止或终止。
  tell_father (current->father);
  schedule ();			// 重新调度进程的运行。
  return (-1);			/* just to suppress warnings */
}
Exemplo n.º 4
0
int do_exit()
{
	int i;
	struct task_struct *p = current;
	int pid = p->pid;	
	printk("%d\n",pid);
	for(i = 0;i < NR_PROCESS + NR_PROCS;i++)
	{
		if(proc_table[i].parent == pid)
		{
			proc_table[i].parent = 1; //init pid
			if(proc_table[i].state == TASK_WAITING && proc_table[i].state == TASK_ZOMBIE)
			{
	//			release_process(&proc_table[i]);
			}
		}
	}
	p->state = TASK_ZOMBIE;
//	p->exit_code = code;
	tell_father(p->parent);
	schedule();
	return 0;

}
Exemplo n.º 5
0
int main(int argc, char const *argv[])
{
    char buf[MAXSIZE]={'\0'};
    char buf_r[MAXSIZE]={'\0'};

    int fd[2];
    pipe(fd);
    signal(SIGPIPE,fun);
    pid_t pid;
    int len = 0;
    int nr = 0;
    int sum = 0;
    int nread,len_r;
    //signal tongbu
    tell_wait();
    //sgnal tongbu
    pid  = fork();
    if (pid <0) {
        perror("error");
        /* code */
    }else if (pid == 0) {
        /* code */
       
        wait_father();
        printf("the child process.....%d\n",getpid());
        printf("the child process's father process id:%d\n",getppid());
        close(fd[1]);

        while((nread = read(fd[0],buf,sizeof(buf)))!=-1){
            tell_father(pid);
            setbuf(stdout,NULL);//set the stdout no buffer
            printf("the child write to stdout:");
            write(STDOUT_FILENO,buf,nread); //the write to stdout is bo bug ,but the printf is bug

            len_r = strlen(buf);
            printf("len_r :%d\n",len_r );

            for (int i = 0; (buf[i]!='\n'); i++) {
                sum +=i;
                printf("sum:%d\n",sum );
                printf("buf[%d]:%c\t",i,buf[i] );
                if (buf[i]=='\0') {
                    break;
                    
                }

            }
            printf("\n");

            // printf("child read:%s\n",buf ); //the sentence is bug ,it  is  of buffer and \n
        }
        exit(0);      
    }else{
        // sleep(3);
        tell_child(pid);
        printf("the father process.......%d\n",getpid());
        printf("the father process's father process id:%d\n",getppid());
        close(fd[0]);//the sentense to invlole the SIGPIPE take place
        char * p  = NULL; /* code */ 
        while((p = fgets(buf,sizeof(buf),stdin))!=NULL){

            len = strlen(buf);
            printf("the length :%d\n",len );
            if (p[len] =='\n') {
                printf("%c\n",p[len -1] );
                len--;
                p[len ] = '\0';
                /* code */
            }
            if (p[len -1] == '\0') {
                printf("fgets  read the null in buffer\n");
                /* code */
            }

            fflush(stdin);
            int  n = write(fd[1],buf,len);
            if (n==-1) {
                if (errno = EINTR) {
                    printf("the failed is SIGINT\n");
                    /* code */
                }
                printf("err write\n");
            }else
                printf("father write to pipe successfully\n");

            wait_child();
        }

        int status;
        // the waitpid 's return val is the son process pid,if it wait to catch the son state successfully
        int ret = waitpid(pid,&status,0);
        if (ret == -1) {
            printf("wait child failed\n");
            /* code */
        }else
            printf("the wait id:%d\n", ret);//the ret == son pid
        
    }

    
  
    return 0;
}