⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exit.c

📁 msLinux v1.0 可以在arm ads 下仿真运行的linux
💻 C
字号:
/* MShowTec - www.mshowtec.com
** msLinux exit.c ver1.0
** 20051221 lmjx create limiao@mshowtec.com
** 
*/
#define MSLINUX_EXIT_C

#include "signal.h"
#include "sched.h"
#include "wait.h"
#include "errno.h"
#include "kernel.h"
#include "malloc.h"

void release (struct task_struct *p)
{
  int i;

  if (!p)
    return;
  for (i = 1; i < NR_TASKS; i++)
    if (task[i] == p)
	{
		task[i] = NULL;
		free((void*)(p->stack.p_TopOfStack));
		free((void*)p);
		schedule ();
		return;
	}
  panic ("trying to release non-existent task");
}

static __inline int send_sig (long sig, struct task_struct *p,int priv)
{
  if (!p || sig < 1 || sig > 32)
    return -EINVAL;

  if (priv || (current->euid == p->euid) || suser ())
    p->signal |= (1 << (sig - 1));
  else
    return -EPERM;
  return 0;
}

static void kill_session (void)
{
  struct task_struct **p = NR_TASKS + task;

  while (--p > &FIRST_TASK)
  {
    if (*p && (*p)->session == current->session)
	  (*p)->signal |= 1 << (SIGHUP - 1);
  }
}

int sys_kill (int pid, int sig)
{
  struct task_struct **p = NR_TASKS + task;
  int err, retval = 0;

  if (!pid)
    while (--p > &FIRST_TASK)
	{
		if (*p && (*p)->pgrp == current->pid)
		  if (err = send_sig (sig, *p, 1))
			retval = err;
	}
  else if (pid > 0)
    while (--p > &FIRST_TASK)
    {
	if (*p && (*p)->pid == pid)
	  if (err = send_sig (sig, *p, 0))
	    retval = err;
    }
  else if (pid == -1)
    while (--p > &FIRST_TASK)
      if (err = send_sig (sig, *p, 0))
		retval = err;
      else
		while (--p > &FIRST_TASK)
		  if (*p && (*p)->pgrp == -pid)
			if (err = send_sig (sig, *p, 0))
			  retval = err;
  return retval;
}

static void tell_father (int pid)
{
  int i;

  if (pid)
    for (i = 0; i < NR_TASKS; i++)
    {
		if (!task[i])
		  continue;
		if (task[i]->pid != pid)
		  continue;
		task[i]->signal |= (1 << (SIGCHLD - 1));
		return;
    }
/* if we don't find any fathers, we just release ourselves */
/* This is not really OK. Must change it to make father 1 */
  printk ("BAD BAD - no father found\n\r");
  release (current);
}

int do_exit (long code)
{
  int i;

  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);
    }
  if (current->leader)
    kill_session ();
    
  current->state = TASK_ZOMBIE;
  current->exit_code = code;
  
  tell_father (current->father);
  
  schedule ();
  
  return (-1);
  
}

int sys_exit (int error_code)
{
  return do_exit ((error_code & 0xff) << 8);
}

int sys_waitpid (int pid, unsigned long *stat_addr, int options)
{
  int flag, code;
  struct task_struct **p;

repeat:
  flag = 0;
  for (p = &LAST_TASK; p > &FIRST_TASK; --p)
  {
      if (!*p || *p == current)
		continue;
      if ((*p)->father != current->pid)
		continue;
      if (pid > 0)
		{
		  if ((*p)->pid != pid)
			continue;
		}
      else if (!pid)
		{
		  if ((*p)->pgrp != current->pgrp)
			continue;
		}
      else if (pid != -1)
		{			
		  if ((*p)->pgrp != -pid)
			continue;
		}
    switch ((*p)->state)
	{
	case TASK_STOPPED:
	  if (!(options & WUNTRACED))
	    continue;
	  *stat_addr = 0x7f;
	  return (*p)->pid;
	case TASK_ZOMBIE:
	  current->cutime += (*p)->utime;
	  flag = (*p)->pid;
	  code = (*p)->exit_code;
	  release (*p);
	  *stat_addr = 0x7f;
	  return flag;
	default:
	  flag = 1;	
	  continue;
	}
  }
  if (flag)
  {
	  if (options & WNOHANG)
		return 0;
	  current->state = TASK_INTERRUPTIBLE;
	  schedule ();
	  if (!(current->signal &= ~(1 << (SIGCHLD - 1))))
		goto repeat;
	  else
		return -EINTR;
  }
  return -ECHILD;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -